diff --git a/.prettierignore b/.prettierignore
index 9b7334e..a354176 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -9,3 +9,4 @@ drizzle/
packages/ui/src/primitives/form/form.mdx
packages/ui/src/primitives/toast/toast.mdx
packages/ui/src/primitives/carousel/carousel.mdx
+packages/constants/src/auth.ts
\ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 7b2e17a..cac9cf2 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -11,7 +11,6 @@
"tamasfe.even-better-toml",
"github.vscode-github-actions",
"GitHub.copilot",
- "GitHub.copilot-chat",
"GitHub.vscode-pull-request-github",
"DavidAnson.vscode-markdownlint",
"unifiedjs.vscode-mdx",
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..ffb95b1
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,10 @@
+{
+ "configurations": [
+ {
+ "type": "chrome",
+ "name": "http://localhost:4321",
+ "request": "launch",
+ "url": "http://localhost:4321"
+ }
+ ]
+}
diff --git a/apps/marketing/astro.config.ts b/apps/marketing/astro.config.ts
index fb0cbfe..cb999f8 100644
--- a/apps/marketing/astro.config.ts
+++ b/apps/marketing/astro.config.ts
@@ -8,8 +8,8 @@ import react from '@astrojs/react'
import sitemap from '@astrojs/sitemap'
import tailwind from '@astrojs/tailwind'
import vercel from '@astrojs/vercel/serverless'
-import sentry from '@sentry/astro'
-import { defineConfig } from 'astro/config'
+// import sentry from '@sentry/astro'
+import { defineConfig, envField } from 'astro/config'
import dotenv from 'dotenv'
import postcss from './postcss.config.js'
@@ -29,14 +29,14 @@ export default defineConfig({
react({
experimentalReactChildren: true,
}),
- sentry({
- dsn: import.meta.env.PUBLIC_SENTRY_DSN,
- sourceMapsUploadOptions: {
- org: import.meta.env.SENTRY_ORG,
- project: import.meta.env.SENTRY_PROJECT,
- authToken: import.meta.env.SENTRY_AUTH_TOKEN,
- },
- }),
+ // sentry({
+ // dsn: import.meta.env.PUBLIC_SENTRY_DSN,
+ // sourceMapsUploadOptions: {
+ // org: import.meta.env.SENTRY_ORG,
+ // project: import.meta.env.SENTRY_PROJECT,
+ // authToken: import.meta.env.SENTRY_AUTH_TOKEN,
+ // },
+ // }),
],
vite: {
css: {
@@ -47,9 +47,17 @@ export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
+ '@/supabase': path.resolve(__dirname, './src/supabase'),
+ '@prodkt/assets': path.resolve(__dirname, '../../packages/assets'),
+ '@prodkt/config/tailwind': path.resolve(
+ __dirname,
+ '../../packages/config/tailwind',
+ ),
+ '@prodkt/ui': path.resolve(__dirname, '../../packages/ui/dist'),
},
},
ssr: {
+ noExternal: ['@prodkt/ui'],
external: ['image-size', 'tiny-glob'],
},
},
@@ -57,4 +65,16 @@ export default defineConfig({
adapter: vercel({
imageService: true,
}),
+ experimental: {
+ env: {
+ schema: {
+ SUPABASE_DEV_MODE: envField.string({
+ context: 'server',
+ access: 'public',
+ default: 'false',
+ }),
+ },
+ },
+ // serverIslands: true,
+ },
})
diff --git a/apps/marketing/eslint.config.js b/apps/marketing/eslint.config.js
index 0204931..83d3be4 100644
--- a/apps/marketing/eslint.config.js
+++ b/apps/marketing/eslint.config.js
@@ -11,6 +11,7 @@ export default defineConfig(
tsconfigRootDir: import.meta.dirname,
},
},
+ ignores: ['public'],
rules: {
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
diff --git a/apps/marketing/package.json b/apps/marketing/package.json
index a1a83b5..dd2c166 100644
--- a/apps/marketing/package.json
+++ b/apps/marketing/package.json
@@ -8,6 +8,7 @@
"type": "module",
"scripts": {
"build": "astro check && astro build",
+ "build:prodkt-css": "npx tailwindcss -c ./tailwind.config.ts -i ./src/styles/globals.css -o ./public/prodkt-styles.css --watch",
"clean": "bun run rm -rf .astro dist *.tsbuildinfo playwright-report test-results",
"dev": "astro dev",
"generate:types": "bunx supabase gen types --lang=typescript --project-id odzdpcvclydcqawdagdt > src/database.types.ts",
@@ -20,10 +21,13 @@
"dependencies": {
"@astrojs/rss": "^4.0.7",
"@astrojs/vercel": "^7.8.1",
- "@codesandbox/sandpack-react": "^2.19.8",
+ "@astrolib/seo": "^1.0.0-beta.6",
+ "@codesandbox/sandpack-react": "^2.19.9",
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/modifiers": "^7.0.0",
"@dnd-kit/sortable": "^8.0.0",
+ "@dotlottie/react-player": "^1.6.19",
+ "@lottiefiles/dotlottie-react": "^0.9.0",
"@prodkt/assets": "workspace:*",
"@prodkt/blocks": "workspace:*",
"@prodkt/env": "workspace:*",
@@ -33,40 +37,53 @@
"@supabase/ssr": "^0.5.1",
"@supabase/supabase-js": "^2.45.4",
"@t3-oss/env-core": "^0.11.1",
+ "@tiptap/extension-character-count": "^2.1.12",
+ "@tiptap/extension-highlight": "^2.1.11",
+ "@tiptap/extension-link": "^2.2.4",
+ "@tiptap/extension-placeholder": "^2.1.11",
+ "@tiptap/extension-typography": "^2.1.11",
+ "@tiptap/pm": "^2.1.11",
+ "@tiptap/react": "^2.1.11",
+ "@tiptap/starter-kit": "^2.1.11",
"@total-typescript/ts-reset": "^0.5.1",
"@types/cheerio": "^0.22.35",
"@types/micromatch": "^4.0.9",
"@xyflow/react": "^12.3.0",
- "astro": "^4.15.4",
+ "astro": "^4.15.9",
+ "base64-arraybuffer": "^1.0.2",
+ "chart.js": "^4.4.4",
"cheerio": "^1.0.0",
- "lucide-react": "^0.441.0",
+ "class-variance-authority": "^0.7.0",
+ "lucide-react": "^0.445.0",
"micromatch": "^4.0.8",
"next-themes": "^0.3.0",
- "posthog-js": "^1.161.5",
+ "posthog-js": "^1.164.2",
"react": "^18.3.1",
+ "react-chartjs-2": "^5.2.0",
"react-dom": "^18.3.1",
"reactflow": "^11.11.4",
- "sass": "^1.78.0",
- "supabase": "^1.192.5",
+ "sass": "^1.79.3",
+ "supabase": "^1.200.3",
+ "swiper": "^11.1.14",
+ "tailwind-merge": "^2.5.2",
"zod": "^3.23.8"
},
"devDependencies": {
"@astrojs/check": "^0.9.3",
- "@astrojs/mdx": "^3.1.6",
+ "@astrojs/mdx": "^3.1.7",
"@astrojs/react": "^3.6.2",
"@astrojs/sitemap": "^3.1.6",
- "@astrojs/tailwind": "^5.1.0",
+ "@astrojs/tailwind": "^5.1.1",
"@playwright/test": "^1.45.2",
"@prodkt/eslint": "workspace:*",
"@prodkt/tailwind": "workspace:*",
"@prodkt/tsconfig": "workspace:*",
- "@sentry/astro": "^8.30.0",
- "@types/react": "^18.3.6",
+ "@types/react": "^18.3.9",
"@types/react-dom": "^18.3.0",
"autoprefixer": "^10.4.20",
"dotenv": "^16.4.5",
"postcss": "^8.4.47",
"postcss-import": "^16.1.0",
- "tailwindcss": "^3.4.11"
+ "tailwindcss": "^3.4.13"
}
}
diff --git a/apps/marketing/public/posthog.js b/apps/marketing/public/posthog.js
new file mode 100644
index 0000000..369cf12
--- /dev/null
+++ b/apps/marketing/public/posthog.js
@@ -0,0 +1,47 @@
+!(function (t, e) {
+ var o, n, p, r
+ e.__SV ||
+ ((window.posthog = e),
+ (e._i = []),
+ (e.init = function (i, s, a) {
+ function g(t, e) {
+ var o = e.split('.')
+ 2 == o.length && ((t = t[o[0]]), (e = o[1])),
+ (t[e] = function () {
+ t.push([e].concat(Array.prototype.slice.call(arguments, 0)))
+ })
+ }
+ ;((p = t.createElement('script')).type = 'text/javascript'),
+ (p.async = !0),
+ (p.src =
+ s.api_host.replace('.i.posthog.com', '-assets.i.posthog.com') +
+ '/static/array.js'),
+ (r = t.getElementsByTagName('script')[0]).parentNode.insertBefore(p, r)
+ var u = e
+ for (
+ void 0 !== a ? (u = e[a] = []) : (a = 'posthog'),
+ u.people = u.people || [],
+ u.toString = function (t) {
+ var e = 'posthog'
+ return 'posthog' !== a && (e += '.' + a), t || (e += ' (stub)'), e
+ },
+ u.people.toString = function () {
+ return u.toString(1) + '.people (stub)'
+ },
+ o =
+ 'init capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug'.split(
+ ' ',
+ ),
+ n = 0;
+ n < o.length;
+ n++
+ )
+ g(u, o[n])
+ e._i.push([i, s, a])
+ }),
+ (e.__SV = 1))
+})(document, window.posthog || [])
+posthog.init('phc_WeLwdCDRIfwgIuVhKoeU7kZUEP5seUxfWjREmPsnhwJ', {
+ api_host: 'https://us.i.posthog.com',
+ person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well
+})
diff --git a/apps/marketing/public/prodkt-styles.css b/apps/marketing/public/prodkt-styles.css
new file mode 100644
index 0000000..8a8cb2d
--- /dev/null
+++ b/apps/marketing/public/prodkt-styles.css
@@ -0,0 +1,21133 @@
+:root .light,
+:root .dark {
+ --sp-space-1: 4px;
+ --sp-space-2: 8px;
+ --sp-space-3: 12px;
+ --sp-space-4: 16px;
+ --sp-space-5: 20px;
+ --sp-space-6: 24px;
+ --sp-space-7: 28px;
+ --sp-space-8: 32px;
+ --sp-space-9: 36px;
+ --sp-space-10: 40px;
+ --sp-space-11: 44px;
+ --sp-border-radius: 12px;
+ --sp-layout-height: 300px;
+ --sp-layout-headerHeight: 28px;
+ --sp-transitions-default: 150ms ease;
+ --sp-zIndices-base: 1;
+ --sp-zIndices-overlay: 2;
+ --sp-zIndices-top: 3;
+ --sp-colors-surface1: var(--gray9) !important;
+ --sp-colors-surface2: transparent;
+ --sp-colors-surface3: transparent;
+ --sp-colors-disabled: var(--gray9);
+ --sp-colors-base: transparent;
+ --sp-colors-clickable: var(--gray7);
+ --sp-colors-hover: var(--gray8);
+ --sp-colors-accent: var(--gray10);
+ --sp-colors-error: #ffb4a6;
+ --sp-colors-errorSurface: #690000;
+ --sp-colors-warning: #e7c400;
+ --sp-colors-warningSurface: #3a3000;
+ --sp-font-body: 'Labil Grotesk';
+ --sp-font-mono: 'IBM Plex Mono';
+ --sp-font-size: 12px;
+ --sp-font-lineHeight: 20px;
+ --sp-syntax-color-plain: var(--gray10);
+ --sp-syntax-color-comment: #757575;
+ --sp-syntax-fontStyle-comment: italic;
+ --sp-syntax-color-keyword: #77b7d7;
+ --sp-syntax-color-tag: #dfab5c;
+ --sp-syntax-color-punctuation: var(--gray10);
+ --sp-syntax-color-definition: #86d9ca;
+ --sp-syntax-color-property: #77b7d7;
+ --sp-syntax-color-static: #c64640;
+ --sp-syntax-color-string: #977cdc;
+}
+
+@tailwind base;
+
+@layer {
+ .prodkt-codeblock-wrapper,
+ .prodkt-codeblock-layout {
+ width: 100% !important;
+ border-radius: 1rem 0rem 1rem 0rem !important;
+ border: 0 !important;
+ background-color: transparent !important;
+ }
+
+ .prodkt-codeblock-wrapper:is(.dark *),
+ .prodkt-codeblock-layout:is(.dark *) {
+ background-color: transparent !important;
+ }
+
+ .prodkt-codeblock-wrapper,
+ .prodkt-codeblock-layout {
+ overflow: auto;
+ }
+}
+
+a.prodkt-codepreview-actions {
+ display: none;
+ background-color: transparent;
+}
+
+.prodkt-codeblock-wrapper {
+ position: relative;
+ top: 0px;
+ max-height: calc(100dvh - 110px);
+ width: 100%;
+}
+
+.prodkt-codeblock-layout {
+ position: relative;
+ top: 0;
+ max-height: calc(100dvh - 110px);
+}
+
+.prodkt-codeblock-tab-button,
+.sp-tab-button,
+.prodkt-codeblock-tab-button,
+.prodkt-codeblock-tab-button:focus,
+.sp-tab-button:focus,
+.prodkt-codeblock-tab-button:focus,
+aria-selected:prodkt-codeblock-tab-button,
+aria-selected:sp-tab-button,
+aria-selected:prodkt-codeblock-tab-button {
+ border-radius: 0.5rem !important;
+ border-width: 1px !important;
+ border-style: none !important;
+ border-color: transparent !important;
+ background-color: transparent !important;
+ padding-top: 0.25rem !important;
+ padding-bottom: 0.125rem !important;
+ font-size: 0.75rem !important;
+ line-height: 1rem !important;
+ --tw-shadow: 0 0 #0000 !important;
+ --tw-shadow-colored: 0 0 #0000 !important;
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) !important;
+ outline-width: 0px !important;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000) !important;
+ --tw-ring-color: transparent !important;
+ min-height: auto !important;
+ padding-left: 12px !important;
+ padding-right: 12px !important;
+ height: 32px;
+}
+
+.sp-tabs-scrollable-container:is(.dark *),
+.prodkt-tabs-scrollable-container:is(.dark *),
+.sp-tabs-scrollable-container,
+.prodkt-tabs-scrollable-container {
+ border-style: none !important;
+ border-color: transparent !important;
+}
+
+.prodkt-codeblock-tab-button[data-active='true'],
+data-active:prodkt-codeblock-tab-button,
+.sp-tab-button .prodkt-codeblock-tab-button[data-active='true'] {
+ border-radius: 0.5rem !important;
+ border-style: none !important;
+ outline: 2px solid transparent !important;
+ outline-offset: 2px !important;
+ outline-width: 0px !important;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000) !important;
+}
+
+.prodkt-codeblock-tab-button[data-active='true'][aria-selected='true'],
+data-active:prodkt-codeblock-tab-button[aria-selected='true'],
+.sp-tab-button
+ .prodkt-codeblock-tab-button[data-active='true'][aria-selected='true'] {
+ border-style: none !important;
+}
+
+.prodkt-codeblock-tab-container,
+.prodkt-codeblock-tab-container:has(button:focus),
+.sp-tab-container,
+.sp-tab-container:has(button:focus),
+.prodkt-codeblock-tab-container button,
+.sp-tab-container button,
+.prodkt-codeblock-tab-container[data-active='true'],
+.sp-tab-container[data-active='true'],
+.prodkt-codeblock-tab-container[data-active='true'] button,
+.sp-tab-container[data-active='true'] button,
+.sp-tab-button,
+.sp-tab-button button,
+.sp-tab-button[data-active='true'],
+button[data-active='true'],
+aria-selected:prodkt-codeblock-tab-container {
+ border-style: none !important;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000) !important;
+ outline: 2px solid transparent !important;
+ outline-offset: 2px !important;
+}
+
+.prodkt-codeblock-tab-container[aria-selected='true'],
+.prodkt-codeblock-tab-container:has(button:focus)[aria-selected='true'],
+.sp-tab-container[aria-selected='true'],
+.sp-tab-container:has(button:focus)[aria-selected='true'],
+.prodkt-codeblock-tab-container button[aria-selected='true'],
+.sp-tab-container button[aria-selected='true'],
+.prodkt-codeblock-tab-container[data-active='true'][aria-selected='true'],
+.sp-tab-container[data-active='true'][aria-selected='true'],
+.prodkt-codeblock-tab-container[data-active='true']
+ button[aria-selected='true'],
+.sp-tab-container[data-active='true'] button[aria-selected='true'],
+.sp-tab-button[aria-selected='true'],
+.sp-tab-button button[aria-selected='true'],
+.sp-tab-button[data-active='true'][aria-selected='true'],
+button[data-active='true'][aria-selected='true'],
+aria-selected:prodkt-codeblock-tab-container[aria-selected='true'] {
+ border-color: var(--grayA1) !important;
+ outline: 2px solid transparent !important;
+ outline-offset: 2px !important;
+ outline-color: var(--grayA1) !important;
+ --tw-ring-color: var(--grayA1) !important;
+}
+
+.sp-pre-placeholder,
+.prodkt-codeblock-pre-placeholder {
+ width: 100%;
+ background-color: transparent;
+}
+
+.prodkt-codemirror-gutters,
+.cm-gutters {
+ border-radius: 0.5rem !important;
+ background-color: transparent !important;
+ padding-right: 0.25rem !important;
+}
+
+.prodkt-codeblock-read-only {
+ background-color: transparent;
+}
+
+.sp-tab-container .prodkt-codeblock-tab-container,
+.sp-tab-container,
+.prodkt-codeblock-tab-container,
+.sp-tab-container.prodkt-codeblock-tab-container {
+ outline: none !important;
+ outline-color: var(--grayA4);
+}
+
+.prodkt-codeblock-code-editor,
+.sp-code-editor {
+ width: 100%;
+}
+
+.prodkt-codeblock-code-editor,
+.prodkt-codeblock-codemirror-editor,
+.cm-editor,
+.prodkt-codeblock-codemirror-scroller,
+.cm-scroller,
+.cm-activeLine .cm-line,
+.cm-activeLine,
+.cm-line,
+div.cm-line,
+.sp-code-editor,
+.prodkt-code-editor,
+.sp-cm,
+.prodkt-cm-editor,
+.sp-syntax-string,
+.prodkt-syntax-string,
+span.sp-syntax-string,
+div.cm-string,
+.sp-syntax-property,
+.prodkt-syntax-property,
+span.sp-syntax-property,
+div.cm-property,
+.sp-syntax-definition,
+.prodkt-syntax-definition,
+span.sp-syntax-definition,
+div.cm-definition,
+.sp-syntax-punctuation,
+.prodkt-syntax-punctuation,
+span.sp-syntax-punctuation,
+div.cm-punctuation,
+.sp-syntax-plain,
+.prodkt-syntax-plain,
+span.sp-syntax-plain,
+div.cm-plain,
+.sp-syntax-keyword,
+.prodkt-syntax-keyword,
+span.sp-syntax-keyword,
+div.cm-keyword,
+.sp-syntax-static,
+.prodkt-syntax-static,
+span.sp-syntax-static,
+div.cm-static,
+.sp-syntax-comment,
+.prodkt-syntax-comment,
+span.sp-syntax-comment,
+div.cm-comment {
+ border-width: 0px;
+ border-color: transparent;
+ background-color: transparent;
+ background-image: none;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+ --tw-ring-inset: inset;
+ --tw-ring-color: transparent;
+ font-family: 'IBM Plex Mono', monospace !important;
+ font-size: 0.75rem !important;
+ line-height: 1rem !important;
+}
+
+.prodkt-codeblock-tabs {
+ position: absolute;
+ top: 0px;
+ bottom: auto;
+ z-index: 10;
+ margin-top: 0px;
+ display: flex;
+ min-height: 48px;
+ width: 100%;
+ flex-direction: row;
+ align-items: center;
+ justify-content: flex-start !important;
+ gap: 0px !important;
+ overflow: hidden;
+ border-radius: 1rem;
+ border-bottom-width: 0px !important;
+ border-style: none;
+ background-color: var(--gray1) !important;
+ padding-left: 0.375rem;
+ padding-right: 0.375rem;
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+ font-size: 0.75rem;
+ line-height: 1rem;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+ --tw-ring-inset: inset;
+ --tw-ring-color: var(--grayA4);
+}
+
+.prodkt-codeblock-tabs-scrollable-container {
+ position: relative;
+ z-index: 10;
+ display: flex;
+ min-height: 48px;
+ width: 100%;
+ flex-direction: row;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 0px;
+ overflow-y: hidden;
+ overflow-x: scroll;
+ border-radius: 0.75rem;
+ padding-top: 0.5rem !important;
+ padding-bottom: 0.5rem !important;
+ padding-left: 0px !important;
+ padding-right: 0px !important;
+ font-size: 0.75rem;
+ line-height: 1rem;
+ font-weight: 400;
+ letter-spacing: 0.0125rem;
+}
+
+.sp-tabs-scrollable-container:has(
+ [role='tab'],
+ [aria-selected='false'],
+ [aria-selected='true']
+ ),
+.sp-tabs-scrollable-container:has(button),
+.sp-tabs-scrollable-container,
+.sp-tabs-scrollable-container[role='tab'],
+.prodkt-codeblock-tabs-scrollable-container[role='tab'],
+.prodkt-codeblock-tabs-scrollable-container,
+.sp-tabs-scrollable-container .prodkt-codeblock-tabs-scrollable-container,
+.sp-tabs-scrollable-container.prodkt-codeblock-tabs-scrollable-container {
+ padding-right: 1px !important;
+ padding-left: 0 !important;
+ padding: 0 0 0 0 !important;
+ margin: 0;
+}
+
+.prodkt-codeblock-tab-container button {
+ margin-left: 0px !important;
+ margin-right: -20px !important;
+ border-radius: 1rem !important;
+ border-width: 1px !important;
+ border-color: var(--grayA3) !important;
+ background-color: var(--grayA1) !important;
+ padding-top: 0.5rem !important;
+ padding-bottom: 0.5rem !important;
+ padding-left: 0.75rem !important;
+ padding-right: 0.75rem !important;
+ color: var(--gray12) !important;
+}
+
+.prodkt-codeblock-tab-container button:hover {
+ color: var(--accent11) !important;
+}
+
+.prodkt-codeblock-tabs-scrollable-container button[data-active='true'] {
+ color: var(--accent11) !important;
+}
+
+.prodkt-codeblock-tab-container button[data-active='true'] {
+ border-radius: 0.75rem !important;
+ border-width: 1px !important;
+ border-color: var(--grayA1) !important;
+ background-color: var(--gray5) !important;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000) !important;
+ --tw-ring-inset: inset !important;
+ --tw-ring-color: var(--gray6) !important;
+}
+
+.prodkt-codeblock-tab-container button[data-active='true']:is(.dark *) {
+ --tw-ring-color: var(--gray6) !important;
+}
+
+.prodkt-codeblock-tabs-scrollable-container::-webkit-resizer {
+ background-color: transparent;
+ border: 0px solid transparent;
+}
+
+.prodkt-codeblock-tabs-scrollable-container::-webkit-scrollbar {
+ background-color: transparent;
+ border: 0px solid transparent;
+ width: auto;
+ height: 5px;
+ border-radius: 9999px;
+}
+
+.prodkt-codeblock-tabs-scrollable-container::-webkit-scrollbar-button {
+ background-color: transparent;
+ border: 0px solid transparent;
+ border-radius: 9999px;
+}
+
+.prodkt-codeblock-tabs-scrollable-container::-webkit-scrollbar-corner {
+ background-color: transparent;
+ border: 0px solid transparent;
+ border-radius: 9999px;
+}
+
+.prodkt-codeblock-tabs-scrollable-container::-webkit-scrollbar-thumb {
+ background-color: var(--grayA8);
+ border: 0px solid var(--grayA2);
+ border-radius: 9999px;
+}
+
+.prodkt-codeblock-tabs-scrollable-container::-webkit-scrollbar-track {
+ background-color: var(--gray4);
+ border: 0px solid var(--gray5);
+ border-right-width: 0;
+ border-radius: 9999px;
+}
+
+.prodkt-codeblock-tabs-scrollable-container::-webkit-scrollbar-track-piece {
+ background-color: transparent;
+ border: 0px solid transparent;
+ border-radius: 9999px;
+}
+
+.prodkt-codeblock-editor {
+ margin-bottom: 0px !important;
+ height: 100% !important;
+ border-radius: 0.5rem !important;
+ border-width: 1px !important;
+ border-style: none !important;
+ border-color: transparent !important;
+ background-color: transparent !important;
+ padding-top: 0.25rem !important;
+ padding-bottom: 0px !important;
+ font-size: 0.75rem !important;
+ line-height: 1rem !important;
+ --tw-shadow: 0 0 #0000 !important;
+ --tw-shadow-colored: 0 0 #0000 !important;
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow) !important;
+ outline-width: 0px !important;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color) !important;
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color) !important;
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000) !important;
+ --tw-ring-color: transparent !important;
+}
+
+.sp-stack {
+ bottom: 0px;
+ top: auto;
+ margin-top: auto;
+ margin-bottom: 0px;
+ display: flex;
+ height: 100%;
+ flex-direction: column;
+ flex-wrap: nowrap;
+ overflow: hidden;
+ border-style: none;
+}
+
+.sp-editor {
+ position: relative;
+}
+
+.prodkt-cm-editor {
+ height: calc(100dvh - 248px);
+ min-height: calc(100dvh - 248px);
+ max-height: calc(100dvh - 248px);
+ overflow-x: hidden;
+ overflow-y: auto;
+ border-radius: 1rem;
+ background-color: var(--gray4);
+}
+
+.prodkt-cm-editor:is(.dark *) {
+ background-color: var(--gray1);
+}
+
+.prodkt-cm-editor {
+ border-width: 1px;
+ border-color: var(--gray6);
+}
+
+.prodkt-cm-editor:is(.dark *) {
+ border-color: var(--grayA4);
+}
+
+.prodkt-code-editor,
+.sp-code-editor {
+ background-color: transparent !important;
+ overflow: auto;
+ margin-top: 50px;
+ border-radius: 1rem;
+}
+
+.cm-scroller {
+ padding-right: 0.5rem !important;
+}
+
+.cm-scroller::-webkit-resizer {
+ background-color: transparent !important;
+ border: 0px solid transparent !important;
+}
+
+.cm-scroller::-webkit-scrollbar {
+ background-color: transparent !important;
+ border: 0px solid transparent !important;
+ width: 8px !important;
+ height: 5px !important;
+ border-radius: 9999px !important;
+}
+
+.cm-scroller::-webkit-scrollbar-button {
+ background-color: transparent !important;
+ border: 0px solid transparent !important;
+ border-radius: 9999px !important;
+}
+
+.cm-scroller::-webkit-scrollbar-corner {
+ background-color: transparent !important;
+ border: 0px solid transparent !important;
+ border-radius: 9999px !important;
+}
+
+.cm-scroller::-webkit-scrollbar-thumb {
+ background-color: var(--gray10) !important;
+ border: 0px solid var(--grayA2) !important;
+ border-radius: 9999px !important;
+}
+
+.cm-scroller::-webkit-scrollbar-track {
+ background-color: var(--gray1) !important;
+ border: 0px solid var(--gray3) !important;
+ border-radius: 9999px !important;
+}
+
+.cm-scroller::-webkit-scrollbar-track-piece {
+ background-color: transparent !important;
+ border: 0px solid transparent !important;
+ border-radius: 9999px !important;
+}
+
+.sp-syntax-definition {
+ color: var(--iris10) !important;
+}
+
+.sp-syntax-property {
+ color: var(--tomato11) !important;
+}
+
+.sp-syntax-string {
+ color: var(--mauve10) !important;
+}
+
+.sp-syntax-punctuation {
+ color: var(--mauve11) !important;
+}
+
+.sp-syntax-keyword {
+ color: var(--violet8) !important;
+}
+
+.sp-syntax-plain {
+ color: var(--sky11) !important;
+}
+
+.sp-syntax-plain:is(.dark *) {
+ color: var(--sky9) !important;
+}
+
+.sp-syntax-static {
+ color: var(--mauve10) !important;
+}
+
+.cm-line {
+ color: var(--violet10) !important;
+}
+
+/* @import '@prodkt/tailwind/color'; */
+
+:root,
+.light-theme,
+.light {
+ --ghost-a1: rgba(0, 0, 0, 0.05);
+ --ghost-a2: rgba(0, 0, 0, 0.1);
+ --ghost-a3: rgba(0, 0, 0, 0.15);
+ --ghost-a4: rgba(0, 0, 0, 0.2);
+ --ghost-a5: rgba(0, 0, 0, 0.3);
+ --ghost-a6: rgba(0, 0, 0, 0.4);
+ --ghost-a7: rgba(0, 0, 0, 0.5);
+ --ghost-a8: rgba(0, 0, 0, 0.6);
+ --ghost-a9: rgba(0, 0, 0, 0.7);
+ --ghost-a10: rgba(0, 0, 0, 0.8);
+ --ghost-a11: rgba(0, 0, 0, 0.9);
+ --ghost-a12: rgba(0, 0, 0, 0.95);
+ --ghost-aa1: rgba(255, 255, 255, 0.05);
+ --ghost-aa2: rgba(255, 255, 255, 0.1);
+ --ghost-aa3: rgba(255, 255, 255, 0.15);
+ --ghost-aa4: rgba(255, 255, 255, 0.2);
+ --ghost-aa5: rgba(255, 255, 255, 0.3);
+ --ghost-aa6: rgba(255, 255, 255, 0.4);
+ --ghost-aa7: rgba(255, 255, 255, 0.5);
+ --ghost-aa8: rgba(255, 255, 255, 0.6);
+ --ghost-aa9: rgba(255, 255, 255, 0.7);
+ --ghost-aa10: rgba(255, 255, 255, 0.8);
+ --ghost-aa11: rgba(255, 255, 255, 0.9);
+ --ghost-aa12: rgba(255, 255, 255, 0.95);
+ --ghost-1: rgb(12, 12, 12);
+ --ghost-2: rgb(25, 25, 25);
+ --ghost-3: rgb(38, 38, 38);
+ --ghost-4: rgb(51, 51, 51);
+ --ghost-5: rgb(76, 76, 76);
+ --ghost-6: rgb(102, 102, 102);
+ --ghost-7: rgb(127, 127, 127);
+ --ghost-8: rgb(153, 153, 153);
+ --ghost-9: rgb(178, 178, 178);
+ --ghost-10: rgb(204, 204, 204);
+ --ghost-11: rgb(229, 229, 229);
+ --ghost-12: rgb(242, 242, 242);
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root {
+ --ghost-a1: color(display-p3 0 0 0 / 0.05);
+ --ghost-a2: color(display-p3 0 0 0 / 0.1);
+ --ghost-a3: color(display-p3 0 0 0 / 0.15);
+ --ghost-a4: color(display-p3 0 0 0 / 0.2);
+ --ghost-a5: color(display-p3 0 0 0 / 0.3);
+ --ghost-a6: color(display-p3 0 0 0 / 0.4);
+ --ghost-a7: color(display-p3 0 0 0 / 0.5);
+ --ghost-a8: color(display-p3 0 0 0 / 0.6);
+ --ghost-a9: color(display-p3 0 0 0 / 0.7);
+ --ghost-a10: color(display-p3 0 0 0 / 0.8);
+ --ghost-a11: color(display-p3 0 0 0 / 0.9);
+ --ghost-a12: color(display-p3 0 0 0 / 0.95);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --ghost-a1: rgba(255, 255, 255, 0.05);
+ --ghost-a2: rgba(255, 255, 255, 0.1);
+ --ghost-a3: rgba(255, 255, 255, 0.15);
+ --ghost-a4: rgba(255, 255, 255, 0.2);
+ --ghost-a5: rgba(255, 255, 255, 0.3);
+ --ghost-a6: rgba(255, 255, 255, 0.4);
+ --ghost-a7: rgba(255, 255, 255, 0.5);
+ --ghost-a8: rgba(255, 255, 255, 0.6);
+ --ghost-a9: rgba(255, 255, 255, 0.7);
+ --ghost-a10: rgba(255, 255, 255, 0.8);
+ --ghost-a11: rgba(255, 255, 255, 0.9);
+ --ghost-a12: rgba(255, 255, 255, 0.95);
+ --ghost-aa1: rgba(0, 0, 0, 0.05);
+ --ghost-aa2: rgba(0, 0, 0, 0.1);
+ --ghost-aa3: rgba(0, 0, 0, 0.15);
+ --ghost-aa4: rgba(0, 0, 0, 0.2);
+ --ghost-aa5: rgba(0, 0, 0, 0.3);
+ --ghost-aa6: rgba(0, 0, 0, 0.4);
+ --ghost-aa7: rgba(0, 0, 0, 0.5);
+ --ghost-aa8: rgba(0, 0, 0, 0.6);
+ --ghost-aa9: rgba(0, 0, 0, 0.7);
+ --ghost-aa10: rgba(0, 0, 0, 0.8);
+ --ghost-aa11: rgba(0, 0, 0, 0.9);
+ --ghost-aa12: rgba(0, 0, 0, 0.95);
+ --ghost-1: rgb(242, 242, 242);
+ --ghost-2: rgb(229, 229, 229);
+ --ghost-3: rgb(204, 204, 204);
+ --ghost-4: rgb(178, 178, 178);
+ --ghost-5: rgb(153, 153, 153);
+ --ghost-6: rgb(127, 127, 127);
+ --ghost-7: rgb(102, 102, 102);
+ --ghost-8: rgb(76, 76, 76);
+ --ghost-9: rgb(51, 51, 51);
+ --ghost-10: rgb(38, 38, 38);
+ --ghost-11: rgb(25, 25, 25);
+ --ghost-12: rgb(12, 12, 12);
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --ghost-a1: color(display-p3 1 1 1 / 0.05);
+ --ghost-a2: color(display-p3 1 1 1 / 0.1);
+ --ghost-a3: color(display-p3 1 1 1 / 0.15);
+ --ghost-a4: color(display-p3 1 1 1 / 0.2);
+ --ghost-a5: color(display-p3 1 1 1 / 0.3);
+ --ghost-a6: color(display-p3 1 1 1 / 0.4);
+ --ghost-a7: color(display-p3 1 1 1 / 0.5);
+ --ghost-a8: color(display-p3 1 1 1 / 0.6);
+ --ghost-a9: color(display-p3 1 1 1 / 0.7);
+ --ghost-a10: color(display-p3 1 1 1 / 0.8);
+ --ghost-a11: color(display-p3 1 1 1 / 0.9);
+ --ghost-a12: color(display-p3 1 1 1 / 0.95);
+ }
+ }
+}
+
+button[type='button'],
+button[aria-haspopup='menu'],
+button[aria-expanded='false'],
+button[data-state='closed'],
+button,
+input:where([type='button']),
+input:where([type='reset']),
+input:where([type='submit']) {
+ outline: none;
+ outline-color: var(--grayA4);
+}
+
+.hero-mask {
+ mask-image: radial-gradient(
+ 50% 50% at 50% 50%,
+ rgba(255, 255, 255, 1) 3.78%,
+ rgba(255, 255, 255, 0.1) 80.27%,
+ rgba(255, 255, 255, 0) 100%
+ );
+ -webkit-mask-image: radial-gradient(
+ 50% 50% at 50% 50%,
+ rgba(255, 255, 255, 1) 3.78%,
+ rgba(255, 255, 255, 0.1) 80.27%,
+ rgba(255, 255, 255, 0) 100%
+ );
+}
+
+.gradientMask-to-t {
+ mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 1) 0%,
+ rgba(0, 0, 0, 0) 100%
+ );
+ -webkit-mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 1) 0%,
+ rgba(0, 0, 0, 0) 100%
+ );
+}
+
+.gradientMask-to-t-50 {
+ mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 1) 50%,
+ rgba(0, 0, 0, 0) 100%
+ );
+ -webkit-mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 1) 50%,
+ rgba(0, 0, 0, 0) 100%
+ );
+}
+
+.gradientMask-to-t-20 {
+ mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 1) 80%,
+ rgba(0, 0, 0, 0) 100%
+ );
+ -webkit-mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 1) 80%,
+ rgba(0, 0, 0, 0) 100%
+ );
+}
+
+.gradientMask-to-t-10 {
+ mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 1) 90%,
+ rgba(0, 0, 0, 0) 100%
+ );
+ -webkit-mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 1) 90%,
+ rgba(0, 0, 0, 0) 100%
+ );
+}
+
+.gradientMask-to-b {
+ mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(0, 0, 0, 1) 100%
+ );
+ -webkit-mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(0, 0, 0, 1) 100%
+ );
+}
+
+.gradientMask-to-b-20 {
+ mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(0, 0, 0, 1) 20%
+ );
+ -webkit-mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(0, 0, 0, 1) 20%
+ );
+}
+
+.gradientMask-to-b-10 {
+ mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(0, 0, 0, 1) 10%
+ );
+ -webkit-mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(0, 0, 0, 1) 10%
+ );
+}
+
+.gradientMask-to-l {
+ mask-image: linear-gradient(
+ 270deg,
+ rgba(255, 255, 255, 1) 0%,
+ rgba(0, 0, 0, 0) 100%
+ );
+ -webkit-mask-image: linear-gradient(
+ 270deg,
+ rgba(255, 255, 255, 1) 0%,
+ rgba(0, 0, 0, 0) 100%
+ );
+}
+
+.gradientMask-to-r {
+ mask-image: linear-gradient(
+ 270deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(0, 0, 0, 1) 100%
+ );
+ -webkit-mask-image: linear-gradient(
+ 270deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(0, 0, 0, 1) 100%
+ );
+}
+
+.gradientMask-workShowcase {
+ -webkit-mask-image: radial-gradient(
+ circle,
+ rgba(0, 0, 0, 1) 25%,
+ rgba(0, 0, 0, 0.5) 35%,
+ rgba(0, 0, 0, 0) 80%
+ );
+ mask-image: radial-gradient(
+ circle,
+ rgba(0, 0, 0, 1) 25%,
+ rgba(0, 0, 0, 0.5) 35%,
+ rgba(0, 0, 0, 0) 80%
+ );
+}
+
+.prodkt-blog-content a {
+ font-weight: 400 !important;
+ color: var(--accent10) !important;
+ -webkit-text-decoration-line: underline !important;
+ text-decoration-line: underline !important;
+ text-underline-offset: 4px !important;
+}
+
+:root,
+.light,
+.light-theme {
+ --amberA1: #c0800004;
+ --amberA2: #f4d10016;
+ --amberA3: #ffde003d;
+ --amberA4: #ffd40063;
+ --amberA5: #f8cf0088;
+ --amberA6: #eab5008c;
+ --amberA7: #dc9b009d;
+ --amberA8: #da8a00c9;
+ --amberA9: #ffb300c2;
+ --amberA10: #ffb300e7;
+ --amberA11: #ab6400;
+ --amberA12: #341500dd;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --amberA1: color(display-p3 0.757 0.514 0.024 / 0.016);
+ --amberA2: color(display-p3 0.902 0.804 0.008 / 0.079);
+ --amberA3: color(display-p3 0.965 0.859 0.004 / 0.22);
+ --amberA4: color(display-p3 0.969 0.82 0.004 / 0.35);
+ --amberA5: color(display-p3 0.933 0.796 0.004 / 0.475);
+ --amberA6: color(display-p3 0.875 0.682 0.004 / 0.495);
+ --amberA7: color(display-p3 0.804 0.573 0 / 0.557);
+ --amberA8: color(display-p3 0.788 0.502 0 / 0.699);
+ --amberA9: color(display-p3 1 0.686 0 / 0.742);
+ --amberA10: color(display-p3 0.945 0.643 0 / 0.726);
+ --amberA11: color(display-p3 0.64 0.4 0);
+ --amberA12: color(display-p3 0.294 0.208 0.145);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --amberA1: #e63c0006;
+ --amberA2: #fd9b000d;
+ --amberA3: #fa820022;
+ --amberA4: #fc820032;
+ --amberA5: #fd8b0041;
+ --amberA6: #fd9b0051;
+ --amberA7: #ffab2567;
+ --amberA8: #ffae3587;
+ --amberA9: #ffc53d;
+ --amberA10: #ffd60a;
+ --amberA11: #ffca16;
+ --amberA12: #ffe7b3;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --amberA1: color(display-p3 0.992 0.298 0 / 0.017);
+ --amberA2: color(display-p3 0.988 0.651 0 / 0.047);
+ --amberA3: color(display-p3 1 0.6 0 / 0.118);
+ --amberA4: color(display-p3 1 0.557 0 / 0.185);
+ --amberA5: color(display-p3 1 0.592 0 / 0.24);
+ --amberA6: color(display-p3 1 0.659 0.094 / 0.299);
+ --amberA7: color(display-p3 1 0.714 0.263 / 0.383);
+ --amberA8: color(display-p3 0.996 0.729 0.306 / 0.5);
+ --amberA9: color(display-p3 1 0.769 0.259);
+ --amberA10: color(display-p3 1 0.871 0.149);
+ --amberA11: color(display-p3 1 0.8 0.29);
+ --amberA12: color(display-p3 0.984 0.909 0.726);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --amber1: #16120c;
+ --amber2: #1d180f;
+ --amber3: #302008;
+ --amber4: #3f2700;
+ --amber5: #4d3000;
+ --amber6: #5c3d05;
+ --amber7: #714f19;
+ --amber8: #8f6424;
+ --amber9: #ffc53d;
+ --amber10: #ffd60a;
+ --amber11: #ffca16;
+ --amber12: #ffe7b3;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --amber1: color(display-p3 0.082 0.07 0.05);
+ --amber2: color(display-p3 0.111 0.094 0.064);
+ --amber3: color(display-p3 0.178 0.128 0.049);
+ --amber4: color(display-p3 0.239 0.156 0);
+ --amber5: color(display-p3 0.29 0.193 0);
+ --amber6: color(display-p3 0.344 0.245 0.076);
+ --amber7: color(display-p3 0.422 0.314 0.141);
+ --amber8: color(display-p3 0.535 0.399 0.189);
+ --amber9: color(display-p3 1 0.77 0.26);
+ --amber10: color(display-p3 1 0.87 0.15);
+ --amber11: color(display-p3 1 0.8 0.29);
+ --amber12: color(display-p3 0.984 0.909 0.726);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --amber1: #fefdfb;
+ --amber2: #fefbe9;
+ --amber3: #fff7c2;
+ --amber4: #ffee9c;
+ --amber5: #fbe577;
+ --amber6: #f3d673;
+ --amber7: #e9c162;
+ --amber8: #e2a336;
+ --amber9: #ffc53d;
+ --amber10: #ffba18;
+ --amber11: #ab6400;
+ --amber12: #4f3422;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --amber1: color(display-p3 0.995 0.992 0.985);
+ --amber2: color(display-p3 0.994 0.986 0.921);
+ --amber3: color(display-p3 0.994 0.969 0.782);
+ --amber4: color(display-p3 0.989 0.937 0.65);
+ --amber5: color(display-p3 0.97 0.902 0.527);
+ --amber6: color(display-p3 0.936 0.844 0.506);
+ --amber7: color(display-p3 0.89 0.762 0.443);
+ --amber8: color(display-p3 0.85 0.65 0.3);
+ --amber9: color(display-p3 1 0.77 0.26);
+ --amber10: color(display-p3 0.959 0.741 0.274);
+ --amber11: color(display-p3 0.64 0.4 0);
+ --amber12: color(display-p3 0.294 0.208 0.145);
+ }
+ }
+}
+
+:root {
+ --blackA1: rgba(0, 0, 0, 0.05);
+ --blackA2: rgba(0, 0, 0, 0.1);
+ --blackA3: rgba(0, 0, 0, 0.15);
+ --blackA4: rgba(0, 0, 0, 0.2);
+ --blackA5: rgba(0, 0, 0, 0.3);
+ --blackA6: rgba(0, 0, 0, 0.4);
+ --blackA7: rgba(0, 0, 0, 0.5);
+ --blackA8: rgba(0, 0, 0, 0.6);
+ --blackA9: rgba(0, 0, 0, 0.7);
+ --blackA10: rgba(0, 0, 0, 0.8);
+ --blackA11: rgba(0, 0, 0, 0.9);
+ --blackA12: rgba(0, 0, 0, 0.95);
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root {
+ --blackA1: color(display-p3 0 0 0 / 0.05);
+ --blackA2: color(display-p3 0 0 0 / 0.1);
+ --blackA3: color(display-p3 0 0 0 / 0.15);
+ --blackA4: color(display-p3 0 0 0 / 0.2);
+ --blackA5: color(display-p3 0 0 0 / 0.3);
+ --blackA6: color(display-p3 0 0 0 / 0.4);
+ --blackA7: color(display-p3 0 0 0 / 0.5);
+ --blackA8: color(display-p3 0 0 0 / 0.6);
+ --blackA9: color(display-p3 0 0 0 / 0.7);
+ --blackA10: color(display-p3 0 0 0 / 0.8);
+ --blackA11: color(display-p3 0 0 0 / 0.9);
+ --blackA12: color(display-p3 0 0 0 / 0.95);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --blueA1: #0080ff04;
+ --blueA2: #008cff0b;
+ --blueA3: #008ff519;
+ --blueA4: #009eff2a;
+ --blueA5: #0093ff3d;
+ --blueA6: #0088f653;
+ --blueA7: #0083eb71;
+ --blueA8: #0084e6a1;
+ --blueA9: #0090ff;
+ --blueA10: #0086f0fa;
+ --blueA11: #006dcbf2;
+ --blueA12: #002359ee;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --blueA1: color(display-p3 0.024 0.514 1 / 0.016);
+ --blueA2: color(display-p3 0.024 0.514 0.906 / 0.04);
+ --blueA3: color(display-p3 0.012 0.506 0.914 / 0.087);
+ --blueA4: color(display-p3 0.008 0.545 1 / 0.146);
+ --blueA5: color(display-p3 0.004 0.502 0.984 / 0.212);
+ --blueA6: color(display-p3 0.004 0.463 0.922 / 0.291);
+ --blueA7: color(display-p3 0.004 0.431 0.863 / 0.393);
+ --blueA8: color(display-p3 0 0.427 0.851 / 0.55);
+ --blueA9: color(display-p3 0 0.412 0.961 / 0.753);
+ --blueA10: color(display-p3 0 0.376 0.886 / 0.765);
+ --blueA11: color(display-p3 0.15 0.44 0.84);
+ --blueA12: color(display-p3 0.102 0.193 0.379);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --blueA1: #004df211;
+ --blueA2: #1166fb18;
+ --blueA3: #0077ff3a;
+ --blueA4: #0075ff57;
+ --blueA5: #0081fd6b;
+ --blueA6: #0f89fd7f;
+ --blueA7: #2a91fe98;
+ --blueA8: #3094feb9;
+ --blueA9: #0090ff;
+ --blueA10: #3b9eff;
+ --blueA11: #70b8ff;
+ --blueA12: #c2e6ff;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --blueA1: color(display-p3 0 0.333 1 / 0.059);
+ --blueA2: color(display-p3 0.114 0.435 0.988 / 0.085);
+ --blueA3: color(display-p3 0.122 0.463 1 / 0.219);
+ --blueA4: color(display-p3 0 0.467 1 / 0.324);
+ --blueA5: color(display-p3 0.098 0.51 1 / 0.4);
+ --blueA6: color(display-p3 0.224 0.557 1 / 0.475);
+ --blueA7: color(display-p3 0.294 0.584 1 / 0.572);
+ --blueA8: color(display-p3 0.314 0.592 1 / 0.702);
+ --blueA9: color(display-p3 0.251 0.573 0.996 / 0.967);
+ --blueA10: color(display-p3 0.357 0.631 1 / 0.971);
+ --blueA11: color(display-p3 0.49 0.72 1);
+ --blueA12: color(display-p3 0.788 0.898 0.99);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --blue1: #0d1520;
+ --blue2: #111927;
+ --blue3: #0d2847;
+ --blue4: #003362;
+ --blue5: #004074;
+ --blue6: #104d87;
+ --blue7: #205d9e;
+ --blue8: #2870bd;
+ --blue9: #0090ff;
+ --blue10: #3b9eff;
+ --blue11: #70b8ff;
+ --blue12: #c2e6ff;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --blue1: color(display-p3 0.057 0.081 0.122);
+ --blue2: color(display-p3 0.072 0.098 0.147);
+ --blue3: color(display-p3 0.078 0.154 0.27);
+ --blue4: color(display-p3 0.033 0.197 0.37);
+ --blue5: color(display-p3 0.08 0.245 0.441);
+ --blue6: color(display-p3 0.14 0.298 0.511);
+ --blue7: color(display-p3 0.195 0.361 0.6);
+ --blue8: color(display-p3 0.239 0.434 0.72);
+ --blue9: color(display-p3 0.247 0.556 0.969);
+ --blue10: color(display-p3 0.344 0.612 0.973);
+ --blue11: color(display-p3 0.49 0.72 1);
+ --blue12: color(display-p3 0.788 0.898 0.99);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --blue1: #fbfdff;
+ --blue2: #f4faff;
+ --blue3: #e6f4fe;
+ --blue4: #d5efff;
+ --blue5: #c2e5ff;
+ --blue6: #acd8fc;
+ --blue7: #8ec8f6;
+ --blue8: #5eb1ef;
+ --blue9: #0090ff;
+ --blue10: #0588f0;
+ --blue11: #0d74ce;
+ --blue12: #113264;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --blue1: color(display-p3 0.986 0.992 0.999);
+ --blue2: color(display-p3 0.96 0.979 0.998);
+ --blue3: color(display-p3 0.912 0.956 0.991);
+ --blue4: color(display-p3 0.853 0.932 1);
+ --blue5: color(display-p3 0.788 0.894 0.998);
+ --blue6: color(display-p3 0.709 0.843 0.976);
+ --blue7: color(display-p3 0.606 0.777 0.947);
+ --blue8: color(display-p3 0.451 0.688 0.917);
+ --blue9: color(display-p3 0.247 0.556 0.969);
+ --blue10: color(display-p3 0.234 0.523 0.912);
+ --blue11: color(display-p3 0.15 0.44 0.84);
+ --blue12: color(display-p3 0.102 0.193 0.379);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --bronzeA1: #55000003;
+ --bronzeA2: #cc33000a;
+ --bronzeA3: #92250015;
+ --bronzeA4: #80280020;
+ --bronzeA5: #7423002c;
+ --bronzeA6: #7324003a;
+ --bronzeA7: #6c1f004c;
+ --bronzeA8: #671c0066;
+ --bronzeA9: #551a008d;
+ --bronzeA10: #4c150097;
+ --bronzeA11: #3d0f00ab;
+ --bronzeA12: #1d0600d4;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --bronzeA1: color(display-p3 0.349 0.024 0.024 / 0.012);
+ --bronzeA2: color(display-p3 0.71 0.22 0.024 / 0.04);
+ --bronzeA3: color(display-p3 0.482 0.2 0.008 / 0.083);
+ --bronzeA4: color(display-p3 0.424 0.133 0.004 / 0.122);
+ --bronzeA5: color(display-p3 0.4 0.145 0.004 / 0.169);
+ --bronzeA6: color(display-p3 0.388 0.125 0.004 / 0.224);
+ --bronzeA7: color(display-p3 0.365 0.11 0.004 / 0.295);
+ --bronzeA8: color(display-p3 0.341 0.102 0.004 / 0.393);
+ --bronzeA9: color(display-p3 0.29 0.094 0 / 0.546);
+ --bronzeA10: color(display-p3 0.255 0.082 0 / 0.585);
+ --bronzeA11: color(display-p3 0.471 0.373 0.336);
+ --bronzeA12: color(display-p3 0.251 0.191 0.172);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --bronzeA1: #d1110004;
+ --bronzeA2: #fbbc910c;
+ --bronzeA3: #faceb817;
+ --bronzeA4: #facdb622;
+ --bronzeA5: #ffd2c12d;
+ --bronzeA6: #ffd1c03c;
+ --bronzeA7: #fdd0c04f;
+ --bronzeA8: #ffd6c565;
+ --bronzeA9: #fec7b09b;
+ --bronzeA10: #fecab5a9;
+ --bronzeA11: #ffd7c6d1;
+ --bronzeA12: #fff1e9ec;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --bronzeA1: color(display-p3 0.941 0.067 0 / 0.009);
+ --bronzeA2: color(display-p3 0.98 0.8 0.706 / 0.043);
+ --bronzeA3: color(display-p3 0.988 0.851 0.761 / 0.085);
+ --bronzeA4: color(display-p3 0.996 0.839 0.78 / 0.127);
+ --bronzeA5: color(display-p3 0.996 0.863 0.773 / 0.173);
+ --bronzeA6: color(display-p3 1 0.863 0.796 / 0.227);
+ --bronzeA7: color(display-p3 1 0.867 0.8 / 0.295);
+ --bronzeA8: color(display-p3 1 0.859 0.788 / 0.387);
+ --bronzeA9: color(display-p3 1 0.82 0.733 / 0.585);
+ --bronzeA10: color(display-p3 1 0.839 0.761 / 0.635);
+ --bronzeA11: color(display-p3 0.81 0.707 0.655);
+ --bronzeA12: color(display-p3 0.921 0.88 0.854);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --bronze1: #141110;
+ --bronze2: #1c1917;
+ --bronze3: #262220;
+ --bronze4: #302a27;
+ --bronze5: #3b3330;
+ --bronze6: #493e3a;
+ --bronze7: #5a4c47;
+ --bronze8: #6f5f58;
+ --bronze9: #a18072;
+ --bronze10: #ae8c7e;
+ --bronze11: #d4b3a5;
+ --bronze12: #ede0d9;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --bronze1: color(display-p3 0.076 0.067 0.063);
+ --bronze2: color(display-p3 0.106 0.097 0.093);
+ --bronze3: color(display-p3 0.147 0.132 0.125);
+ --bronze4: color(display-p3 0.185 0.166 0.156);
+ --bronze5: color(display-p3 0.227 0.202 0.19);
+ --bronze6: color(display-p3 0.278 0.246 0.23);
+ --bronze7: color(display-p3 0.343 0.302 0.281);
+ --bronze8: color(display-p3 0.426 0.374 0.347);
+ --bronze9: color(display-p3 0.611 0.507 0.455);
+ --bronze10: color(display-p3 0.66 0.556 0.504);
+ --bronze11: color(display-p3 0.81 0.707 0.655);
+ --bronze12: color(display-p3 0.921 0.88 0.854);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --bronze1: #fdfcfc;
+ --bronze2: #fdf7f5;
+ --bronze3: #f6edea;
+ --bronze4: #efe4df;
+ --bronze5: #e7d9d3;
+ --bronze6: #dfcdc5;
+ --bronze7: #d3bcb3;
+ --bronze8: #c2a499;
+ --bronze9: #a18072;
+ --bronze10: #957468;
+ --bronze11: #7d5e54;
+ --bronze12: #43302b;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --bronze1: color(display-p3 0.991 0.988 0.988);
+ --bronze2: color(display-p3 0.989 0.97 0.961);
+ --bronze3: color(display-p3 0.958 0.932 0.919);
+ --bronze4: color(display-p3 0.929 0.894 0.877);
+ --bronze5: color(display-p3 0.898 0.853 0.832);
+ --bronze6: color(display-p3 0.861 0.805 0.778);
+ --bronze7: color(display-p3 0.812 0.739 0.706);
+ --bronze8: color(display-p3 0.741 0.647 0.606);
+ --bronze9: color(display-p3 0.611 0.507 0.455);
+ --bronze10: color(display-p3 0.563 0.461 0.414);
+ --bronze11: color(display-p3 0.471 0.373 0.336);
+ --bronze12: color(display-p3 0.251 0.191 0.172);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --brownA1: #aa550003;
+ --brownA2: #aa550009;
+ --brownA3: #a04b0018;
+ --brownA4: #9b4a0026;
+ --brownA5: #9f4d0035;
+ --brownA6: #a04e0048;
+ --brownA7: #a34e0060;
+ --brownA8: #9f4a0081;
+ --brownA9: #823c00a7;
+ --brownA10: #723300ac;
+ --brownA11: #522100b9;
+ --brownA12: #140600d1;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --brownA1: color(display-p3 0.675 0.349 0.024 / 0.012);
+ --brownA2: color(display-p3 0.675 0.349 0.024 / 0.036);
+ --brownA3: color(display-p3 0.573 0.314 0.012 / 0.091);
+ --brownA4: color(display-p3 0.545 0.302 0.008 / 0.146);
+ --brownA5: color(display-p3 0.561 0.29 0.004 / 0.204);
+ --brownA6: color(display-p3 0.553 0.294 0.004 / 0.271);
+ --brownA7: color(display-p3 0.557 0.286 0.004 / 0.361);
+ --brownA8: color(display-p3 0.549 0.275 0.004 / 0.487);
+ --brownA9: color(display-p3 0.447 0.22 0 / 0.632);
+ --brownA10: color(display-p3 0.388 0.188 0 / 0.655);
+ --brownA11: color(display-p3 0.485 0.374 0.288);
+ --brownA12: color(display-p3 0.236 0.202 0.183);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --brownA1: #91110002;
+ --brownA2: #fba67c0c;
+ --brownA3: #fcb58c19;
+ --brownA4: #fbbb8a24;
+ --brownA5: #fcb88931;
+ --brownA6: #fdba8741;
+ --brownA7: #ffbb8856;
+ --brownA8: #ffbe8773;
+ --brownA9: #feb87da8;
+ --brownA10: #ffc18cb3;
+ --brownA11: #fed1aad9;
+ --brownA12: #feecd4f2;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --brownA1: color(display-p3 0.855 0.071 0 / 0.005);
+ --brownA2: color(display-p3 0.98 0.706 0.525 / 0.043);
+ --brownA3: color(display-p3 0.996 0.745 0.576 / 0.093);
+ --brownA4: color(display-p3 1 0.765 0.592 / 0.135);
+ --brownA5: color(display-p3 1 0.761 0.588 / 0.181);
+ --brownA6: color(display-p3 1 0.773 0.592 / 0.24);
+ --brownA7: color(display-p3 0.996 0.776 0.58 / 0.32);
+ --brownA8: color(display-p3 1 0.78 0.573 / 0.433);
+ --brownA9: color(display-p3 1 0.769 0.549 / 0.627);
+ --brownA10: color(display-p3 1 0.792 0.596 / 0.677);
+ --brownA11: color(display-p3 0.835 0.715 0.597);
+ --brownA12: color(display-p3 0.938 0.885 0.802);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --brown1: #12110f;
+ --brown2: #1c1816;
+ --brown3: #28211d;
+ --brown4: #322922;
+ --brown5: #3e3128;
+ --brown6: #4d3c2f;
+ --brown7: #614a39;
+ --brown8: #7c5f46;
+ --brown9: #ad7f58;
+ --brown10: #b88c67;
+ --brown11: #dbb594;
+ --brown12: #f2e1ca;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --brown1: color(display-p3 0.071 0.067 0.059);
+ --brown2: color(display-p3 0.107 0.095 0.087);
+ --brown3: color(display-p3 0.151 0.13 0.115);
+ --brown4: color(display-p3 0.191 0.161 0.138);
+ --brown5: color(display-p3 0.235 0.194 0.162);
+ --brown6: color(display-p3 0.291 0.237 0.192);
+ --brown7: color(display-p3 0.365 0.295 0.232);
+ --brown8: color(display-p3 0.469 0.377 0.287);
+ --brown9: color(display-p3 0.651 0.505 0.368);
+ --brown10: color(display-p3 0.697 0.557 0.423);
+ --brown11: color(display-p3 0.835 0.715 0.597);
+ --brown12: color(display-p3 0.938 0.885 0.802);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --brown1: #fefdfc;
+ --brown2: #fcf9f6;
+ --brown3: #f6eee7;
+ --brown4: #f0e4d9;
+ --brown5: #ebdaca;
+ --brown6: #e4cdb7;
+ --brown7: #dcbc9f;
+ --brown8: #cea37e;
+ --brown9: #ad7f58;
+ --brown10: #a07553;
+ --brown11: #815e46;
+ --brown12: #3e332e;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --brown1: color(display-p3 0.995 0.992 0.989);
+ --brown2: color(display-p3 0.987 0.976 0.964);
+ --brown3: color(display-p3 0.959 0.936 0.909);
+ --brown4: color(display-p3 0.934 0.897 0.855);
+ --brown5: color(display-p3 0.909 0.856 0.798);
+ --brown6: color(display-p3 0.88 0.808 0.73);
+ --brown7: color(display-p3 0.841 0.742 0.639);
+ --brown8: color(display-p3 0.782 0.647 0.514);
+ --brown9: color(display-p3 0.651 0.505 0.368);
+ --brown10: color(display-p3 0.601 0.465 0.344);
+ --brown11: color(display-p3 0.485 0.374 0.288);
+ --brown12: color(display-p3 0.236 0.202 0.183);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --crimsonA1: #ff005503;
+ --crimsonA2: #e0004008;
+ --crimsonA3: #ff005216;
+ --crimsonA4: #f8005123;
+ --crimsonA5: #e5004f31;
+ --crimsonA6: #d0004b41;
+ --crimsonA7: #bf004753;
+ --crimsonA8: #b6004a6c;
+ --crimsonA9: #e2005bc2;
+ --crimsonA10: #d70056cb;
+ --crimsonA11: #c4004fe2;
+ --crimsonA12: #530026e9;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --crimsonA1: color(display-p3 0.675 0.024 0.349 / 0.012);
+ --crimsonA2: color(display-p3 0.757 0.02 0.267 / 0.032);
+ --crimsonA3: color(display-p3 0.859 0.008 0.294 / 0.083);
+ --crimsonA4: color(display-p3 0.827 0.008 0.298 / 0.134);
+ --crimsonA5: color(display-p3 0.753 0.008 0.275 / 0.189);
+ --crimsonA6: color(display-p3 0.682 0.004 0.247 / 0.244);
+ --crimsonA7: color(display-p3 0.62 0.004 0.251 / 0.318);
+ --crimsonA8: color(display-p3 0.6 0.004 0.251 / 0.408);
+ --crimsonA9: color(display-p3 0.776 0 0.298 / 0.702);
+ --crimsonA10: color(display-p3 0.737 0 0.275 / 0.734);
+ --crimsonA11: color(display-p3 0.731 0.195 0.388);
+ --crimsonA12: color(display-p3 0.352 0.111 0.221);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --crimsonA1: #f4126709;
+ --crimsonA2: #f22f7a11;
+ --crimsonA3: #fe2a8b2a;
+ --crimsonA4: #fd158741;
+ --crimsonA5: #fd278f51;
+ --crimsonA6: #fe459763;
+ --crimsonA7: #fd559b7f;
+ --crimsonA8: #fe5b9bab;
+ --crimsonA9: #fe418de8;
+ --crimsonA10: #ff5693ed;
+ --crimsonA11: #ff92ad;
+ --crimsonA12: #ffd5eafd;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --crimsonA1: color(display-p3 0.984 0.071 0.463 / 0.03);
+ --crimsonA2: color(display-p3 0.996 0.282 0.569 / 0.055);
+ --crimsonA3: color(display-p3 0.996 0.227 0.573 / 0.148);
+ --crimsonA4: color(display-p3 1 0.157 0.569 / 0.227);
+ --crimsonA5: color(display-p3 1 0.231 0.604 / 0.286);
+ --crimsonA6: color(display-p3 1 0.337 0.643 / 0.349);
+ --crimsonA7: color(display-p3 1 0.416 0.663 / 0.454);
+ --crimsonA8: color(display-p3 0.996 0.427 0.651 / 0.614);
+ --crimsonA9: color(display-p3 1 0.345 0.596 / 0.832);
+ --crimsonA10: color(display-p3 1 0.42 0.62 / 0.853);
+ --crimsonA11: color(display-p3 1 0.56 0.66);
+ --crimsonA12: color(display-p3 0.966 0.834 0.906);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --crimson1: #191114;
+ --crimson2: #201318;
+ --crimson3: #381525;
+ --crimson4: #4d122f;
+ --crimson5: #5c1839;
+ --crimson6: #6d2545;
+ --crimson7: #873356;
+ --crimson8: #b0436e;
+ --crimson9: #e93d82;
+ --crimson10: #ee518a;
+ --crimson11: #ff92ad;
+ --crimson12: #fdd3e8;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --crimson1: color(display-p3 0.093 0.068 0.078);
+ --crimson2: color(display-p3 0.117 0.078 0.095);
+ --crimson3: color(display-p3 0.203 0.091 0.143);
+ --crimson4: color(display-p3 0.277 0.087 0.182);
+ --crimson5: color(display-p3 0.332 0.115 0.22);
+ --crimson6: color(display-p3 0.394 0.162 0.268);
+ --crimson7: color(display-p3 0.489 0.222 0.336);
+ --crimson8: color(display-p3 0.638 0.289 0.429);
+ --crimson9: color(display-p3 0.843 0.298 0.507);
+ --crimson10: color(display-p3 0.864 0.364 0.539);
+ --crimson11: color(display-p3 1 0.56 0.66);
+ --crimson12: color(display-p3 0.966 0.834 0.906);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --crimson1: #fffcfd;
+ --crimson2: #fef7f9;
+ --crimson3: #ffe9f0;
+ --crimson4: #fedce7;
+ --crimson5: #facedd;
+ --crimson6: #f3bed1;
+ --crimson7: #eaacc3;
+ --crimson8: #e093b2;
+ --crimson9: #e93d82;
+ --crimson10: #df3478;
+ --crimson11: #cb1d63;
+ --crimson12: #621639;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --crimson1: color(display-p3 0.998 0.989 0.992);
+ --crimson2: color(display-p3 0.991 0.969 0.976);
+ --crimson3: color(display-p3 0.987 0.917 0.941);
+ --crimson4: color(display-p3 0.975 0.866 0.904);
+ --crimson5: color(display-p3 0.953 0.813 0.864);
+ --crimson6: color(display-p3 0.921 0.755 0.817);
+ --crimson7: color(display-p3 0.88 0.683 0.761);
+ --crimson8: color(display-p3 0.834 0.592 0.694);
+ --crimson9: color(display-p3 0.843 0.298 0.507);
+ --crimson10: color(display-p3 0.807 0.266 0.468);
+ --crimson11: color(display-p3 0.731 0.195 0.388);
+ --crimson12: color(display-p3 0.352 0.111 0.221);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --cyanA1: #0099cc05;
+ --cyanA2: #009db10d;
+ --cyanA3: #00c2d121;
+ --cyanA4: #00bcd435;
+ --cyanA5: #01b4cc4a;
+ --cyanA6: #00a7c162;
+ --cyanA7: #009fbb82;
+ --cyanA8: #00a3c0c2;
+ --cyanA9: #00a2c7;
+ --cyanA10: #0094b7f8;
+ --cyanA11: #007491ef;
+ --cyanA12: #00323ef2;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --cyanA1: color(display-p3 0.02 0.608 0.804 / 0.02);
+ --cyanA2: color(display-p3 0.02 0.557 0.647 / 0.044);
+ --cyanA3: color(display-p3 0.004 0.694 0.796 / 0.114);
+ --cyanA4: color(display-p3 0.004 0.678 0.784 / 0.181);
+ --cyanA5: color(display-p3 0.004 0.624 0.733 / 0.248);
+ --cyanA6: color(display-p3 0.004 0.584 0.706 / 0.33);
+ --cyanA7: color(display-p3 0.004 0.541 0.667 / 0.436);
+ --cyanA8: color(display-p3 0 0.533 0.667 / 0.612);
+ --cyanA9: color(display-p3 0 0.482 0.675 / 0.718);
+ --cyanA10: color(display-p3 0 0.435 0.608 / 0.738);
+ --cyanA11: color(display-p3 0.08 0.48 0.63);
+ --cyanA12: color(display-p3 0.108 0.232 0.277);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --cyanA1: #0091f70a;
+ --cyanA2: #02a7f211;
+ --cyanA3: #00befd28;
+ --cyanA4: #00baff3b;
+ --cyanA5: #00befd4d;
+ --cyanA6: #00c7fd5e;
+ --cyanA7: #14cdff75;
+ --cyanA8: #11cfff95;
+ --cyanA9: #00cfffc3;
+ --cyanA10: #28d6ffcd;
+ --cyanA11: #52e1fee5;
+ --cyanA12: #bbf3fef7;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --cyanA1: color(display-p3 0 0.647 0.992 / 0.034);
+ --cyanA2: color(display-p3 0.133 0.733 1 / 0.059);
+ --cyanA3: color(display-p3 0.122 0.741 0.996 / 0.152);
+ --cyanA4: color(display-p3 0.051 0.725 1 / 0.227);
+ --cyanA5: color(display-p3 0.149 0.757 1 / 0.29);
+ --cyanA6: color(display-p3 0.267 0.792 1 / 0.358);
+ --cyanA7: color(display-p3 0.333 0.808 1 / 0.446);
+ --cyanA8: color(display-p3 0.357 0.816 1 / 0.572);
+ --cyanA9: color(display-p3 0.357 0.82 1 / 0.748);
+ --cyanA10: color(display-p3 0.4 0.839 1 / 0.786);
+ --cyanA11: color(display-p3 0.446 0.79 0.887);
+ --cyanA12: color(display-p3 0.757 0.919 0.962);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --cyan1: #0b161a;
+ --cyan2: #101b20;
+ --cyan3: #082c36;
+ --cyan4: #003848;
+ --cyan5: #004558;
+ --cyan6: #045468;
+ --cyan7: #12677e;
+ --cyan8: #11809c;
+ --cyan9: #00a2c7;
+ --cyan10: #23afd0;
+ --cyan11: #4ccce6;
+ --cyan12: #b6ecf7;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --cyan1: color(display-p3 0.053 0.085 0.098);
+ --cyan2: color(display-p3 0.072 0.105 0.122);
+ --cyan3: color(display-p3 0.073 0.168 0.209);
+ --cyan4: color(display-p3 0.063 0.216 0.277);
+ --cyan5: color(display-p3 0.091 0.267 0.336);
+ --cyan6: color(display-p3 0.137 0.324 0.4);
+ --cyan7: color(display-p3 0.186 0.398 0.484);
+ --cyan8: color(display-p3 0.23 0.496 0.6);
+ --cyan9: color(display-p3 0.282 0.627 0.765);
+ --cyan10: color(display-p3 0.331 0.675 0.801);
+ --cyan11: color(display-p3 0.446 0.79 0.887);
+ --cyan12: color(display-p3 0.757 0.919 0.962);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --cyan1: #fafdfe;
+ --cyan2: #f2fafb;
+ --cyan3: #def7f9;
+ --cyan4: #caf1f6;
+ --cyan5: #b5e9f0;
+ --cyan6: #9ddde7;
+ --cyan7: #7dcedc;
+ --cyan8: #3db9cf;
+ --cyan9: #00a2c7;
+ --cyan10: #0797b9;
+ --cyan11: #107d98;
+ --cyan12: #0d3c48;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --cyan1: color(display-p3 0.982 0.992 0.996);
+ --cyan2: color(display-p3 0.955 0.981 0.984);
+ --cyan3: color(display-p3 0.888 0.965 0.975);
+ --cyan4: color(display-p3 0.821 0.941 0.959);
+ --cyan5: color(display-p3 0.751 0.907 0.935);
+ --cyan6: color(display-p3 0.671 0.862 0.9);
+ --cyan7: color(display-p3 0.564 0.8 0.854);
+ --cyan8: color(display-p3 0.388 0.715 0.798);
+ --cyan9: color(display-p3 0.282 0.627 0.765);
+ --cyan10: color(display-p3 0.264 0.583 0.71);
+ --cyan11: color(display-p3 0.08 0.48 0.63);
+ --cyan12: color(display-p3 0.108 0.232 0.277);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --goldA1: #55550003;
+ --goldA2: #9d8a000d;
+ --goldA3: #75600018;
+ --goldA4: #6b4e0024;
+ --goldA5: #60460030;
+ --goldA6: #64440040;
+ --goldA7: #63420055;
+ --goldA8: #633d0072;
+ --goldA9: #5332009a;
+ --goldA10: #492d00a1;
+ --goldA11: #362100b4;
+ --goldA12: #130c00d4;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --goldA1: color(display-p3 0.349 0.349 0.024 / 0.012);
+ --goldA2: color(display-p3 0.592 0.514 0.024 / 0.048);
+ --goldA3: color(display-p3 0.4 0.357 0.012 / 0.091);
+ --goldA4: color(display-p3 0.357 0.298 0.008 / 0.134);
+ --goldA5: color(display-p3 0.345 0.282 0.004 / 0.185);
+ --goldA6: color(display-p3 0.341 0.263 0.004 / 0.244);
+ --goldA7: color(display-p3 0.345 0.235 0.004 / 0.322);
+ --goldA8: color(display-p3 0.345 0.22 0.004 / 0.436);
+ --goldA9: color(display-p3 0.286 0.18 0 / 0.589);
+ --goldA10: color(display-p3 0.255 0.161 0 / 0.62);
+ --goldA11: color(display-p3 0.433 0.386 0.305);
+ --goldA12: color(display-p3 0.227 0.209 0.173);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --goldA1: #91911102;
+ --goldA2: #f9e29d0b;
+ --goldA3: #f8ecbb15;
+ --goldA4: #ffeec41e;
+ --goldA5: #feecc22a;
+ --goldA6: #feebcb37;
+ --goldA7: #ffedcd48;
+ --goldA8: #fdeaca5f;
+ --goldA9: #ffdba690;
+ --goldA10: #fedfb09d;
+ --goldA11: #fee7c6c8;
+ --goldA12: #fef7ede7;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --goldA1: color(display-p3 0.855 0.855 0.071 / 0.005);
+ --goldA2: color(display-p3 0.98 0.89 0.616 / 0.043);
+ --goldA3: color(display-p3 1 0.949 0.753 / 0.08);
+ --goldA4: color(display-p3 1 0.933 0.8 / 0.118);
+ --goldA5: color(display-p3 1 0.949 0.804 / 0.16);
+ --goldA6: color(display-p3 1 0.925 0.8 / 0.215);
+ --goldA7: color(display-p3 1 0.945 0.831 / 0.278);
+ --goldA8: color(display-p3 1 0.937 0.82 / 0.366);
+ --goldA9: color(display-p3 0.996 0.882 0.69 / 0.551);
+ --goldA10: color(display-p3 1 0.894 0.725 / 0.601);
+ --goldA11: color(display-p3 0.784 0.728 0.635);
+ --goldA12: color(display-p3 0.906 0.887 0.855);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --gold1: #121211;
+ --gold2: #1b1a17;
+ --gold3: #24231f;
+ --gold4: #2d2b26;
+ --gold5: #38352e;
+ --gold6: #444039;
+ --gold7: #544f46;
+ --gold8: #696256;
+ --gold9: #978365;
+ --gold10: #a39073;
+ --gold11: #cbb99f;
+ --gold12: #e8e2d9;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --gold1: color(display-p3 0.071 0.071 0.067);
+ --gold2: color(display-p3 0.104 0.101 0.09);
+ --gold3: color(display-p3 0.141 0.136 0.122);
+ --gold4: color(display-p3 0.177 0.17 0.152);
+ --gold5: color(display-p3 0.217 0.207 0.185);
+ --gold6: color(display-p3 0.265 0.252 0.225);
+ --gold7: color(display-p3 0.327 0.31 0.277);
+ --gold8: color(display-p3 0.407 0.384 0.342);
+ --gold9: color(display-p3 0.579 0.517 0.41);
+ --gold10: color(display-p3 0.628 0.566 0.463);
+ --gold11: color(display-p3 0.784 0.728 0.635);
+ --gold12: color(display-p3 0.906 0.887 0.855);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --gold1: #fdfdfc;
+ --gold2: #faf9f2;
+ --gold3: #f2f0e7;
+ --gold4: #eae6db;
+ --gold5: #e1dccf;
+ --gold6: #d8d0bf;
+ --gold7: #cbc0aa;
+ --gold8: #b9a88d;
+ --gold9: #978365;
+ --gold10: #8c7a5e;
+ --gold11: #71624b;
+ --gold12: #3b352b;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --gold1: color(display-p3 0.992 0.992 0.989);
+ --gold2: color(display-p3 0.98 0.976 0.953);
+ --gold3: color(display-p3 0.947 0.94 0.909);
+ --gold4: color(display-p3 0.914 0.904 0.865);
+ --gold5: color(display-p3 0.88 0.865 0.816);
+ --gold6: color(display-p3 0.84 0.818 0.756);
+ --gold7: color(display-p3 0.788 0.753 0.677);
+ --gold8: color(display-p3 0.715 0.66 0.565);
+ --gold9: color(display-p3 0.579 0.517 0.41);
+ --gold10: color(display-p3 0.538 0.479 0.38);
+ --gold11: color(display-p3 0.433 0.386 0.305);
+ --gold12: color(display-p3 0.227 0.209 0.173);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --grassA1: #00c00004;
+ --grassA2: #0099000a;
+ --grassA3: #00970016;
+ --grassA4: #009f0725;
+ --grassA5: #00930536;
+ --grassA6: #008f0a4d;
+ --grassA7: #018b0f6b;
+ --grassA8: #008d199a;
+ --grassA9: #008619b9;
+ --grassA10: #007b17c1;
+ --grassA11: #006514d5;
+ --grassA12: #002006df;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --grassA1: color(display-p3 0.024 0.757 0.024 / 0.016);
+ --grassA2: color(display-p3 0.024 0.565 0.024 / 0.036);
+ --grassA3: color(display-p3 0.059 0.576 0.008 / 0.083);
+ --grassA4: color(display-p3 0.035 0.565 0.008 / 0.134);
+ --grassA5: color(display-p3 0.047 0.545 0.008 / 0.197);
+ --grassA6: color(display-p3 0.031 0.502 0.004 / 0.275);
+ --grassA7: color(display-p3 0.012 0.482 0.004 / 0.377);
+ --grassA8: color(display-p3 0 0.467 0.008 / 0.522);
+ --grassA9: color(display-p3 0.008 0.435 0 / 0.624);
+ --grassA10: color(display-p3 0.008 0.388 0 / 0.659);
+ --grassA11: color(display-p3 0.263 0.488 0.261);
+ --grassA12: color(display-p3 0.151 0.233 0.153);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --grassA1: #00de1205;
+ --grassA2: #5ef7780a;
+ --grassA3: #70fe8c1b;
+ --grassA4: #57ff802c;
+ --grassA5: #68ff8b3b;
+ --grassA6: #71ff8f4b;
+ --grassA7: #77fd925d;
+ --grassA8: #77fd9070;
+ --grassA9: #65ff82a1;
+ --grassA10: #72ff8dae;
+ --grassA11: #89ff9fcd;
+ --grassA12: #ceffceef;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --grassA1: color(display-p3 0 0.992 0.071 / 0.017);
+ --grassA2: color(display-p3 0.482 0.996 0.584 / 0.038);
+ --grassA3: color(display-p3 0.549 0.992 0.588 / 0.106);
+ --grassA4: color(display-p3 0.51 0.996 0.557 / 0.169);
+ --grassA5: color(display-p3 0.553 1 0.588 / 0.227);
+ --grassA6: color(display-p3 0.584 1 0.608 / 0.29);
+ --grassA7: color(display-p3 0.604 1 0.616 / 0.358);
+ --grassA8: color(display-p3 0.608 1 0.62 / 0.433);
+ --grassA9: color(display-p3 0.573 1 0.569 / 0.622);
+ --grassA10: color(display-p3 0.6 0.996 0.6 / 0.673);
+ --grassA11: color(display-p3 0.535 0.807 0.542);
+ --grassA12: color(display-p3 0.797 0.936 0.776);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --grass1: #0e1511;
+ --grass2: #141a15;
+ --grass3: #1b2a1e;
+ --grass4: #1d3a24;
+ --grass5: #25482d;
+ --grass6: #2d5736;
+ --grass7: #366740;
+ --grass8: #3e7949;
+ --grass9: #46a758;
+ --grass10: #53b365;
+ --grass11: #71d083;
+ --grass12: #c2f0c2;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --grass1: color(display-p3 0.062 0.083 0.067);
+ --grass2: color(display-p3 0.083 0.103 0.085);
+ --grass3: color(display-p3 0.118 0.163 0.122);
+ --grass4: color(display-p3 0.142 0.225 0.15);
+ --grass5: color(display-p3 0.178 0.279 0.186);
+ --grass6: color(display-p3 0.217 0.337 0.224);
+ --grass7: color(display-p3 0.258 0.4 0.264);
+ --grass8: color(display-p3 0.302 0.47 0.305);
+ --grass9: color(display-p3 0.38 0.647 0.378);
+ --grass10: color(display-p3 0.426 0.694 0.426);
+ --grass11: color(display-p3 0.535 0.807 0.542);
+ --grass12: color(display-p3 0.797 0.936 0.776);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --grass1: #fbfefb;
+ --grass2: #f5fbf5;
+ --grass3: #e9f6e9;
+ --grass4: #daf1db;
+ --grass5: #c9e8ca;
+ --grass6: #b2ddb5;
+ --grass7: #94ce9a;
+ --grass8: #65ba74;
+ --grass9: #46a758;
+ --grass10: #3e9b4f;
+ --grass11: #2a7e3b;
+ --grass12: #203c25;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --grass1: color(display-p3 0.986 0.996 0.985);
+ --grass2: color(display-p3 0.966 0.983 0.964);
+ --grass3: color(display-p3 0.923 0.965 0.917);
+ --grass4: color(display-p3 0.872 0.94 0.865);
+ --grass5: color(display-p3 0.811 0.908 0.802);
+ --grass6: color(display-p3 0.733 0.864 0.724);
+ --grass7: color(display-p3 0.628 0.803 0.622);
+ --grass8: color(display-p3 0.477 0.72 0.482);
+ --grass9: color(display-p3 0.38 0.647 0.378);
+ --grass10: color(display-p3 0.344 0.598 0.342);
+ --grass11: color(display-p3 0.263 0.488 0.261);
+ --grass12: color(display-p3 0.151 0.233 0.153);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --grayA1: #00000003;
+ --grayA2: #00000006;
+ --grayA3: #0000000f;
+ --grayA4: #00000017;
+ --grayA5: #0000001f;
+ --grayA6: #00000026;
+ --grayA7: #00000031;
+ --grayA8: #00000044;
+ --grayA9: #00000072;
+ --grayA10: #0000007c;
+ --grayA11: #0000009b;
+ --grayA12: #000000df;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --grayA1: color(display-p3 0 0 0 / 0.012);
+ --grayA2: color(display-p3 0 0 0 / 0.024);
+ --grayA3: color(display-p3 0 0 0 / 0.063);
+ --grayA4: color(display-p3 0 0 0 / 0.09);
+ --grayA5: color(display-p3 0 0 0 / 0.122);
+ --grayA6: color(display-p3 0 0 0 / 0.153);
+ --grayA7: color(display-p3 0 0 0 / 0.192);
+ --grayA8: color(display-p3 0 0 0 / 0.267);
+ --grayA9: color(display-p3 0 0 0 / 0.447);
+ --grayA10: color(display-p3 0 0 0 / 0.486);
+ --grayA11: color(display-p3 0 0 0 / 0.608);
+ --grayA12: color(display-p3 0 0 0 / 0.875);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --grayA1: #00000000;
+ --grayA2: #ffffff09;
+ --grayA3: #ffffff12;
+ --grayA4: #ffffff1b;
+ --grayA5: #ffffff22;
+ --grayA6: #ffffff2c;
+ --grayA7: #ffffff3b;
+ --grayA8: #ffffff55;
+ --grayA9: #ffffff64;
+ --grayA10: #ffffff72;
+ --grayA11: #ffffffaf;
+ --grayA12: #ffffffed;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --grayA1: color(display-p3 0 0 0 / 0);
+ --grayA2: color(display-p3 1 1 1 / 0.034);
+ --grayA3: color(display-p3 1 1 1 / 0.071);
+ --grayA4: color(display-p3 1 1 1 / 0.105);
+ --grayA5: color(display-p3 1 1 1 / 0.134);
+ --grayA6: color(display-p3 1 1 1 / 0.172);
+ --grayA7: color(display-p3 1 1 1 / 0.231);
+ --grayA8: color(display-p3 1 1 1 / 0.332);
+ --grayA9: color(display-p3 1 1 1 / 0.391);
+ --grayA10: color(display-p3 1 1 1 / 0.445);
+ --grayA11: color(display-p3 1 1 1 / 0.685);
+ --grayA12: color(display-p3 1 1 1 / 0.929);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --gray1: #111111;
+ --gray2: #191919;
+ --gray3: #222222;
+ --gray4: #2a2a2a;
+ --gray5: #313131;
+ --gray6: #3a3a3a;
+ --gray7: #484848;
+ --gray8: #606060;
+ --gray9: #6e6e6e;
+ --gray10: #7b7b7b;
+ --gray11: #b4b4b4;
+ --gray12: #eeeeee;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --gray1: color(display-p3 0.067 0.067 0.067);
+ --gray2: color(display-p3 0.098 0.098 0.098);
+ --gray3: color(display-p3 0.135 0.135 0.135);
+ --gray4: color(display-p3 0.163 0.163 0.163);
+ --gray5: color(display-p3 0.192 0.192 0.192);
+ --gray6: color(display-p3 0.228 0.228 0.228);
+ --gray7: color(display-p3 0.283 0.283 0.283);
+ --gray8: color(display-p3 0.375 0.375 0.375);
+ --gray9: color(display-p3 0.431 0.431 0.431);
+ --gray10: color(display-p3 0.484 0.484 0.484);
+ --gray11: color(display-p3 0.706 0.706 0.706);
+ --gray12: color(display-p3 0.933 0.933 0.933);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --gray1: #fcfcfc;
+ --gray2: #f9f9f9;
+ --gray3: #f0f0f0;
+ --gray4: #e8e8e8;
+ --gray5: #e0e0e0;
+ --gray6: #d9d9d9;
+ --gray7: #cecece;
+ --gray8: #bbbbbb;
+ --gray9: #8d8d8d;
+ --gray10: #838383;
+ --gray11: #646464;
+ --gray12: #202020;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --gray1: color(display-p3 0.988 0.988 0.988);
+ --gray2: color(display-p3 0.975 0.975 0.975);
+ --gray3: color(display-p3 0.939 0.939 0.939);
+ --gray4: color(display-p3 0.908 0.908 0.908);
+ --gray5: color(display-p3 0.88 0.88 0.88);
+ --gray6: color(display-p3 0.849 0.849 0.849);
+ --gray7: color(display-p3 0.807 0.807 0.807);
+ --gray8: color(display-p3 0.732 0.732 0.732);
+ --gray9: color(display-p3 0.553 0.553 0.553);
+ --gray10: color(display-p3 0.512 0.512 0.512);
+ --gray11: color(display-p3 0.392 0.392 0.392);
+ --gray12: color(display-p3 0.125 0.125 0.125);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --greenA1: #00c04004;
+ --greenA2: #00a32f0b;
+ --greenA3: #00a43319;
+ --greenA4: #00a83829;
+ --greenA5: #019c393b;
+ --greenA6: #00963c52;
+ --greenA7: #00914071;
+ --greenA8: #00924ba4;
+ --greenA9: #008f4acf;
+ --greenA10: #008647d4;
+ --greenA11: #00713fde;
+ --greenA12: #002616e6;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --greenA1: color(display-p3 0.024 0.757 0.267 / 0.016);
+ --greenA2: color(display-p3 0.024 0.565 0.129 / 0.036);
+ --greenA3: color(display-p3 0.012 0.596 0.145 / 0.087);
+ --greenA4: color(display-p3 0.008 0.588 0.145 / 0.142);
+ --greenA5: color(display-p3 0.004 0.541 0.157 / 0.204);
+ --greenA6: color(display-p3 0.004 0.518 0.157 / 0.283);
+ --greenA7: color(display-p3 0.004 0.486 0.165 / 0.389);
+ --greenA8: color(display-p3 0 0.478 0.2 / 0.55);
+ --greenA9: color(display-p3 0 0.455 0.165 / 0.667);
+ --greenA10: color(display-p3 0 0.416 0.153 / 0.691);
+ --greenA11: color(display-p3 0.19 0.5 0.32);
+ --greenA12: color(display-p3 0.132 0.228 0.18);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --greenA1: #00de4505;
+ --greenA2: #29f99d0b;
+ --greenA3: #22ff991e;
+ --greenA4: #11ff992d;
+ --greenA5: #2bffa23c;
+ --greenA6: #44ffaa4b;
+ --greenA7: #50fdac5e;
+ --greenA8: #54ffad73;
+ --greenA9: #44ffa49e;
+ --greenA10: #43fea4ab;
+ --greenA11: #46fea5d4;
+ --greenA12: #bbffd7f0;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --greenA1: color(display-p3 0 0.992 0.298 / 0.017);
+ --greenA2: color(display-p3 0.341 0.98 0.616 / 0.043);
+ --greenA3: color(display-p3 0.376 0.996 0.655 / 0.114);
+ --greenA4: color(display-p3 0.341 0.996 0.635 / 0.173);
+ --greenA5: color(display-p3 0.408 1 0.678 / 0.232);
+ --greenA6: color(display-p3 0.475 1 0.706 / 0.29);
+ --greenA7: color(display-p3 0.514 1 0.706 / 0.362);
+ --greenA8: color(display-p3 0.529 1 0.718 / 0.442);
+ --greenA9: color(display-p3 0.502 0.996 0.682 / 0.61);
+ --greenA10: color(display-p3 0.506 1 0.682 / 0.66);
+ --greenA11: color(display-p3 0.434 0.828 0.573);
+ --greenA12: color(display-p3 0.747 0.938 0.807);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --green1: #0e1512;
+ --green2: #121b17;
+ --green3: #132d21;
+ --green4: #113b29;
+ --green5: #174933;
+ --green6: #20573e;
+ --green7: #28684a;
+ --green8: #2f7c57;
+ --green9: #30a46c;
+ --green10: #33b074;
+ --green11: #3dd68c;
+ --green12: #b1f1cb;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --green1: color(display-p3 0.062 0.083 0.071);
+ --green2: color(display-p3 0.079 0.106 0.09);
+ --green3: color(display-p3 0.1 0.173 0.133);
+ --green4: color(display-p3 0.115 0.229 0.166);
+ --green5: color(display-p3 0.147 0.282 0.206);
+ --green6: color(display-p3 0.185 0.338 0.25);
+ --green7: color(display-p3 0.227 0.403 0.298);
+ --green8: color(display-p3 0.27 0.479 0.351);
+ --green9: color(display-p3 0.332 0.634 0.442);
+ --green10: color(display-p3 0.357 0.682 0.474);
+ --green11: color(display-p3 0.434 0.828 0.573);
+ --green12: color(display-p3 0.747 0.938 0.807);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --green1: #fbfefc;
+ --green2: #f4fbf6;
+ --green3: #e6f6eb;
+ --green4: #d6f1df;
+ --green5: #c4e8d1;
+ --green6: #adddc0;
+ --green7: #8eceaa;
+ --green8: #5bb98b;
+ --green9: #30a46c;
+ --green10: #2b9a66;
+ --green11: #218358;
+ --green12: #193b2d;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --green1: color(display-p3 0.986 0.996 0.989);
+ --green2: color(display-p3 0.963 0.983 0.967);
+ --green3: color(display-p3 0.913 0.964 0.925);
+ --green4: color(display-p3 0.859 0.94 0.879);
+ --green5: color(display-p3 0.796 0.907 0.826);
+ --green6: color(display-p3 0.718 0.863 0.761);
+ --green7: color(display-p3 0.61 0.801 0.675);
+ --green8: color(display-p3 0.451 0.715 0.559);
+ --green9: color(display-p3 0.332 0.634 0.442);
+ --green10: color(display-p3 0.308 0.595 0.417);
+ --green11: color(display-p3 0.19 0.5 0.32);
+ --green12: color(display-p3 0.132 0.228 0.18);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --indigoA1: #00008002;
+ --indigoA2: #0040ff08;
+ --indigoA3: #0047f112;
+ --indigoA4: #0044ff1e;
+ --indigoA5: #0044ff2d;
+ --indigoA6: #003eff3e;
+ --indigoA7: #0037ed54;
+ --indigoA8: #0034dc72;
+ --indigoA9: #0031d2c1;
+ --indigoA10: #002ec9cc;
+ --indigoA11: #002bb7c5;
+ --indigoA12: #001046e0;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --indigoA1: color(display-p3 0.02 0.02 0.51 / 0.008);
+ --indigoA2: color(display-p3 0.024 0.161 0.863 / 0.028);
+ --indigoA3: color(display-p3 0.008 0.239 0.886 / 0.067);
+ --indigoA4: color(display-p3 0.004 0.247 1 / 0.114);
+ --indigoA5: color(display-p3 0.004 0.235 1 / 0.169);
+ --indigoA6: color(display-p3 0.004 0.208 0.984 / 0.232);
+ --indigoA7: color(display-p3 0.004 0.176 0.863 / 0.314);
+ --indigoA8: color(display-p3 0.004 0.165 0.812 / 0.432);
+ --indigoA9: color(display-p3 0 0.153 0.773 / 0.726);
+ --indigoA10: color(display-p3 0 0.137 0.737 / 0.765);
+ --indigoA11: color(display-p3 0.256 0.354 0.755);
+ --indigoA12: color(display-p3 0.133 0.175 0.348);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --indigoA1: #1133ff0f;
+ --indigoA2: #3354fa17;
+ --indigoA3: #2f62ff3c;
+ --indigoA4: #3566ff57;
+ --indigoA5: #4171fd6b;
+ --indigoA6: #5178fd7c;
+ --indigoA7: #5a7fff90;
+ --indigoA8: #5b81feac;
+ --indigoA9: #4671ffdb;
+ --indigoA10: #5c7efee3;
+ --indigoA11: #9eb1ff;
+ --indigoA12: #d6e1ff;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --indigoA1: color(display-p3 0.071 0.212 0.996 / 0.055);
+ --indigoA2: color(display-p3 0.251 0.345 0.988 / 0.085);
+ --indigoA3: color(display-p3 0.243 0.404 1 / 0.223);
+ --indigoA4: color(display-p3 0.263 0.42 1 / 0.324);
+ --indigoA5: color(display-p3 0.314 0.451 1 / 0.4);
+ --indigoA6: color(display-p3 0.361 0.49 1 / 0.467);
+ --indigoA7: color(display-p3 0.388 0.51 1 / 0.547);
+ --indigoA8: color(display-p3 0.404 0.518 1 / 0.652);
+ --indigoA9: color(display-p3 0.318 0.451 1 / 0.824);
+ --indigoA10: color(display-p3 0.404 0.506 1 / 0.858);
+ --indigoA11: color(display-p3 0.63 0.69 1);
+ --indigoA12: color(display-p3 0.848 0.881 0.99);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --indigo1: #11131f;
+ --indigo2: #141726;
+ --indigo3: #182449;
+ --indigo4: #1d2e62;
+ --indigo5: #253974;
+ --indigo6: #304384;
+ --indigo7: #3a4f97;
+ --indigo8: #435db1;
+ --indigo9: #3e63dd;
+ --indigo10: #5472e4;
+ --indigo11: #9eb1ff;
+ --indigo12: #d6e1ff;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --indigo1: color(display-p3 0.068 0.074 0.118);
+ --indigo2: color(display-p3 0.081 0.089 0.144);
+ --indigo3: color(display-p3 0.105 0.141 0.275);
+ --indigo4: color(display-p3 0.129 0.18 0.369);
+ --indigo5: color(display-p3 0.163 0.22 0.439);
+ --indigo6: color(display-p3 0.203 0.262 0.5);
+ --indigo7: color(display-p3 0.245 0.309 0.575);
+ --indigo8: color(display-p3 0.285 0.362 0.674);
+ --indigo9: color(display-p3 0.276 0.384 0.837);
+ --indigo10: color(display-p3 0.354 0.445 0.866);
+ --indigo11: color(display-p3 0.63 0.69 1);
+ --indigo12: color(display-p3 0.848 0.881 0.99);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --indigo1: #fdfdfe;
+ --indigo2: #f7f9ff;
+ --indigo3: #edf2fe;
+ --indigo4: #e1e9ff;
+ --indigo5: #d2deff;
+ --indigo6: #c1d0ff;
+ --indigo7: #abbdf9;
+ --indigo8: #8da4ef;
+ --indigo9: #3e63dd;
+ --indigo10: #3358d4;
+ --indigo11: #3a5bc7;
+ --indigo12: #1f2d5c;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --indigo1: color(display-p3 0.992 0.992 0.996);
+ --indigo2: color(display-p3 0.971 0.977 0.998);
+ --indigo3: color(display-p3 0.933 0.948 0.992);
+ --indigo4: color(display-p3 0.885 0.914 1);
+ --indigo5: color(display-p3 0.831 0.87 1);
+ --indigo6: color(display-p3 0.767 0.814 0.995);
+ --indigo7: color(display-p3 0.685 0.74 0.957);
+ --indigo8: color(display-p3 0.569 0.639 0.916);
+ --indigo9: color(display-p3 0.276 0.384 0.837);
+ --indigo10: color(display-p3 0.234 0.343 0.801);
+ --indigo11: color(display-p3 0.256 0.354 0.755);
+ --indigo12: color(display-p3 0.133 0.175 0.348);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --irisA1: #0000ff02;
+ --irisA2: #0000ff07;
+ --irisA3: #0011ee0f;
+ --irisA4: #000bff19;
+ --irisA5: #000eff25;
+ --irisA6: #000aff34;
+ --irisA7: #0008e647;
+ --irisA8: #0008d964;
+ --irisA9: #0000c0a4;
+ --irisA10: #0000b6ae;
+ --irisA11: #0600abac;
+ --irisA12: #000246d8;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --irisA1: color(display-p3 0.02 0.02 1 / 0.008);
+ --irisA2: color(display-p3 0.024 0.024 0.863 / 0.028);
+ --irisA3: color(display-p3 0.004 0.071 0.871 / 0.059);
+ --irisA4: color(display-p3 0.012 0.051 1 / 0.099);
+ --irisA5: color(display-p3 0.008 0.035 1 / 0.142);
+ --irisA6: color(display-p3 0 0.02 0.941 / 0.2);
+ --irisA7: color(display-p3 0.004 0.02 0.847 / 0.279);
+ --irisA8: color(display-p3 0.004 0.024 0.788 / 0.389);
+ --irisA9: color(display-p3 0 0 0.706 / 0.644);
+ --irisA10: color(display-p3 0 0 0.667 / 0.683);
+ --irisA11: color(display-p3 0.337 0.326 0.748);
+ --irisA12: color(display-p3 0.154 0.161 0.371);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --irisA1: #3636fe0e;
+ --irisA2: #564bf916;
+ --irisA3: #525bff3b;
+ --irisA4: #4d58ff5a;
+ --irisA5: #5b62fd6b;
+ --irisA6: #6d6ffd7a;
+ --irisA7: #7777fe8e;
+ --irisA8: #7b7afeac;
+ --irisA9: #6a6afed4;
+ --irisA10: #7d79ffdc;
+ --irisA11: #b1a9ff;
+ --irisA12: #e1e0fffe;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --irisA1: color(display-p3 0.224 0.224 0.992 / 0.051);
+ --irisA2: color(display-p3 0.361 0.314 1 / 0.08);
+ --irisA3: color(display-p3 0.357 0.373 1 / 0.219);
+ --irisA4: color(display-p3 0.325 0.361 1 / 0.337);
+ --irisA5: color(display-p3 0.38 0.4 1 / 0.4);
+ --irisA6: color(display-p3 0.447 0.447 1 / 0.454);
+ --irisA7: color(display-p3 0.486 0.486 1 / 0.534);
+ --irisA8: color(display-p3 0.502 0.494 1 / 0.652);
+ --irisA9: color(display-p3 0.431 0.431 1 / 0.799);
+ --irisA10: color(display-p3 0.502 0.486 1 / 0.832);
+ --irisA11: color(display-p3 0.685 0.662 1);
+ --irisA12: color(display-p3 0.878 0.875 0.986);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --iris1: #13131e;
+ --iris2: #171625;
+ --iris3: #202248;
+ --iris4: #262a65;
+ --iris5: #303374;
+ --iris6: #3d3e82;
+ --iris7: #4a4a95;
+ --iris8: #5958b1;
+ --iris9: #5b5bd6;
+ --iris10: #6e6ade;
+ --iris11: #b1a9ff;
+ --iris12: #e0dffe;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --iris1: color(display-p3 0.075 0.075 0.114);
+ --iris2: color(display-p3 0.089 0.086 0.14);
+ --iris3: color(display-p3 0.128 0.134 0.272);
+ --iris4: color(display-p3 0.153 0.165 0.382);
+ --iris5: color(display-p3 0.192 0.201 0.44);
+ --iris6: color(display-p3 0.239 0.241 0.491);
+ --iris7: color(display-p3 0.291 0.289 0.565);
+ --iris8: color(display-p3 0.35 0.345 0.673);
+ --iris9: color(display-p3 0.357 0.357 0.81);
+ --iris10: color(display-p3 0.428 0.416 0.843);
+ --iris11: color(display-p3 0.685 0.662 1);
+ --iris12: color(display-p3 0.878 0.875 0.986);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --iris1: #fdfdff;
+ --iris2: #f8f8ff;
+ --iris3: #f0f1fe;
+ --iris4: #e6e7ff;
+ --iris5: #dadcff;
+ --iris6: #cbcdff;
+ --iris7: #b8baf8;
+ --iris8: #9b9ef0;
+ --iris9: #5b5bd6;
+ --iris10: #5151cd;
+ --iris11: #5753c6;
+ --iris12: #272962;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --iris1: color(display-p3 0.992 0.992 0.999);
+ --iris2: color(display-p3 0.972 0.973 0.998);
+ --iris3: color(display-p3 0.943 0.945 0.992);
+ --iris4: color(display-p3 0.902 0.906 1);
+ --iris5: color(display-p3 0.857 0.861 1);
+ --iris6: color(display-p3 0.799 0.805 0.987);
+ --iris7: color(display-p3 0.721 0.727 0.955);
+ --iris8: color(display-p3 0.61 0.619 0.918);
+ --iris9: color(display-p3 0.357 0.357 0.81);
+ --iris10: color(display-p3 0.318 0.318 0.774);
+ --iris11: color(display-p3 0.337 0.326 0.748);
+ --iris12: color(display-p3 0.154 0.161 0.371);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --jadeA1: #00c08004;
+ --jadeA2: #00a3460b;
+ --jadeA3: #00ae4819;
+ --jadeA4: #00a85129;
+ --jadeA5: #00a2553c;
+ --jadeA6: #009a5753;
+ --jadeA7: #00945f74;
+ --jadeA8: #00976ea9;
+ --jadeA9: #00916bd6;
+ --jadeA10: #008764d9;
+ --jadeA11: #007152df;
+ --jadeA12: #002217e2;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --jadeA1: color(display-p3 0.024 0.757 0.514 / 0.016);
+ --jadeA2: color(display-p3 0.024 0.612 0.22 / 0.04);
+ --jadeA3: color(display-p3 0.012 0.596 0.235 / 0.087);
+ --jadeA4: color(display-p3 0.008 0.588 0.255 / 0.142);
+ --jadeA5: color(display-p3 0.004 0.561 0.251 / 0.204);
+ --jadeA6: color(display-p3 0.004 0.525 0.278 / 0.287);
+ --jadeA7: color(display-p3 0.004 0.506 0.29 / 0.397);
+ --jadeA8: color(display-p3 0 0.506 0.337 / 0.561);
+ --jadeA9: color(display-p3 0 0.459 0.298 / 0.683);
+ --jadeA10: color(display-p3 0 0.42 0.271 / 0.702);
+ --jadeA11: color(display-p3 0.15 0.5 0.37);
+ --jadeA12: color(display-p3 0.142 0.229 0.194);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --jadeA1: #00de4505;
+ --jadeA2: #27fba60c;
+ --jadeA3: #02f99920;
+ --jadeA4: #00ffaa2d;
+ --jadeA5: #11ffb63b;
+ --jadeA6: #34ffc24b;
+ --jadeA7: #45fdc75e;
+ --jadeA8: #48ffcf75;
+ --jadeA9: #38feca9d;
+ --jadeA10: #31fec7ab;
+ --jadeA11: #21fec0d6;
+ --jadeA12: #b8ffe1ef;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --jadeA1: color(display-p3 0 0.992 0.298 / 0.017);
+ --jadeA2: color(display-p3 0.318 0.988 0.651 / 0.047);
+ --jadeA3: color(display-p3 0.267 1 0.667 / 0.118);
+ --jadeA4: color(display-p3 0.275 0.996 0.702 / 0.173);
+ --jadeA5: color(display-p3 0.361 1 0.741 / 0.227);
+ --jadeA6: color(display-p3 0.439 1 0.796 / 0.286);
+ --jadeA7: color(display-p3 0.49 1 0.804 / 0.362);
+ --jadeA8: color(display-p3 0.506 1 0.835 / 0.45);
+ --jadeA9: color(display-p3 0.478 0.996 0.816 / 0.606);
+ --jadeA10: color(display-p3 0.478 1 0.816 / 0.656);
+ --jadeA11: color(display-p3 0.4 0.835 0.656);
+ --jadeA12: color(display-p3 0.734 0.934 0.838);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --jade1: #0d1512;
+ --jade2: #121c18;
+ --jade3: #0f2e22;
+ --jade4: #0b3b2c;
+ --jade5: #114837;
+ --jade6: #1b5745;
+ --jade7: #246854;
+ --jade8: #2a7e68;
+ --jade9: #29a383;
+ --jade10: #27b08b;
+ --jade11: #1fd8a4;
+ --jade12: #adf0d4;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --jade1: color(display-p3 0.059 0.083 0.071);
+ --jade2: color(display-p3 0.078 0.11 0.094);
+ --jade3: color(display-p3 0.091 0.176 0.138);
+ --jade4: color(display-p3 0.102 0.228 0.177);
+ --jade5: color(display-p3 0.133 0.279 0.221);
+ --jade6: color(display-p3 0.174 0.334 0.273);
+ --jade7: color(display-p3 0.219 0.402 0.335);
+ --jade8: color(display-p3 0.263 0.488 0.411);
+ --jade9: color(display-p3 0.319 0.63 0.521);
+ --jade10: color(display-p3 0.338 0.68 0.555);
+ --jade11: color(display-p3 0.4 0.835 0.656);
+ --jade12: color(display-p3 0.734 0.934 0.838);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --jade1: #fbfefd;
+ --jade2: #f4fbf7;
+ --jade3: #e6f7ed;
+ --jade4: #d6f1e3;
+ --jade5: #c3e9d7;
+ --jade6: #acdec8;
+ --jade7: #8bceb6;
+ --jade8: #56ba9f;
+ --jade9: #29a383;
+ --jade10: #26997b;
+ --jade11: #208368;
+ --jade12: #1d3b31;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --jade1: color(display-p3 0.986 0.996 0.992);
+ --jade2: color(display-p3 0.962 0.983 0.969);
+ --jade3: color(display-p3 0.912 0.965 0.932);
+ --jade4: color(display-p3 0.858 0.941 0.893);
+ --jade5: color(display-p3 0.795 0.909 0.847);
+ --jade6: color(display-p3 0.715 0.864 0.791);
+ --jade7: color(display-p3 0.603 0.802 0.718);
+ --jade8: color(display-p3 0.44 0.72 0.629);
+ --jade9: color(display-p3 0.319 0.63 0.521);
+ --jade10: color(display-p3 0.299 0.592 0.488);
+ --jade11: color(display-p3 0.15 0.5 0.37);
+ --jade12: color(display-p3 0.142 0.229 0.194);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --limeA1: #66990005;
+ --limeA2: #6b95000c;
+ --limeA3: #96c80029;
+ --limeA4: #8fc60042;
+ --limeA5: #81bb0059;
+ --limeA6: #72aa006e;
+ --limeA7: #61990087;
+ --limeA8: #559200ab;
+ --limeA9: #93e4009c;
+ --limeA10: #8fdc00b3;
+ --limeA11: #375f00d0;
+ --limeA12: #1e2900e3;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --limeA1: color(display-p3 0.412 0.608 0.02 / 0.02);
+ --limeA2: color(display-p3 0.514 0.592 0.024 / 0.048);
+ --limeA3: color(display-p3 0.584 0.765 0.008 / 0.15);
+ --limeA4: color(display-p3 0.561 0.757 0.004 / 0.24);
+ --limeA5: color(display-p3 0.514 0.698 0.004 / 0.322);
+ --limeA6: color(display-p3 0.443 0.627 0 / 0.4);
+ --limeA7: color(display-p3 0.376 0.561 0.004 / 0.491);
+ --limeA8: color(display-p3 0.333 0.529 0 / 0.624);
+ --limeA9: color(display-p3 0.588 0.867 0 / 0.534);
+ --limeA10: color(display-p3 0.561 0.827 0 / 0.604);
+ --limeA11: color(display-p3 0.386 0.482 0.227);
+ --limeA12: color(display-p3 0.222 0.25 0.128);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --limeA1: #11bb0003;
+ --limeA2: #78f7000a;
+ --limeA3: #9bfd4c1a;
+ --limeA4: #a7fe5c29;
+ --limeA5: #affe6537;
+ --limeA6: #b2fe6d46;
+ --limeA7: #b6ff6f57;
+ --limeA8: #b6fd6d6c;
+ --limeA9: #caff69ed;
+ --limeA10: #d4ff70;
+ --limeA11: #d1fe77e4;
+ --limeA12: #e9febff7;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --limeA1: color(display-p3 0.067 0.941 0 / 0.009);
+ --limeA2: color(display-p3 0.584 0.996 0.071 / 0.038);
+ --limeA3: color(display-p3 0.69 1 0.38 / 0.101);
+ --limeA4: color(display-p3 0.729 1 0.435 / 0.16);
+ --limeA5: color(display-p3 0.745 1 0.471 / 0.215);
+ --limeA6: color(display-p3 0.769 1 0.482 / 0.274);
+ --limeA7: color(display-p3 0.769 1 0.506 / 0.341);
+ --limeA8: color(display-p3 0.784 1 0.51 / 0.416);
+ --limeA9: color(display-p3 0.839 1 0.502 / 0.925);
+ --limeA10: color(display-p3 0.871 1 0.522 / 0.996);
+ --limeA11: color(display-p3 0.771 0.893 0.485);
+ --limeA12: color(display-p3 0.905 0.966 0.753);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --lime1: #11130c;
+ --lime2: #151a10;
+ --lime3: #1f2917;
+ --lime4: #29371d;
+ --lime5: #334423;
+ --lime6: #3d522a;
+ --lime7: #496231;
+ --lime8: #577538;
+ --lime9: #bdee63;
+ --lime10: #d4ff70;
+ --lime11: #bde56c;
+ --lime12: #e3f7ba;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --lime1: color(display-p3 0.067 0.073 0.048);
+ --lime2: color(display-p3 0.086 0.1 0.067);
+ --lime3: color(display-p3 0.13 0.16 0.099);
+ --lime4: color(display-p3 0.172 0.214 0.126);
+ --lime5: color(display-p3 0.213 0.266 0.153);
+ --lime6: color(display-p3 0.257 0.321 0.182);
+ --lime7: color(display-p3 0.307 0.383 0.215);
+ --lime8: color(display-p3 0.365 0.456 0.25);
+ --lime9: color(display-p3 0.78 0.928 0.466);
+ --lime10: color(display-p3 0.865 0.995 0.519);
+ --lime11: color(display-p3 0.771 0.893 0.485);
+ --lime12: color(display-p3 0.905 0.966 0.753);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --lime1: #fcfdfa;
+ --lime2: #f8faf3;
+ --lime3: #eef6d6;
+ --lime4: #e2f0bd;
+ --lime5: #d3e7a6;
+ --lime6: #c2da91;
+ --lime7: #abc978;
+ --lime8: #8db654;
+ --lime9: #bdee63;
+ --lime10: #b0e64c;
+ --lime11: #5c7c2f;
+ --lime12: #37401c;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --lime1: color(display-p3 0.989 0.992 0.981);
+ --lime2: color(display-p3 0.975 0.98 0.954);
+ --lime3: color(display-p3 0.939 0.965 0.851);
+ --lime4: color(display-p3 0.896 0.94 0.76);
+ --lime5: color(display-p3 0.843 0.903 0.678);
+ --lime6: color(display-p3 0.778 0.852 0.599);
+ --lime7: color(display-p3 0.694 0.784 0.508);
+ --lime8: color(display-p3 0.585 0.707 0.378);
+ --lime9: color(display-p3 0.78 0.928 0.466);
+ --lime10: color(display-p3 0.734 0.896 0.397);
+ --lime11: color(display-p3 0.386 0.482 0.227);
+ --lime12: color(display-p3 0.222 0.25 0.128);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --mauveA1: #55005503;
+ --mauveA2: #2b005506;
+ --mauveA3: #30004010;
+ --mauveA4: #20003618;
+ --mauveA5: #20003820;
+ --mauveA6: #14003527;
+ --mauveA7: #10003332;
+ --mauveA8: #08003145;
+ --mauveA9: #05001d73;
+ --mauveA10: #0500197d;
+ --mauveA11: #0400119c;
+ --mauveA12: #020008e0;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --mauveA1: color(display-p3 0.349 0.024 0.349 / 0.012);
+ --mauveA2: color(display-p3 0.184 0.024 0.349 / 0.024);
+ --mauveA3: color(display-p3 0.129 0.008 0.255 / 0.063);
+ --mauveA4: color(display-p3 0.094 0.012 0.216 / 0.095);
+ --mauveA5: color(display-p3 0.098 0.008 0.224 / 0.126);
+ --mauveA6: color(display-p3 0.055 0.004 0.18 / 0.153);
+ --mauveA7: color(display-p3 0.067 0.008 0.184 / 0.197);
+ --mauveA8: color(display-p3 0.02 0.004 0.176 / 0.271);
+ --mauveA9: color(display-p3 0.02 0.004 0.106 / 0.451);
+ --mauveA10: color(display-p3 0.012 0.004 0.09 / 0.491);
+ --mauveA11: color(display-p3 0.016 0 0.059 / 0.612);
+ --mauveA12: color(display-p3 0.008 0 0.027 / 0.879);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --mauveA1: #00000000;
+ --mauveA2: #f5f4f609;
+ --mauveA3: #ebeaf814;
+ --mauveA4: #eee5f81d;
+ --mauveA5: #efe6fe25;
+ --mauveA6: #f1e6fd30;
+ --mauveA7: #eee9ff40;
+ --mauveA8: #eee7ff5d;
+ --mauveA9: #eae6fd6e;
+ --mauveA10: #ece9fd7c;
+ --mauveA11: #f5f1ffb7;
+ --mauveA12: #fdfdffef;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --mauveA1: color(display-p3 0 0 0 / 0);
+ --mauveA2: color(display-p3 0.996 0.992 1 / 0.034);
+ --mauveA3: color(display-p3 0.937 0.933 0.992 / 0.077);
+ --mauveA4: color(display-p3 0.957 0.918 0.996 / 0.111);
+ --mauveA5: color(display-p3 0.937 0.906 0.996 / 0.145);
+ --mauveA6: color(display-p3 0.953 0.925 0.996 / 0.183);
+ --mauveA7: color(display-p3 0.945 0.929 1 / 0.246);
+ --mauveA8: color(display-p3 0.937 0.918 1 / 0.361);
+ --mauveA9: color(display-p3 0.933 0.918 1 / 0.424);
+ --mauveA10: color(display-p3 0.941 0.925 1 / 0.479);
+ --mauveA11: color(display-p3 0.965 0.961 1 / 0.712);
+ --mauveA12: color(display-p3 0.992 0.992 1 / 0.937);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --mauve1: #121113;
+ --mauve2: #1a191b;
+ --mauve3: #232225;
+ --mauve4: #2b292d;
+ --mauve5: #323035;
+ --mauve6: #3c393f;
+ --mauve7: #49474e;
+ --mauve8: #625f69;
+ --mauve9: #6f6d78;
+ --mauve10: #7c7a85;
+ --mauve11: #b5b2bc;
+ --mauve12: #eeeef0;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --mauve1: color(display-p3 0.07 0.067 0.074);
+ --mauve2: color(display-p3 0.101 0.098 0.105);
+ --mauve3: color(display-p3 0.138 0.134 0.144);
+ --mauve4: color(display-p3 0.167 0.161 0.175);
+ --mauve5: color(display-p3 0.196 0.189 0.206);
+ --mauve6: color(display-p3 0.232 0.225 0.245);
+ --mauve7: color(display-p3 0.286 0.277 0.302);
+ --mauve8: color(display-p3 0.383 0.373 0.408);
+ --mauve9: color(display-p3 0.434 0.428 0.467);
+ --mauve10: color(display-p3 0.487 0.48 0.519);
+ --mauve11: color(display-p3 0.707 0.7 0.735);
+ --mauve12: color(display-p3 0.933 0.933 0.94);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --mauve1: #fdfcfd;
+ --mauve2: #faf9fb;
+ --mauve3: #f2eff3;
+ --mauve4: #eae7ec;
+ --mauve5: #e3dfe6;
+ --mauve6: #dbd8e0;
+ --mauve7: #d0cdd7;
+ --mauve8: #bcbac7;
+ --mauve9: #8e8c99;
+ --mauve10: #84828e;
+ --mauve11: #65636d;
+ --mauve12: #211f26;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --mauve1: color(display-p3 0.991 0.988 0.992);
+ --mauve2: color(display-p3 0.98 0.976 0.984);
+ --mauve3: color(display-p3 0.946 0.938 0.952);
+ --mauve4: color(display-p3 0.915 0.906 0.925);
+ --mauve5: color(display-p3 0.886 0.876 0.901);
+ --mauve6: color(display-p3 0.856 0.846 0.875);
+ --mauve7: color(display-p3 0.814 0.804 0.84);
+ --mauve8: color(display-p3 0.735 0.728 0.777);
+ --mauve9: color(display-p3 0.555 0.549 0.596);
+ --mauve10: color(display-p3 0.514 0.508 0.552);
+ --mauve11: color(display-p3 0.395 0.388 0.424);
+ --mauve12: color(display-p3 0.128 0.122 0.147);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --mintA1: #00d5aa06;
+ --mintA2: #00b18a0d;
+ --mintA3: #00d29e22;
+ --mintA4: #00cc9937;
+ --mintA5: #00c0914c;
+ --mintA6: #00b08663;
+ --mintA7: #00a17d81;
+ --mintA8: #009e7fb3;
+ --mintA9: #00d3a579;
+ --mintA10: #00c39982;
+ --mintA11: #007763fd;
+ --mintA12: #00312ae9;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --mintA1: color(display-p3 0.02 0.804 0.608 / 0.02);
+ --mintA2: color(display-p3 0.02 0.647 0.467 / 0.044);
+ --mintA3: color(display-p3 0.004 0.761 0.553 / 0.114);
+ --mintA4: color(display-p3 0.004 0.741 0.545 / 0.181);
+ --mintA5: color(display-p3 0.004 0.678 0.51 / 0.255);
+ --mintA6: color(display-p3 0.004 0.616 0.463 / 0.334);
+ --mintA7: color(display-p3 0.004 0.549 0.412 / 0.432);
+ --mintA8: color(display-p3 0 0.529 0.392 / 0.581);
+ --mintA9: color(display-p3 0.004 0.765 0.569 / 0.381);
+ --mintA10: color(display-p3 0.004 0.69 0.51 / 0.416);
+ --mintA11: color(display-p3 0.203 0.463 0.397);
+ --mintA12: color(display-p3 0.136 0.259 0.236);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --mintA1: #00dede05;
+ --mintA2: #00f9f90b;
+ --mintA3: #00fff61d;
+ --mintA4: #00fff42c;
+ --mintA5: #00fff23a;
+ --mintA6: #0effeb4a;
+ --mintA7: #34fde55e;
+ --mintA8: #41ffdf76;
+ --mintA9: #92ffe7e9;
+ --mintA10: #aefeedf5;
+ --mintA11: #67ffded2;
+ --mintA12: #cbfee9f5;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --mintA1: color(display-p3 0 0.992 0.992 / 0.017);
+ --mintA2: color(display-p3 0.071 0.98 0.98 / 0.043);
+ --mintA3: color(display-p3 0.176 0.996 0.996 / 0.11);
+ --mintA4: color(display-p3 0.071 0.996 0.973 / 0.169);
+ --mintA5: color(display-p3 0.243 1 0.949 / 0.223);
+ --mintA6: color(display-p3 0.369 1 0.933 / 0.286);
+ --mintA7: color(display-p3 0.459 1 0.914 / 0.362);
+ --mintA8: color(display-p3 0.49 1 0.89 / 0.454);
+ --mintA9: color(display-p3 0.678 0.996 0.914 / 0.904);
+ --mintA10: color(display-p3 0.761 1 0.941 / 0.95);
+ --mintA11: color(display-p3 0.482 0.825 0.733);
+ --mintA12: color(display-p3 0.807 0.955 0.887);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --mint1: #0e1515;
+ --mint2: #0f1b1b;
+ --mint3: #092c2b;
+ --mint4: #003a38;
+ --mint5: #004744;
+ --mint6: #105650;
+ --mint7: #1e685f;
+ --mint8: #277f70;
+ --mint9: #86ead4;
+ --mint10: #a8f5e5;
+ --mint11: #58d5ba;
+ --mint12: #c4f5e1;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --mint1: color(display-p3 0.059 0.082 0.081);
+ --mint2: color(display-p3 0.068 0.104 0.105);
+ --mint3: color(display-p3 0.077 0.17 0.168);
+ --mint4: color(display-p3 0.068 0.224 0.22);
+ --mint5: color(display-p3 0.104 0.275 0.264);
+ --mint6: color(display-p3 0.154 0.332 0.313);
+ --mint7: color(display-p3 0.207 0.403 0.373);
+ --mint8: color(display-p3 0.258 0.49 0.441);
+ --mint9: color(display-p3 0.62 0.908 0.834);
+ --mint10: color(display-p3 0.725 0.954 0.898);
+ --mint11: color(display-p3 0.482 0.825 0.733);
+ --mint12: color(display-p3 0.807 0.955 0.887);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --mint1: #f9fefd;
+ --mint2: #f2fbf9;
+ --mint3: #ddf9f2;
+ --mint4: #c8f4e9;
+ --mint5: #b3ecde;
+ --mint6: #9ce0d0;
+ --mint7: #7ecfbd;
+ --mint8: #4cbba5;
+ --mint9: #86ead4;
+ --mint10: #7de0cb;
+ --mint11: #027864;
+ --mint12: #16433c;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --mint1: color(display-p3 0.98 0.995 0.992);
+ --mint2: color(display-p3 0.957 0.985 0.977);
+ --mint3: color(display-p3 0.888 0.972 0.95);
+ --mint4: color(display-p3 0.819 0.951 0.916);
+ --mint5: color(display-p3 0.747 0.918 0.873);
+ --mint6: color(display-p3 0.668 0.87 0.818);
+ --mint7: color(display-p3 0.567 0.805 0.744);
+ --mint8: color(display-p3 0.42 0.724 0.649);
+ --mint9: color(display-p3 0.62 0.908 0.834);
+ --mint10: color(display-p3 0.585 0.871 0.797);
+ --mint11: color(display-p3 0.203 0.463 0.397);
+ --mint12: color(display-p3 0.136 0.259 0.236);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --oliveA1: #00550003;
+ --oliveA2: #00490007;
+ --oliveA3: #00200010;
+ --oliveA4: #00160018;
+ --oliveA5: #00180020;
+ --oliveA6: #00140028;
+ --oliveA7: #000f0033;
+ --oliveA8: #040f0047;
+ --oliveA9: #050f0078;
+ --oliveA10: #040e0082;
+ --oliveA11: #020a00a0;
+ --oliveA12: #010600e3;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --oliveA1: color(display-p3 0.024 0.349 0.024 / 0.012);
+ --oliveA2: color(display-p3 0.024 0.302 0.024 / 0.028);
+ --oliveA3: color(display-p3 0.008 0.129 0.008 / 0.063);
+ --oliveA4: color(display-p3 0.012 0.094 0.012 / 0.095);
+ --oliveA5: color(display-p3 0.035 0.098 0.008 / 0.126);
+ --oliveA6: color(display-p3 0.027 0.078 0.004 / 0.157);
+ --oliveA7: color(display-p3 0.02 0.059 0 / 0.2);
+ --oliveA8: color(display-p3 0.02 0.059 0.004 / 0.279);
+ --oliveA9: color(display-p3 0.02 0.051 0.004 / 0.467);
+ --oliveA10: color(display-p3 0.024 0.047 0 / 0.51);
+ --oliveA11: color(display-p3 0.012 0.039 0 / 0.628);
+ --oliveA12: color(display-p3 0.008 0.024 0 / 0.891);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --oliveA1: #00000000;
+ --oliveA2: #f1f2f008;
+ --oliveA3: #f4f5f312;
+ --oliveA4: #f3fef21a;
+ --oliveA5: #f2fbf122;
+ --oliveA6: #f4faed2c;
+ --oliveA7: #f2fced3b;
+ --oliveA8: #edfdeb57;
+ --oliveA9: #ebfde766;
+ --oliveA10: #f0fdec74;
+ --oliveA11: #f6fef4b0;
+ --oliveA12: #fdfffded;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --oliveA1: color(display-p3 0 0 0 / 0);
+ --oliveA2: color(display-p3 0.984 0.988 0.976 / 0.03);
+ --oliveA3: color(display-p3 0.992 0.996 0.988 / 0.068);
+ --oliveA4: color(display-p3 0.953 0.996 0.949 / 0.102);
+ --oliveA5: color(display-p3 0.969 1 0.965 / 0.131);
+ --oliveA6: color(display-p3 0.973 1 0.969 / 0.169);
+ --oliveA7: color(display-p3 0.98 1 0.961 / 0.228);
+ --oliveA8: color(display-p3 0.961 1 0.957 / 0.334);
+ --oliveA9: color(display-p3 0.949 1 0.922 / 0.397);
+ --oliveA10: color(display-p3 0.953 1 0.941 / 0.452);
+ --oliveA11: color(display-p3 0.976 1 0.965 / 0.688);
+ --oliveA12: color(display-p3 0.992 1 0.992 / 0.929);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --olive1: #111210;
+ --olive2: #181917;
+ --olive3: #212220;
+ --olive4: #282a27;
+ --olive5: #2f312e;
+ --olive6: #383a36;
+ --olive7: #454843;
+ --olive8: #5c625b;
+ --olive9: #687066;
+ --olive10: #767d74;
+ --olive11: #afb5ad;
+ --olive12: #eceeec;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --olive1: color(display-p3 0.067 0.07 0.063);
+ --olive2: color(display-p3 0.095 0.098 0.091);
+ --olive3: color(display-p3 0.131 0.135 0.126);
+ --olive4: color(display-p3 0.158 0.163 0.153);
+ --olive5: color(display-p3 0.186 0.192 0.18);
+ --olive6: color(display-p3 0.221 0.229 0.215);
+ --olive7: color(display-p3 0.273 0.284 0.266);
+ --olive8: color(display-p3 0.365 0.382 0.359);
+ --olive9: color(display-p3 0.414 0.438 0.404);
+ --olive10: color(display-p3 0.467 0.49 0.458);
+ --olive11: color(display-p3 0.69 0.709 0.682);
+ --olive12: color(display-p3 0.927 0.933 0.926);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --olive1: #fcfdfc;
+ --olive2: #f8faf8;
+ --olive3: #eff1ef;
+ --olive4: #e7e9e7;
+ --olive5: #dfe2df;
+ --olive6: #d7dad7;
+ --olive7: #cccfcc;
+ --olive8: #b9bcb8;
+ --olive9: #898e87;
+ --olive10: #7f847d;
+ --olive11: #60655f;
+ --olive12: #1d211c;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --olive1: color(display-p3 0.989 0.992 0.989);
+ --olive2: color(display-p3 0.974 0.98 0.973);
+ --olive3: color(display-p3 0.939 0.945 0.937);
+ --olive4: color(display-p3 0.907 0.914 0.905);
+ --olive5: color(display-p3 0.878 0.885 0.875);
+ --olive6: color(display-p3 0.846 0.855 0.843);
+ --olive7: color(display-p3 0.803 0.812 0.8);
+ --olive8: color(display-p3 0.727 0.738 0.723);
+ --olive9: color(display-p3 0.541 0.556 0.532);
+ --olive10: color(display-p3 0.5 0.515 0.491);
+ --olive11: color(display-p3 0.38 0.395 0.374);
+ --olive12: color(display-p3 0.117 0.129 0.111);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --orangeA1: #c0400004;
+ --orangeA2: #ff8e0012;
+ --orangeA3: #ff9c0029;
+ --orangeA4: #ff91014a;
+ --orangeA5: #ff8b0065;
+ --orangeA6: #ff81007d;
+ --orangeA7: #ed6c008c;
+ --orangeA8: #e35f00aa;
+ --orangeA9: #f65e00ea;
+ --orangeA10: #ef5f00;
+ --orangeA11: #cc4e00;
+ --orangeA12: #431200e2;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --orangeA1: color(display-p3 0.757 0.267 0.024 / 0.016);
+ --orangeA2: color(display-p3 0.886 0.533 0.008 / 0.067);
+ --orangeA3: color(display-p3 0.922 0.584 0.008 / 0.15);
+ --orangeA4: color(display-p3 1 0.604 0.004 / 0.314);
+ --orangeA5: color(display-p3 1 0.569 0.004 / 0.416);
+ --orangeA6: color(display-p3 0.949 0.494 0.004 / 0.455);
+ --orangeA7: color(display-p3 0.839 0.408 0 / 0.514);
+ --orangeA8: color(display-p3 0.804 0.349 0 / 0.62);
+ --orangeA9: color(display-p3 0.878 0.314 0 / 0.8);
+ --orangeA10: color(display-p3 0.843 0.29 0 / 0.836);
+ --orangeA11: color(display-p3 0.76 0.34 0);
+ --orangeA12: color(display-p3 0.323 0.185 0.127);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --orangeA1: #ec360007;
+ --orangeA2: #fe6d000e;
+ --orangeA3: #fb6a0025;
+ --orangeA4: #ff590039;
+ --orangeA5: #ff61004a;
+ --orangeA6: #fd75045c;
+ --orangeA7: #ff832c75;
+ --orangeA8: #fe84389d;
+ --orangeA9: #fe6d15f7;
+ --orangeA10: #ff801f;
+ --orangeA11: #ffa057;
+ --orangeA12: #ffe0c2;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --orangeA1: color(display-p3 0.961 0.247 0 / 0.022);
+ --orangeA2: color(display-p3 0.992 0.529 0 / 0.051);
+ --orangeA3: color(display-p3 0.996 0.486 0 / 0.131);
+ --orangeA4: color(display-p3 0.996 0.384 0 / 0.211);
+ --orangeA5: color(display-p3 1 0.455 0 / 0.265);
+ --orangeA6: color(display-p3 1 0.529 0.129 / 0.332);
+ --orangeA7: color(display-p3 1 0.569 0.251 / 0.429);
+ --orangeA8: color(display-p3 1 0.584 0.302 / 0.572);
+ --orangeA9: color(display-p3 1 0.494 0.216 / 0.895);
+ --orangeA10: color(display-p3 1 0.522 0.235 / 0.979);
+ --orangeA11: color(display-p3 1 0.63 0.38);
+ --orangeA12: color(display-p3 0.98 0.883 0.775);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --orange1: #17120e;
+ --orange2: #1e160f;
+ --orange3: #331e0b;
+ --orange4: #462100;
+ --orange5: #562800;
+ --orange6: #66350c;
+ --orange7: #7e451d;
+ --orange8: #a35829;
+ --orange9: #f76b15;
+ --orange10: #ff801f;
+ --orange11: #ffa057;
+ --orange12: #ffe0c2;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --orange1: color(display-p3 0.088 0.07 0.057);
+ --orange2: color(display-p3 0.113 0.089 0.061);
+ --orange3: color(display-p3 0.189 0.12 0.056);
+ --orange4: color(display-p3 0.262 0.132 0);
+ --orange5: color(display-p3 0.315 0.168 0.016);
+ --orange6: color(display-p3 0.376 0.219 0.088);
+ --orange7: color(display-p3 0.465 0.283 0.147);
+ --orange8: color(display-p3 0.601 0.359 0.201);
+ --orange9: color(display-p3 0.9 0.45 0.2);
+ --orange10: color(display-p3 0.98 0.51 0.23);
+ --orange11: color(display-p3 1 0.63 0.38);
+ --orange12: color(display-p3 0.98 0.883 0.775);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --orange1: #fefcfb;
+ --orange2: #fff7ed;
+ --orange3: #ffefd6;
+ --orange4: #ffdfb5;
+ --orange5: #ffd19a;
+ --orange6: #ffc182;
+ --orange7: #f5ae73;
+ --orange8: #ec9455;
+ --orange9: #f76b15;
+ --orange10: #ef5f00;
+ --orange11: #cc4e00;
+ --orange12: #582d1d;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --orange1: color(display-p3 0.995 0.988 0.985);
+ --orange2: color(display-p3 0.994 0.968 0.934);
+ --orange3: color(display-p3 0.989 0.938 0.85);
+ --orange4: color(display-p3 1 0.874 0.687);
+ --orange5: color(display-p3 1 0.821 0.583);
+ --orange6: color(display-p3 0.975 0.767 0.545);
+ --orange7: color(display-p3 0.919 0.693 0.486);
+ --orange8: color(display-p3 0.877 0.597 0.379);
+ --orange9: color(display-p3 0.9 0.45 0.2);
+ --orange10: color(display-p3 0.87 0.409 0.164);
+ --orange11: color(display-p3 0.76 0.34 0);
+ --orange12: color(display-p3 0.323 0.185 0.127);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --pinkA1: #ff00aa03;
+ --pinkA2: #e0008008;
+ --pinkA3: #f4008c16;
+ --pinkA4: #e2008b23;
+ --pinkA5: #d1008331;
+ --pinkA6: #c0007840;
+ --pinkA7: #b6006f53;
+ --pinkA8: #af006f6c;
+ --pinkA9: #c8007fbf;
+ --pinkA10: #c2007ac7;
+ --pinkA11: #b60074d6;
+ --pinkA12: #59003bed;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --pinkA1: color(display-p3 0.675 0.024 0.675 / 0.012);
+ --pinkA2: color(display-p3 0.757 0.02 0.51 / 0.032);
+ --pinkA3: color(display-p3 0.765 0.008 0.529 / 0.083);
+ --pinkA4: color(display-p3 0.737 0.008 0.506 / 0.134);
+ --pinkA5: color(display-p3 0.663 0.004 0.451 / 0.185);
+ --pinkA6: color(display-p3 0.616 0.004 0.424 / 0.244);
+ --pinkA7: color(display-p3 0.596 0.004 0.412 / 0.318);
+ --pinkA8: color(display-p3 0.573 0.004 0.404 / 0.412);
+ --pinkA9: color(display-p3 0.682 0 0.447 / 0.702);
+ --pinkA10: color(display-p3 0.655 0 0.424 / 0.73);
+ --pinkA11: color(display-p3 0.698 0.219 0.528);
+ --pinkA12: color(display-p3 0.363 0.101 0.279);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --pinkA1: #f412bc09;
+ --pinkA2: #f420bb12;
+ --pinkA3: #fe37cc29;
+ --pinkA4: #fc1ec43f;
+ --pinkA5: #fd35c24e;
+ --pinkA6: #fd51c75f;
+ --pinkA7: #fd62c87b;
+ --pinkA8: #ff68c8a2;
+ --pinkA9: #fe49bcd4;
+ --pinkA10: #ff5cc0dc;
+ --pinkA11: #ff8dcc;
+ --pinkA12: #ffd3ecfd;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --pinkA1: color(display-p3 0.984 0.071 0.855 / 0.03);
+ --pinkA2: color(display-p3 1 0.2 0.8 / 0.059);
+ --pinkA3: color(display-p3 1 0.294 0.886 / 0.139);
+ --pinkA4: color(display-p3 1 0.192 0.82 / 0.219);
+ --pinkA5: color(display-p3 1 0.282 0.827 / 0.274);
+ --pinkA6: color(display-p3 1 0.396 0.835 / 0.337);
+ --pinkA7: color(display-p3 1 0.459 0.831 / 0.442);
+ --pinkA8: color(display-p3 1 0.478 0.827 / 0.585);
+ --pinkA9: color(display-p3 1 0.373 0.784 / 0.761);
+ --pinkA10: color(display-p3 1 0.435 0.792 / 0.795);
+ --pinkA11: color(display-p3 1 0.535 0.78);
+ --pinkA12: color(display-p3 0.964 0.826 0.912);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --pink1: #191117;
+ --pink2: #21121d;
+ --pink3: #37172f;
+ --pink4: #4b143d;
+ --pink5: #591c47;
+ --pink6: #692955;
+ --pink7: #833869;
+ --pink8: #a84885;
+ --pink9: #d6409f;
+ --pink10: #de51a8;
+ --pink11: #ff8dcc;
+ --pink12: #fdd1ea;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --pink1: color(display-p3 0.093 0.068 0.089);
+ --pink2: color(display-p3 0.121 0.073 0.11);
+ --pink3: color(display-p3 0.198 0.098 0.179);
+ --pink4: color(display-p3 0.271 0.095 0.231);
+ --pink5: color(display-p3 0.32 0.127 0.273);
+ --pink6: color(display-p3 0.382 0.177 0.326);
+ --pink7: color(display-p3 0.477 0.238 0.405);
+ --pink8: color(display-p3 0.612 0.304 0.51);
+ --pink9: color(display-p3 0.775 0.297 0.61);
+ --pink10: color(display-p3 0.808 0.356 0.645);
+ --pink11: color(display-p3 1 0.535 0.78);
+ --pink12: color(display-p3 0.964 0.826 0.912);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --pink1: #fffcfe;
+ --pink2: #fef7fb;
+ --pink3: #fee9f5;
+ --pink4: #fbdcef;
+ --pink5: #f6cee7;
+ --pink6: #efbfdd;
+ --pink7: #e7acd0;
+ --pink8: #dd93c2;
+ --pink9: #d6409f;
+ --pink10: #cf3897;
+ --pink11: #c2298a;
+ --pink12: #651249;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --pink1: color(display-p3 0.998 0.989 0.996);
+ --pink2: color(display-p3 0.992 0.97 0.985);
+ --pink3: color(display-p3 0.981 0.917 0.96);
+ --pink4: color(display-p3 0.963 0.867 0.932);
+ --pink5: color(display-p3 0.939 0.815 0.899);
+ --pink6: color(display-p3 0.907 0.756 0.859);
+ --pink7: color(display-p3 0.869 0.683 0.81);
+ --pink8: color(display-p3 0.825 0.59 0.751);
+ --pink9: color(display-p3 0.775 0.297 0.61);
+ --pink10: color(display-p3 0.748 0.27 0.581);
+ --pink11: color(display-p3 0.698 0.219 0.528);
+ --pink12: color(display-p3 0.363 0.101 0.279);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --plumA1: #aa00ff03;
+ --plumA2: #c000c008;
+ --plumA3: #cc00cc14;
+ --plumA4: #c200c921;
+ --plumA5: #b700bd2e;
+ --plumA6: #a400b03d;
+ --plumA7: #9900a852;
+ --plumA8: #9000a56e;
+ --plumA9: #89009eb5;
+ --plumA10: #7f0092bb;
+ --plumA11: #730086c1;
+ --plumA12: #40004be6;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --plumA1: color(display-p3 0.675 0.024 1 / 0.012);
+ --plumA2: color(display-p3 0.58 0.024 0.58 / 0.028);
+ --plumA3: color(display-p3 0.655 0.008 0.753 / 0.079);
+ --plumA4: color(display-p3 0.627 0.008 0.722 / 0.126);
+ --plumA5: color(display-p3 0.58 0.004 0.69 / 0.177);
+ --plumA6: color(display-p3 0.537 0.004 0.655 / 0.236);
+ --plumA7: color(display-p3 0.49 0.004 0.616 / 0.314);
+ --plumA8: color(display-p3 0.471 0.004 0.6 / 0.42);
+ --plumA9: color(display-p3 0.451 0 0.576 / 0.687);
+ --plumA10: color(display-p3 0.42 0 0.529 / 0.71);
+ --plumA11: color(display-p3 0.543 0.263 0.619);
+ --plumA12: color(display-p3 0.299 0.114 0.352);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --plumA1: #f112f108;
+ --plumA2: #f22ff211;
+ --plumA3: #fd4cfd27;
+ --plumA4: #f646ff3a;
+ --plumA5: #f455ff48;
+ --plumA6: #f66dff56;
+ --plumA7: #f07cfd70;
+ --plumA8: #ee84ff95;
+ --plumA9: #e961feb6;
+ --plumA10: #ed70ffc0;
+ --plumA11: #f19cfef3;
+ --plumA12: #feddfef4;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --plumA1: color(display-p3 0.973 0.071 0.973 / 0.026);
+ --plumA2: color(display-p3 0.933 0.267 1 / 0.059);
+ --plumA3: color(display-p3 0.918 0.333 0.996 / 0.148);
+ --plumA4: color(display-p3 0.91 0.318 1 / 0.219);
+ --plumA5: color(display-p3 0.914 0.388 1 / 0.269);
+ --plumA6: color(display-p3 0.906 0.463 1 / 0.328);
+ --plumA7: color(display-p3 0.906 0.529 1 / 0.425);
+ --plumA8: color(display-p3 0.906 0.553 1 / 0.568);
+ --plumA9: color(display-p3 0.875 0.427 1 / 0.69);
+ --plumA10: color(display-p3 0.886 0.471 0.996 / 0.732);
+ --plumA11: color(display-p3 0.86 0.602 0.933);
+ --plumA12: color(display-p3 0.936 0.836 0.949);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --plum1: #181118;
+ --plum2: #201320;
+ --plum3: #351a35;
+ --plum4: #451d47;
+ --plum5: #512454;
+ --plum6: #5e3061;
+ --plum7: #734079;
+ --plum8: #92549c;
+ --plum9: #ab4aba;
+ --plum10: #b658c4;
+ --plum11: #e796f3;
+ --plum12: #f4d4f4;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --plum1: color(display-p3 0.09 0.068 0.092);
+ --plum2: color(display-p3 0.118 0.077 0.121);
+ --plum3: color(display-p3 0.192 0.105 0.202);
+ --plum4: color(display-p3 0.25 0.121 0.271);
+ --plum5: color(display-p3 0.293 0.152 0.319);
+ --plum6: color(display-p3 0.343 0.198 0.372);
+ --plum7: color(display-p3 0.424 0.262 0.461);
+ --plum8: color(display-p3 0.54 0.341 0.595);
+ --plum9: color(display-p3 0.624 0.313 0.708);
+ --plum10: color(display-p3 0.666 0.365 0.748);
+ --plum11: color(display-p3 0.86 0.602 0.933);
+ --plum12: color(display-p3 0.936 0.836 0.949);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --plum1: #fefcff;
+ --plum2: #fdf7fd;
+ --plum3: #fbebfb;
+ --plum4: #f7def8;
+ --plum5: #f2d1f3;
+ --plum6: #e9c2ec;
+ --plum7: #deade3;
+ --plum8: #cf91d8;
+ --plum9: #ab4aba;
+ --plum10: #a144af;
+ --plum11: #953ea3;
+ --plum12: #53195d;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --plum1: color(display-p3 0.995 0.988 0.999);
+ --plum2: color(display-p3 0.988 0.971 0.99);
+ --plum3: color(display-p3 0.973 0.923 0.98);
+ --plum4: color(display-p3 0.953 0.875 0.966);
+ --plum5: color(display-p3 0.926 0.825 0.945);
+ --plum6: color(display-p3 0.89 0.765 0.916);
+ --plum7: color(display-p3 0.84 0.686 0.877);
+ --plum8: color(display-p3 0.775 0.58 0.832);
+ --plum9: color(display-p3 0.624 0.313 0.708);
+ --plum10: color(display-p3 0.587 0.29 0.667);
+ --plum11: color(display-p3 0.543 0.263 0.619);
+ --plum12: color(display-p3 0.299 0.114 0.352);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --purpleA1: #aa00aa03;
+ --purpleA2: #8000e008;
+ --purpleA3: #8e00f112;
+ --purpleA4: #8d00e51d;
+ --purpleA5: #8000db2a;
+ --purpleA6: #7a01d03b;
+ --purpleA7: #6d00c350;
+ --purpleA8: #6600c06c;
+ --purpleA9: #5c00adb1;
+ --purpleA10: #53009eb8;
+ --purpleA11: #52009aba;
+ --purpleA12: #250049df;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --purpleA1: color(display-p3 0.675 0.024 0.675 / 0.012);
+ --purpleA2: color(display-p3 0.443 0.024 0.722 / 0.028);
+ --purpleA3: color(display-p3 0.506 0.008 0.835 / 0.071);
+ --purpleA4: color(display-p3 0.451 0.004 0.831 / 0.114);
+ --purpleA5: color(display-p3 0.431 0.004 0.788 / 0.165);
+ --purpleA6: color(display-p3 0.384 0.004 0.745 / 0.228);
+ --purpleA7: color(display-p3 0.357 0.004 0.71 / 0.31);
+ --purpleA8: color(display-p3 0.322 0.004 0.702 / 0.416);
+ --purpleA9: color(display-p3 0.298 0 0.639 / 0.683);
+ --purpleA10: color(display-p3 0.271 0 0.58 / 0.71);
+ --purpleA11: color(display-p3 0.473 0.281 0.687);
+ --purpleA12: color(display-p3 0.234 0.132 0.363);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --purpleA1: #b412f90b;
+ --purpleA2: #b744f714;
+ --purpleA3: #c150ff2d;
+ --purpleA4: #bb53fd42;
+ --purpleA5: #be5cfd51;
+ --purpleA6: #c16dfd61;
+ --purpleA7: #c378fd7a;
+ --purpleA8: #c47effa4;
+ --purpleA9: #b661ffc2;
+ --purpleA10: #bc6fffcd;
+ --purpleA11: #d19dff;
+ --purpleA12: #f1ddfffa;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --purpleA1: color(display-p3 0.686 0.071 0.996 / 0.038);
+ --purpleA2: color(display-p3 0.722 0.286 0.996 / 0.072);
+ --purpleA3: color(display-p3 0.718 0.349 0.996 / 0.169);
+ --purpleA4: color(display-p3 0.702 0.353 1 / 0.248);
+ --purpleA5: color(display-p3 0.718 0.404 1 / 0.303);
+ --purpleA6: color(display-p3 0.733 0.455 1 / 0.366);
+ --purpleA7: color(display-p3 0.753 0.506 1 / 0.458);
+ --purpleA8: color(display-p3 0.749 0.522 1 / 0.622);
+ --purpleA9: color(display-p3 0.686 0.408 1 / 0.736);
+ --purpleA10: color(display-p3 0.71 0.459 1 / 0.778);
+ --purpleA11: color(display-p3 0.8 0.62 1);
+ --purpleA12: color(display-p3 0.913 0.854 0.971);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --purple1: #18111b;
+ --purple2: #1e1523;
+ --purple3: #301c3b;
+ --purple4: #3d224e;
+ --purple5: #48295c;
+ --purple6: #54346b;
+ --purple7: #664282;
+ --purple8: #8457aa;
+ --purple9: #8e4ec6;
+ --purple10: #9a5cd0;
+ --purple11: #d19dff;
+ --purple12: #ecd9fa;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --purple1: color(display-p3 0.09 0.068 0.103);
+ --purple2: color(display-p3 0.113 0.082 0.134);
+ --purple3: color(display-p3 0.175 0.112 0.224);
+ --purple4: color(display-p3 0.224 0.137 0.297);
+ --purple5: color(display-p3 0.264 0.167 0.349);
+ --purple6: color(display-p3 0.311 0.208 0.406);
+ --purple7: color(display-p3 0.381 0.266 0.496);
+ --purple8: color(display-p3 0.49 0.349 0.649);
+ --purple9: color(display-p3 0.523 0.318 0.751);
+ --purple10: color(display-p3 0.57 0.373 0.791);
+ --purple11: color(display-p3 0.8 0.62 1);
+ --purple12: color(display-p3 0.913 0.854 0.971);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --purple1: #fefcfe;
+ --purple2: #fbf7fe;
+ --purple3: #f7edfe;
+ --purple4: #f2e2fc;
+ --purple5: #ead5f9;
+ --purple6: #e0c4f4;
+ --purple7: #d1afec;
+ --purple8: #be93e4;
+ --purple9: #8e4ec6;
+ --purple10: #8347b9;
+ --purple11: #8145b5;
+ --purple12: #402060;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --purple1: color(display-p3 0.995 0.988 0.996);
+ --purple2: color(display-p3 0.983 0.971 0.993);
+ --purple3: color(display-p3 0.963 0.931 0.989);
+ --purple4: color(display-p3 0.937 0.888 0.981);
+ --purple5: color(display-p3 0.904 0.837 0.966);
+ --purple6: color(display-p3 0.86 0.774 0.942);
+ --purple7: color(display-p3 0.799 0.69 0.91);
+ --purple8: color(display-p3 0.719 0.583 0.874);
+ --purple9: color(display-p3 0.523 0.318 0.751);
+ --purple10: color(display-p3 0.483 0.289 0.7);
+ --purple11: color(display-p3 0.473 0.281 0.687);
+ --purple12: color(display-p3 0.234 0.132 0.363);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --redA1: #ff000003;
+ --redA2: #ff000008;
+ --redA3: #f3000d14;
+ --redA4: #ff000824;
+ --redA5: #ff000632;
+ --redA6: #f8000442;
+ --redA7: #df000356;
+ --redA8: #d2000571;
+ --redA9: #db0007b7;
+ --redA10: #d10005c1;
+ --redA11: #c40006d3;
+ --redA12: #55000de8;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --redA1: color(display-p3 0.675 0.024 0.024 / 0.012);
+ --redA2: color(display-p3 0.863 0.024 0.024 / 0.028);
+ --redA3: color(display-p3 0.792 0.008 0.008 / 0.075);
+ --redA4: color(display-p3 1 0.008 0.008 / 0.134);
+ --redA5: color(display-p3 0.918 0.008 0.008 / 0.189);
+ --redA6: color(display-p3 0.831 0.02 0.004 / 0.251);
+ --redA7: color(display-p3 0.741 0.016 0.004 / 0.33);
+ --redA8: color(display-p3 0.698 0.012 0.004 / 0.428);
+ --redA9: color(display-p3 0.749 0.008 0 / 0.675);
+ --redA10: color(display-p3 0.714 0.012 0 / 0.714);
+ --redA11: color(display-p3 0.744 0.234 0.222);
+ --redA12: color(display-p3 0.36 0.115 0.143);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --redA1: #f4121209;
+ --redA2: #f22f3e11;
+ --redA3: #ff173f2d;
+ --redA4: #fe0a3b44;
+ --redA5: #ff204756;
+ --redA6: #ff3e5668;
+ --redA7: #ff536184;
+ --redA8: #ff5d61b0;
+ --redA9: #fe4e54e4;
+ --redA10: #ff6465eb;
+ --redA11: #ff9592;
+ --redA12: #ffd1d9;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --redA1: color(display-p3 0.984 0.071 0.071 / 0.03);
+ --redA2: color(display-p3 0.996 0.282 0.282 / 0.055);
+ --redA3: color(display-p3 1 0.169 0.271 / 0.156);
+ --redA4: color(display-p3 1 0.118 0.267 / 0.236);
+ --redA5: color(display-p3 1 0.212 0.314 / 0.303);
+ --redA6: color(display-p3 1 0.318 0.38 / 0.374);
+ --redA7: color(display-p3 1 0.4 0.424 / 0.475);
+ --redA8: color(display-p3 1 0.431 0.431 / 0.635);
+ --redA9: color(display-p3 1 0.388 0.384 / 0.82);
+ --redA10: color(display-p3 1 0.463 0.447 / 0.853);
+ --redA11: color(display-p3 1 0.57 0.55);
+ --redA12: color(display-p3 0.971 0.826 0.852);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --red1: #191111;
+ --red2: #201314;
+ --red3: #3b1219;
+ --red4: #500f1c;
+ --red5: #611623;
+ --red6: #72232d;
+ --red7: #8c333a;
+ --red8: #b54548;
+ --red9: #e5484d;
+ --red10: #ec5d5e;
+ --red11: #ff9592;
+ --red12: #ffd1d9;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --red1: color(display-p3 0.093 0.068 0.067);
+ --red2: color(display-p3 0.118 0.077 0.079);
+ --red3: color(display-p3 0.211 0.081 0.099);
+ --red4: color(display-p3 0.287 0.079 0.113);
+ --red5: color(display-p3 0.348 0.11 0.142);
+ --red6: color(display-p3 0.414 0.16 0.183);
+ --red7: color(display-p3 0.508 0.224 0.236);
+ --red8: color(display-p3 0.659 0.298 0.297);
+ --red9: color(display-p3 0.83 0.329 0.324);
+ --red10: color(display-p3 0.861 0.403 0.387);
+ --red11: color(display-p3 1 0.57 0.55);
+ --red12: color(display-p3 0.971 0.826 0.852);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --red1: #fffcfc;
+ --red2: #fff7f7;
+ --red3: #feebec;
+ --red4: #ffdbdc;
+ --red5: #ffcdce;
+ --red6: #fdbdbe;
+ --red7: #f4a9aa;
+ --red8: #eb8e90;
+ --red9: #e5484d;
+ --red10: #dc3e42;
+ --red11: #ce2c31;
+ --red12: #641723;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --red1: color(display-p3 0.998 0.989 0.988);
+ --red2: color(display-p3 0.995 0.971 0.971);
+ --red3: color(display-p3 0.985 0.925 0.925);
+ --red4: color(display-p3 0.999 0.866 0.866);
+ --red5: color(display-p3 0.984 0.812 0.811);
+ --red6: color(display-p3 0.955 0.751 0.749);
+ --red7: color(display-p3 0.915 0.675 0.672);
+ --red8: color(display-p3 0.872 0.575 0.572);
+ --red9: color(display-p3 0.83 0.329 0.324);
+ --red10: color(display-p3 0.798 0.294 0.285);
+ --red11: color(display-p3 0.744 0.234 0.222);
+ --red12: color(display-p3 0.36 0.115 0.143);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --rubyA1: #ff005503;
+ --rubyA2: #ff002008;
+ --rubyA3: #f3002515;
+ --rubyA4: #ff002523;
+ --rubyA5: #ff002a31;
+ --rubyA6: #e4002440;
+ --rubyA7: #ce002553;
+ --rubyA8: #c300286d;
+ --rubyA9: #db002cb9;
+ --rubyA10: #d2002cc4;
+ --rubyA11: #c10030db;
+ --rubyA12: #550016e8;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --rubyA1: color(display-p3 0.675 0.024 0.349 / 0.012);
+ --rubyA2: color(display-p3 0.863 0.024 0.024 / 0.028);
+ --rubyA3: color(display-p3 0.804 0.008 0.11 / 0.079);
+ --rubyA4: color(display-p3 0.91 0.008 0.125 / 0.13);
+ --rubyA5: color(display-p3 0.831 0.004 0.133 / 0.185);
+ --rubyA6: color(display-p3 0.745 0.004 0.118 / 0.244);
+ --rubyA7: color(display-p3 0.678 0.004 0.114 / 0.314);
+ --rubyA8: color(display-p3 0.639 0.004 0.125 / 0.412);
+ --rubyA9: color(display-p3 0.753 0 0.129 / 0.679);
+ --rubyA10: color(display-p3 0.714 0 0.125 / 0.714);
+ --rubyA11: color(display-p3 0.728 0.211 0.311);
+ --rubyA12: color(display-p3 0.36 0.115 0.171);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --rubyA1: #f4124a09;
+ --rubyA2: #fe5a7f0e;
+ --rubyA3: #ff235d2c;
+ --rubyA4: #fd195e42;
+ --rubyA5: #fe2d6b53;
+ --rubyA6: #ff447665;
+ --rubyA7: #ff577d80;
+ --rubyA8: #ff5c7cae;
+ --rubyA9: #fe4c70e4;
+ --rubyA10: #ff617beb;
+ --rubyA11: #ff949d;
+ --rubyA12: #ffd3e2fe;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --rubyA1: color(display-p3 0.984 0.071 0.329 / 0.03);
+ --rubyA2: color(display-p3 0.992 0.376 0.529 / 0.051);
+ --rubyA3: color(display-p3 0.996 0.196 0.404 / 0.152);
+ --rubyA4: color(display-p3 1 0.173 0.416 / 0.227);
+ --rubyA5: color(display-p3 1 0.259 0.459 / 0.29);
+ --rubyA6: color(display-p3 1 0.341 0.506 / 0.358);
+ --rubyA7: color(display-p3 1 0.412 0.541 / 0.458);
+ --rubyA8: color(display-p3 1 0.431 0.537 / 0.627);
+ --rubyA9: color(display-p3 1 0.376 0.482 / 0.82);
+ --rubyA10: color(display-p3 1 0.447 0.522 / 0.849);
+ --rubyA11: color(display-p3 1 0.57 0.59);
+ --rubyA12: color(display-p3 0.968 0.83 0.88);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --ruby1: #191113;
+ --ruby2: #1e1517;
+ --ruby3: #3a141e;
+ --ruby4: #4e1325;
+ --ruby5: #5e1a2e;
+ --ruby6: #6f2539;
+ --ruby7: #883447;
+ --ruby8: #b3445a;
+ --ruby9: #e54666;
+ --ruby10: #ec5a72;
+ --ruby11: #ff949d;
+ --ruby12: #fed2e1;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --ruby1: color(display-p3 0.093 0.068 0.074);
+ --ruby2: color(display-p3 0.113 0.083 0.089);
+ --ruby3: color(display-p3 0.208 0.088 0.117);
+ --ruby4: color(display-p3 0.279 0.092 0.147);
+ --ruby5: color(display-p3 0.337 0.12 0.18);
+ --ruby6: color(display-p3 0.401 0.166 0.223);
+ --ruby7: color(display-p3 0.495 0.224 0.281);
+ --ruby8: color(display-p3 0.652 0.295 0.359);
+ --ruby9: color(display-p3 0.83 0.323 0.408);
+ --ruby10: color(display-p3 0.857 0.392 0.455);
+ --ruby11: color(display-p3 1 0.57 0.59);
+ --ruby12: color(display-p3 0.968 0.83 0.88);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --ruby1: #fffcfd;
+ --ruby2: #fff7f8;
+ --ruby3: #feeaed;
+ --ruby4: #ffdce1;
+ --ruby5: #ffced6;
+ --ruby6: #f8bfc8;
+ --ruby7: #efacb8;
+ --ruby8: #e592a3;
+ --ruby9: #e54666;
+ --ruby10: #dc3b5d;
+ --ruby11: #ca244d;
+ --ruby12: #64172b;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --ruby1: color(display-p3 0.998 0.989 0.992);
+ --ruby2: color(display-p3 0.995 0.971 0.974);
+ --ruby3: color(display-p3 0.983 0.92 0.928);
+ --ruby4: color(display-p3 0.987 0.869 0.885);
+ --ruby5: color(display-p3 0.968 0.817 0.839);
+ --ruby6: color(display-p3 0.937 0.758 0.786);
+ --ruby7: color(display-p3 0.897 0.685 0.721);
+ --ruby8: color(display-p3 0.851 0.588 0.639);
+ --ruby9: color(display-p3 0.83 0.323 0.408);
+ --ruby10: color(display-p3 0.795 0.286 0.375);
+ --ruby11: color(display-p3 0.728 0.211 0.311);
+ --ruby12: color(display-p3 0.36 0.115 0.171);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --sageA1: #00804004;
+ --sageA2: #00402008;
+ --sageA3: #002d1e11;
+ --sageA4: #001f1519;
+ --sageA5: #00180820;
+ --sageA6: #00140d28;
+ --sageA7: #00140a34;
+ --sageA8: #000f0847;
+ --sageA9: #00110b79;
+ --sageA10: #00100a83;
+ --sageA11: #000a07a0;
+ --sageA12: #000805e5;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --sageA1: color(display-p3 0.024 0.514 0.267 / 0.016);
+ --sageA2: color(display-p3 0.02 0.267 0.145 / 0.032);
+ --sageA3: color(display-p3 0.008 0.184 0.125 / 0.067);
+ --sageA4: color(display-p3 0.012 0.094 0.051 / 0.095);
+ --sageA5: color(display-p3 0.008 0.098 0.035 / 0.126);
+ --sageA6: color(display-p3 0.004 0.078 0.027 / 0.157);
+ --sageA7: color(display-p3 0 0.059 0.039 / 0.2);
+ --sageA8: color(display-p3 0.004 0.047 0.031 / 0.275);
+ --sageA9: color(display-p3 0.004 0.059 0.035 / 0.471);
+ --sageA10: color(display-p3 0 0.047 0.031 / 0.51);
+ --sageA11: color(display-p3 0 0.031 0.02 / 0.624);
+ --sageA12: color(display-p3 0 0.027 0.012 / 0.895);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --sageA1: #00000000;
+ --sageA2: #f0f2f108;
+ --sageA3: #f3f5f412;
+ --sageA4: #f2fefd1a;
+ --sageA5: #f1fbfa22;
+ --sageA6: #edfbf42d;
+ --sageA7: #edfcf73c;
+ --sageA8: #ebfdf657;
+ --sageA9: #dffdf266;
+ --sageA10: #e5fdf674;
+ --sageA11: #f4fefbb0;
+ --sageA12: #fdfffeed;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --sageA1: color(display-p3 0 0 0 / 0);
+ --sageA2: color(display-p3 0.976 0.988 0.984 / 0.03);
+ --sageA3: color(display-p3 0.992 0.945 0.941 / 0.072);
+ --sageA4: color(display-p3 0.988 0.996 0.992 / 0.102);
+ --sageA5: color(display-p3 0.992 1 0.996 / 0.131);
+ --sageA6: color(display-p3 0.973 1 0.976 / 0.173);
+ --sageA7: color(display-p3 0.957 1 0.976 / 0.233);
+ --sageA8: color(display-p3 0.957 1 0.984 / 0.334);
+ --sageA9: color(display-p3 0.902 1 0.957 / 0.397);
+ --sageA10: color(display-p3 0.929 1 0.973 / 0.452);
+ --sageA11: color(display-p3 0.969 1 0.988 / 0.688);
+ --sageA12: color(display-p3 0.992 1 0.996 / 0.929);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --sage1: #101211;
+ --sage2: #171918;
+ --sage3: #202221;
+ --sage4: #272a29;
+ --sage5: #2e3130;
+ --sage6: #373b39;
+ --sage7: #444947;
+ --sage8: #5b625f;
+ --sage9: #63706b;
+ --sage10: #717d79;
+ --sage11: #adb5b2;
+ --sage12: #eceeed;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --sage1: color(display-p3 0.064 0.07 0.067);
+ --sage2: color(display-p3 0.092 0.098 0.094);
+ --sage3: color(display-p3 0.128 0.135 0.131);
+ --sage4: color(display-p3 0.155 0.164 0.159);
+ --sage5: color(display-p3 0.183 0.193 0.188);
+ --sage6: color(display-p3 0.218 0.23 0.224);
+ --sage7: color(display-p3 0.269 0.285 0.277);
+ --sage8: color(display-p3 0.362 0.382 0.373);
+ --sage9: color(display-p3 0.398 0.438 0.421);
+ --sage10: color(display-p3 0.453 0.49 0.474);
+ --sage11: color(display-p3 0.685 0.709 0.697);
+ --sage12: color(display-p3 0.927 0.933 0.93);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --sage1: #fbfdfc;
+ --sage2: #f7f9f8;
+ --sage3: #eef1f0;
+ --sage4: #e6e9e8;
+ --sage5: #dfe2e0;
+ --sage6: #d7dad9;
+ --sage7: #cbcfcd;
+ --sage8: #b8bcba;
+ --sage9: #868e8b;
+ --sage10: #7c8481;
+ --sage11: #5f6563;
+ --sage12: #1a211e;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --sage1: color(display-p3 0.986 0.992 0.988);
+ --sage2: color(display-p3 0.97 0.977 0.974);
+ --sage3: color(display-p3 0.935 0.944 0.94);
+ --sage4: color(display-p3 0.904 0.913 0.909);
+ --sage5: color(display-p3 0.875 0.885 0.88);
+ --sage6: color(display-p3 0.844 0.854 0.849);
+ --sage7: color(display-p3 0.8 0.811 0.806);
+ --sage8: color(display-p3 0.725 0.738 0.732);
+ --sage9: color(display-p3 0.531 0.556 0.546);
+ --sage10: color(display-p3 0.492 0.515 0.506);
+ --sage11: color(display-p3 0.377 0.395 0.389);
+ --sage12: color(display-p3 0.107 0.129 0.118);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --sandA1: #55550003;
+ --sandA2: #25250007;
+ --sandA3: #20100010;
+ --sandA4: #1f150019;
+ --sandA5: #1f180021;
+ --sandA6: #19130029;
+ --sandA7: #19140035;
+ --sandA8: #1915014a;
+ --sandA9: #0f0f0079;
+ --sandA10: #0c0c0083;
+ --sandA11: #080800a1;
+ --sandA12: #060500e3;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --sandA1: color(display-p3 0.349 0.349 0.024 / 0.012);
+ --sandA2: color(display-p3 0.161 0.161 0.024 / 0.028);
+ --sandA3: color(display-p3 0.067 0.067 0.008 / 0.063);
+ --sandA4: color(display-p3 0.129 0.129 0.012 / 0.099);
+ --sandA5: color(display-p3 0.098 0.067 0.008 / 0.126);
+ --sandA6: color(display-p3 0.102 0.075 0.004 / 0.161);
+ --sandA7: color(display-p3 0.098 0.098 0.004 / 0.208);
+ --sandA8: color(display-p3 0.086 0.075 0.004 / 0.287);
+ --sandA9: color(display-p3 0.051 0.051 0.004 / 0.471);
+ --sandA10: color(display-p3 0.047 0.047 0 / 0.514);
+ --sandA11: color(display-p3 0.031 0.031 0 / 0.632);
+ --sandA12: color(display-p3 0.024 0.02 0 / 0.891);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --sandA1: #00000000;
+ --sandA2: #f4f4f309;
+ --sandA3: #f6f6f513;
+ --sandA4: #fefef31b;
+ --sandA5: #fbfbeb23;
+ --sandA6: #fffaed2d;
+ --sandA7: #fffbed3c;
+ --sandA8: #fff9eb57;
+ --sandA9: #fffae965;
+ --sandA10: #fffdee73;
+ --sandA11: #fffcf4b0;
+ --sandA12: #fffffded;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --sandA1: color(display-p3 0 0 0 / 0);
+ --sandA2: color(display-p3 0.992 0.992 0.988 / 0.034);
+ --sandA3: color(display-p3 0.996 0.996 0.992 / 0.072);
+ --sandA4: color(display-p3 0.992 0.992 0.953 / 0.106);
+ --sandA5: color(display-p3 1 1 0.965 / 0.135);
+ --sandA6: color(display-p3 1 0.976 0.929 / 0.177);
+ --sandA7: color(display-p3 1 0.984 0.929 / 0.236);
+ --sandA8: color(display-p3 1 0.976 0.925 / 0.341);
+ --sandA9: color(display-p3 1 0.98 0.925 / 0.395);
+ --sandA10: color(display-p3 1 0.992 0.933 / 0.45);
+ --sandA11: color(display-p3 1 0.996 0.961 / 0.685);
+ --sandA12: color(display-p3 1 1 0.992 / 0.929);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --sand1: #111110;
+ --sand2: #191918;
+ --sand3: #222221;
+ --sand4: #2a2a28;
+ --sand5: #31312e;
+ --sand6: #3b3a37;
+ --sand7: #494844;
+ --sand8: #62605b;
+ --sand9: #6f6d66;
+ --sand10: #7c7b74;
+ --sand11: #b5b3ad;
+ --sand12: #eeeeec;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --sand1: color(display-p3 0.067 0.067 0.063);
+ --sand2: color(display-p3 0.098 0.098 0.094);
+ --sand3: color(display-p3 0.135 0.135 0.129);
+ --sand4: color(display-p3 0.164 0.163 0.156);
+ --sand5: color(display-p3 0.193 0.192 0.183);
+ --sand6: color(display-p3 0.23 0.229 0.217);
+ --sand7: color(display-p3 0.285 0.282 0.267);
+ --sand8: color(display-p3 0.384 0.378 0.357);
+ --sand9: color(display-p3 0.434 0.428 0.403);
+ --sand10: color(display-p3 0.487 0.481 0.456);
+ --sand11: color(display-p3 0.707 0.703 0.68);
+ --sand12: color(display-p3 0.933 0.933 0.926);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --sand1: #fdfdfc;
+ --sand2: #f9f9f8;
+ --sand3: #f1f0ef;
+ --sand4: #e9e8e6;
+ --sand5: #e2e1de;
+ --sand6: #dad9d6;
+ --sand7: #cfceca;
+ --sand8: #bcbbb5;
+ --sand9: #8d8d86;
+ --sand10: #82827c;
+ --sand11: #63635e;
+ --sand12: #21201c;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --sand1: color(display-p3 0.992 0.992 0.989);
+ --sand2: color(display-p3 0.977 0.977 0.973);
+ --sand3: color(display-p3 0.943 0.942 0.936);
+ --sand4: color(display-p3 0.913 0.912 0.903);
+ --sand5: color(display-p3 0.885 0.883 0.873);
+ --sand6: color(display-p3 0.854 0.852 0.839);
+ --sand7: color(display-p3 0.813 0.81 0.794);
+ --sand8: color(display-p3 0.738 0.734 0.713);
+ --sand9: color(display-p3 0.553 0.553 0.528);
+ --sand10: color(display-p3 0.511 0.511 0.488);
+ --sand11: color(display-p3 0.388 0.388 0.37);
+ --sand12: color(display-p3 0.129 0.126 0.111);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --skyA1: #00d5ff06;
+ --skyA2: #00a4db0e;
+ --skyA3: #00b3ee1e;
+ --skyA4: #00ace42e;
+ --skyA5: #00a1d841;
+ --skyA6: #0092ca56;
+ --skyA7: #0089c172;
+ --skyA8: #0085bf9f;
+ --skyA9: #00c7fe83;
+ --skyA10: #00bcf38b;
+ --skyA11: #00749e;
+ --skyA12: #002540e2;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --skyA1: color(display-p3 0.02 0.804 1 / 0.02);
+ --skyA2: color(display-p3 0.024 0.592 0.757 / 0.048);
+ --skyA3: color(display-p3 0.004 0.655 0.886 / 0.102);
+ --skyA4: color(display-p3 0.004 0.604 0.851 / 0.157);
+ --skyA5: color(display-p3 0.004 0.565 0.792 / 0.224);
+ --skyA6: color(display-p3 0.004 0.502 0.737 / 0.299);
+ --skyA7: color(display-p3 0.004 0.459 0.694 / 0.397);
+ --skyA8: color(display-p3 0 0.435 0.682 / 0.542);
+ --skyA9: color(display-p3 0.004 0.71 0.965 / 0.416);
+ --skyA10: color(display-p3 0.004 0.647 0.914 / 0.444);
+ --skyA11: color(display-p3 0.193 0.448 0.605);
+ --skyA12: color(display-p3 0.145 0.241 0.329);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --skyA1: #0044ff0f;
+ --skyA2: #1171fb18;
+ --skyA3: #1184fc33;
+ --skyA4: #128fff49;
+ --skyA5: #1c9dfd5d;
+ --skyA6: #28a5ff72;
+ --skyA7: #2badfe8b;
+ --skyA8: #1db2fea9;
+ --skyA9: #7ce3fffe;
+ --skyA10: #a8eeff;
+ --skyA11: #7cd3ffef;
+ --skyA12: #c2f3ff;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --skyA1: color(display-p3 0 0.282 0.996 / 0.055);
+ --skyA2: color(display-p3 0.157 0.467 0.992 / 0.089);
+ --skyA3: color(display-p3 0.192 0.522 0.996 / 0.19);
+ --skyA4: color(display-p3 0.212 0.584 1 / 0.274);
+ --skyA5: color(display-p3 0.259 0.631 1 / 0.349);
+ --skyA6: color(display-p3 0.302 0.655 1 / 0.433);
+ --skyA7: color(display-p3 0.329 0.686 1 / 0.526);
+ --skyA8: color(display-p3 0.325 0.71 1 / 0.643);
+ --skyA9: color(display-p3 0.592 0.894 1 / 0.984);
+ --skyA10: color(display-p3 0.722 0.933 1 / 0.992);
+ --skyA11: color(display-p3 0.536 0.772 0.924);
+ --skyA12: color(display-p3 0.799 0.947 0.993);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --sky1: #0d141f;
+ --sky2: #111a27;
+ --sky3: #112840;
+ --sky4: #113555;
+ --sky5: #154467;
+ --sky6: #1b537b;
+ --sky7: #1f6692;
+ --sky8: #197cae;
+ --sky9: #7ce2fe;
+ --sky10: #a8eeff;
+ --sky11: #75c7f0;
+ --sky12: #c2f3ff;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --sky1: color(display-p3 0.056 0.078 0.116);
+ --sky2: color(display-p3 0.075 0.101 0.149);
+ --sky3: color(display-p3 0.089 0.154 0.244);
+ --sky4: color(display-p3 0.106 0.207 0.323);
+ --sky5: color(display-p3 0.135 0.261 0.394);
+ --sky6: color(display-p3 0.17 0.322 0.469);
+ --sky7: color(display-p3 0.205 0.394 0.557);
+ --sky8: color(display-p3 0.232 0.48 0.665);
+ --sky9: color(display-p3 0.585 0.877 0.983);
+ --sky10: color(display-p3 0.718 0.925 0.991);
+ --sky11: color(display-p3 0.536 0.772 0.924);
+ --sky12: color(display-p3 0.799 0.947 0.993);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --sky1: #f9feff;
+ --sky2: #f1fafd;
+ --sky3: #e1f6fd;
+ --sky4: #d1f0fa;
+ --sky5: #bee7f5;
+ --sky6: #a9daed;
+ --sky7: #8dcae3;
+ --sky8: #60b3d7;
+ --sky9: #7ce2fe;
+ --sky10: #74daf8;
+ --sky11: #00749e;
+ --sky12: #1d3e56;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --sky1: color(display-p3 0.98 0.995 0.999);
+ --sky2: color(display-p3 0.953 0.98 0.99);
+ --sky3: color(display-p3 0.899 0.963 0.989);
+ --sky4: color(display-p3 0.842 0.937 0.977);
+ --sky5: color(display-p3 0.777 0.9 0.954);
+ --sky6: color(display-p3 0.701 0.851 0.921);
+ --sky7: color(display-p3 0.604 0.785 0.879);
+ --sky8: color(display-p3 0.457 0.696 0.829);
+ --sky9: color(display-p3 0.585 0.877 0.983);
+ --sky10: color(display-p3 0.555 0.845 0.959);
+ --sky11: color(display-p3 0.193 0.448 0.605);
+ --sky12: color(display-p3 0.145 0.241 0.329);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --slateA1: #00005503;
+ --slateA2: #00005506;
+ --slateA3: #0000330f;
+ --slateA4: #00002d17;
+ --slateA5: #0009321f;
+ --slateA6: #00002f26;
+ --slateA7: #00062e32;
+ --slateA8: #00083046;
+ --slateA9: #00051d74;
+ --slateA10: #00071b7f;
+ --slateA11: #0007149f;
+ --slateA12: #000509e3;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --slateA1: color(display-p3 0.024 0.024 0.349 / 0.012);
+ --slateA2: color(display-p3 0.024 0.024 0.349 / 0.024);
+ --slateA3: color(display-p3 0.004 0.004 0.204 / 0.059);
+ --slateA4: color(display-p3 0.012 0.012 0.184 / 0.091);
+ --slateA5: color(display-p3 0.004 0.039 0.2 / 0.122);
+ --slateA6: color(display-p3 0.008 0.008 0.165 / 0.15);
+ --slateA7: color(display-p3 0.008 0.027 0.184 / 0.197);
+ --slateA8: color(display-p3 0.004 0.031 0.176 / 0.275);
+ --slateA9: color(display-p3 0.004 0.02 0.106 / 0.455);
+ --slateA10: color(display-p3 0.004 0.027 0.098 / 0.499);
+ --slateA11: color(display-p3 0 0.02 0.063 / 0.62);
+ --slateA12: color(display-p3 0 0.012 0.031 / 0.887);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --slateA1: #00000000;
+ --slateA2: #d8f4f609;
+ --slateA3: #ddeaf814;
+ --slateA4: #d3edf81d;
+ --slateA5: #d9edfe25;
+ --slateA6: #d6ebfd30;
+ --slateA7: #d9edff40;
+ --slateA8: #d9edff5d;
+ --slateA9: #dfebfd6d;
+ --slateA10: #e5edfd7b;
+ --slateA11: #f1f7feb5;
+ --slateA12: #fcfdffef;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --slateA1: color(display-p3 0 0 0 / 0);
+ --slateA2: color(display-p3 0.875 0.992 1 / 0.034);
+ --slateA3: color(display-p3 0.882 0.933 0.992 / 0.077);
+ --slateA4: color(display-p3 0.882 0.953 0.996 / 0.111);
+ --slateA5: color(display-p3 0.878 0.929 0.996 / 0.145);
+ --slateA6: color(display-p3 0.882 0.949 0.996 / 0.183);
+ --slateA7: color(display-p3 0.882 0.929 1 / 0.246);
+ --slateA8: color(display-p3 0.871 0.937 1 / 0.361);
+ --slateA9: color(display-p3 0.898 0.937 1 / 0.42);
+ --slateA10: color(display-p3 0.918 0.945 1 / 0.475);
+ --slateA11: color(display-p3 0.949 0.969 0.996 / 0.708);
+ --slateA12: color(display-p3 0.988 0.992 1 / 0.937);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --slate1: #111113;
+ --slate2: #18191b;
+ --slate3: #212225;
+ --slate4: #272a2d;
+ --slate5: #2e3135;
+ --slate6: #363a3f;
+ --slate7: #43484e;
+ --slate8: #5a6169;
+ --slate9: #696e77;
+ --slate10: #777b84;
+ --slate11: #b0b4ba;
+ --slate12: #edeef0;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --slate1: color(display-p3 0.067 0.067 0.074);
+ --slate2: color(display-p3 0.095 0.098 0.105);
+ --slate3: color(display-p3 0.13 0.135 0.145);
+ --slate4: color(display-p3 0.156 0.163 0.176);
+ --slate5: color(display-p3 0.183 0.191 0.206);
+ --slate6: color(display-p3 0.215 0.226 0.244);
+ --slate7: color(display-p3 0.265 0.28 0.302);
+ --slate8: color(display-p3 0.357 0.381 0.409);
+ --slate9: color(display-p3 0.415 0.431 0.463);
+ --slate10: color(display-p3 0.469 0.483 0.514);
+ --slate11: color(display-p3 0.692 0.704 0.728);
+ --slate12: color(display-p3 0.93 0.933 0.94);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --slate1: #fcfcfd;
+ --slate2: #f9f9fb;
+ --slate3: #f0f0f3;
+ --slate4: #e8e8ec;
+ --slate5: #e0e1e6;
+ --slate6: #d9d9e0;
+ --slate7: #cdced6;
+ --slate8: #b9bbc6;
+ --slate9: #8b8d98;
+ --slate10: #80838d;
+ --slate11: #60646c;
+ --slate12: #1c2024;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --slate1: color(display-p3 0.988 0.988 0.992);
+ --slate2: color(display-p3 0.976 0.976 0.984);
+ --slate3: color(display-p3 0.94 0.941 0.953);
+ --slate4: color(display-p3 0.908 0.909 0.925);
+ --slate5: color(display-p3 0.88 0.881 0.901);
+ --slate6: color(display-p3 0.85 0.852 0.876);
+ --slate7: color(display-p3 0.805 0.808 0.838);
+ --slate8: color(display-p3 0.727 0.733 0.773);
+ --slate9: color(display-p3 0.547 0.553 0.592);
+ --slate10: color(display-p3 0.503 0.512 0.549);
+ --slate11: color(display-p3 0.379 0.392 0.421);
+ --slate12: color(display-p3 0.113 0.125 0.14);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --tealA1: #00cc9905;
+ --tealA2: #00aa800c;
+ --tealA3: #00c69d1f;
+ --tealA4: #00c39633;
+ --tealA5: #00b49047;
+ --tealA6: #00a6855e;
+ --tealA7: #0099807c;
+ --tealA8: #009783ac;
+ --tealA9: #009e8ced;
+ --tealA10: #009684f2;
+ --tealA11: #008573;
+ --tealA12: #00332df2;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --tealA1: color(display-p3 0.024 0.757 0.514 / 0.016);
+ --tealA2: color(display-p3 0.02 0.647 0.467 / 0.044);
+ --tealA3: color(display-p3 0.004 0.741 0.557 / 0.106);
+ --tealA4: color(display-p3 0.004 0.702 0.537 / 0.169);
+ --tealA5: color(display-p3 0.004 0.643 0.494 / 0.24);
+ --tealA6: color(display-p3 0.004 0.569 0.447 / 0.318);
+ --tealA7: color(display-p3 0.004 0.518 0.424 / 0.42);
+ --tealA8: color(display-p3 0 0.506 0.424 / 0.569);
+ --tealA9: color(display-p3 0 0.482 0.404 / 0.702);
+ --tealA10: color(display-p3 0 0.451 0.369 / 0.726);
+ --tealA11: color(display-p3 0.08 0.5 0.43);
+ --tealA12: color(display-p3 0.11 0.235 0.219);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --tealA1: #00deab05;
+ --tealA2: #12fbe60c;
+ --tealA3: #00ffe61e;
+ --tealA4: #00ffe92d;
+ --tealA5: #00ffea3b;
+ --tealA6: #1cffe84b;
+ --tealA7: #2efde85f;
+ --tealA8: #32ffe775;
+ --tealA9: #13ffe49f;
+ --tealA10: #0dffe0ae;
+ --tealA11: #0afed5d6;
+ --tealA12: #b8ffebef;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --tealA1: color(display-p3 0 0.992 0.761 / 0.017);
+ --tealA2: color(display-p3 0.235 0.988 0.902 / 0.047);
+ --tealA3: color(display-p3 0.235 1 0.898 / 0.118);
+ --tealA4: color(display-p3 0.18 0.996 0.929 / 0.173);
+ --tealA5: color(display-p3 0.31 1 0.933 / 0.227);
+ --tealA6: color(display-p3 0.396 1 0.933 / 0.286);
+ --tealA7: color(display-p3 0.443 1 0.925 / 0.366);
+ --tealA8: color(display-p3 0.459 1 0.925 / 0.454);
+ --tealA9: color(display-p3 0.443 0.996 0.906 / 0.61);
+ --tealA10: color(display-p3 0.439 0.996 0.89 / 0.669);
+ --tealA11: color(display-p3 0.388 0.835 0.719);
+ --tealA12: color(display-p3 0.734 0.934 0.87);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --teal1: #0d1514;
+ --teal2: #111c1b;
+ --teal3: #0d2d2a;
+ --teal4: #023b37;
+ --teal5: #084843;
+ --teal6: #145750;
+ --teal7: #1c6961;
+ --teal8: #207e73;
+ --teal9: #12a594;
+ --teal10: #0eb39e;
+ --teal11: #0bd8b6;
+ --teal12: #adf0dd;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --teal1: color(display-p3 0.059 0.083 0.079);
+ --teal2: color(display-p3 0.075 0.11 0.107);
+ --teal3: color(display-p3 0.087 0.175 0.165);
+ --teal4: color(display-p3 0.087 0.227 0.214);
+ --teal5: color(display-p3 0.12 0.277 0.261);
+ --teal6: color(display-p3 0.162 0.335 0.314);
+ --teal7: color(display-p3 0.205 0.406 0.379);
+ --teal8: color(display-p3 0.245 0.489 0.453);
+ --teal9: color(display-p3 0.297 0.637 0.581);
+ --teal10: color(display-p3 0.319 0.69 0.62);
+ --teal11: color(display-p3 0.388 0.835 0.719);
+ --teal12: color(display-p3 0.734 0.934 0.87);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --teal1: #fafefd;
+ --teal2: #f3fbf9;
+ --teal3: #e0f8f3;
+ --teal4: #ccf3ea;
+ --teal5: #b8eae0;
+ --teal6: #a1ded2;
+ --teal7: #83cdc1;
+ --teal8: #53b9ab;
+ --teal9: #12a594;
+ --teal10: #0d9b8a;
+ --teal11: #008573;
+ --teal12: #0d3d38;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --teal1: color(display-p3 0.983 0.996 0.992);
+ --teal2: color(display-p3 0.958 0.983 0.976);
+ --teal3: color(display-p3 0.895 0.971 0.952);
+ --teal4: color(display-p3 0.831 0.949 0.92);
+ --teal5: color(display-p3 0.761 0.914 0.878);
+ --teal6: color(display-p3 0.682 0.864 0.825);
+ --teal7: color(display-p3 0.581 0.798 0.756);
+ --teal8: color(display-p3 0.433 0.716 0.671);
+ --teal9: color(display-p3 0.297 0.637 0.581);
+ --teal10: color(display-p3 0.275 0.599 0.542);
+ --teal11: color(display-p3 0.08 0.5 0.43);
+ --teal12: color(display-p3 0.11 0.235 0.219);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --tomatoA1: #ff000003;
+ --tomatoA2: #ff200008;
+ --tomatoA3: #f52b0018;
+ --tomatoA4: #ff35002c;
+ --tomatoA5: #ff2e003d;
+ --tomatoA6: #f92d0050;
+ --tomatoA7: #e7280067;
+ --tomatoA8: #db250084;
+ --tomatoA9: #df2600d1;
+ --tomatoA10: #d72400da;
+ --tomatoA11: #cd2200ea;
+ --tomatoA12: #460900e0;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --tomatoA1: color(display-p3 0.675 0.024 0.024 / 0.012);
+ --tomatoA2: color(display-p3 0.757 0.145 0.02 / 0.032);
+ --tomatoA3: color(display-p3 0.831 0.184 0.012 / 0.091);
+ --tomatoA4: color(display-p3 0.976 0.192 0.004 / 0.165);
+ --tomatoA5: color(display-p3 0.918 0.192 0.004 / 0.232);
+ --tomatoA6: color(display-p3 0.847 0.173 0.004 / 0.302);
+ --tomatoA7: color(display-p3 0.788 0.165 0.004 / 0.389);
+ --tomatoA8: color(display-p3 0.749 0.153 0.004 / 0.499);
+ --tomatoA9: color(display-p3 0.78 0.149 0 / 0.769);
+ --tomatoA10: color(display-p3 0.757 0.141 0 / 0.8);
+ --tomatoA11: color(display-p3 0.755 0.259 0.152);
+ --tomatoA12: color(display-p3 0.335 0.165 0.132);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --tomatoA1: #f1121208;
+ --tomatoA2: #ff55330f;
+ --tomatoA3: #ff35232b;
+ --tomatoA4: #fd201142;
+ --tomatoA5: #fe332153;
+ --tomatoA6: #ff4f3864;
+ --tomatoA7: #fd644a7d;
+ --tomatoA8: #fe6d4ea7;
+ --tomatoA9: #fe5431e4;
+ --tomatoA10: #ff6847eb;
+ --tomatoA11: #ff977d;
+ --tomatoA12: #ffd6cefb;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --tomatoA1: color(display-p3 0.973 0.071 0.071 / 0.026);
+ --tomatoA2: color(display-p3 0.992 0.376 0.224 / 0.051);
+ --tomatoA3: color(display-p3 0.996 0.282 0.176 / 0.148);
+ --tomatoA4: color(display-p3 1 0.204 0.118 / 0.232);
+ --tomatoA5: color(display-p3 1 0.286 0.192 / 0.29);
+ --tomatoA6: color(display-p3 1 0.392 0.278 / 0.353);
+ --tomatoA7: color(display-p3 1 0.459 0.349 / 0.45);
+ --tomatoA8: color(display-p3 1 0.49 0.369 / 0.601);
+ --tomatoA9: color(display-p3 1 0.408 0.267 / 0.82);
+ --tomatoA10: color(display-p3 1 0.478 0.341 / 0.853);
+ --tomatoA11: color(display-p3 1 0.585 0.455);
+ --tomatoA12: color(display-p3 0.959 0.833 0.802);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --tomato1: #181111;
+ --tomato2: #1f1513;
+ --tomato3: #391714;
+ --tomato4: #4e1511;
+ --tomato5: #5e1c16;
+ --tomato6: #6e2920;
+ --tomato7: #853a2d;
+ --tomato8: #ac4d39;
+ --tomato9: #e54d2e;
+ --tomato10: #ec6142;
+ --tomato11: #ff977d;
+ --tomato12: #fbd3cb;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --tomato1: color(display-p3 0.09 0.068 0.067);
+ --tomato2: color(display-p3 0.115 0.084 0.076);
+ --tomato3: color(display-p3 0.205 0.097 0.083);
+ --tomato4: color(display-p3 0.282 0.099 0.077);
+ --tomato5: color(display-p3 0.339 0.129 0.101);
+ --tomato6: color(display-p3 0.398 0.179 0.141);
+ --tomato7: color(display-p3 0.487 0.245 0.194);
+ --tomato8: color(display-p3 0.629 0.322 0.248);
+ --tomato9: color(display-p3 0.831 0.345 0.231);
+ --tomato10: color(display-p3 0.862 0.415 0.298);
+ --tomato11: color(display-p3 1 0.585 0.455);
+ --tomato12: color(display-p3 0.959 0.833 0.802);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --tomato1: #fffcfc;
+ --tomato2: #fff8f7;
+ --tomato3: #feebe7;
+ --tomato4: #ffdcd3;
+ --tomato5: #ffcdc2;
+ --tomato6: #fdbdaf;
+ --tomato7: #f5a898;
+ --tomato8: #ec8e7b;
+ --tomato9: #e54d2e;
+ --tomato10: #dd4425;
+ --tomato11: #d13415;
+ --tomato12: #5c271f;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --tomato1: color(display-p3 0.998 0.989 0.988);
+ --tomato2: color(display-p3 0.994 0.974 0.969);
+ --tomato3: color(display-p3 0.985 0.924 0.909);
+ --tomato4: color(display-p3 0.996 0.868 0.835);
+ --tomato5: color(display-p3 0.98 0.812 0.77);
+ --tomato6: color(display-p3 0.953 0.75 0.698);
+ --tomato7: color(display-p3 0.917 0.673 0.611);
+ --tomato8: color(display-p3 0.875 0.575 0.502);
+ --tomato9: color(display-p3 0.831 0.345 0.231);
+ --tomato10: color(display-p3 0.802 0.313 0.2);
+ --tomato11: color(display-p3 0.755 0.259 0.152);
+ --tomato12: color(display-p3 0.335 0.165 0.132);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --violetA1: #5500aa03;
+ --violetA2: #4900ff07;
+ --violetA3: #4400ee0f;
+ --violetA4: #4300ff1b;
+ --violetA5: #3600ff26;
+ --violetA6: #3100fb35;
+ --violetA7: #2d01dd4a;
+ --violetA8: #2b00d066;
+ --violetA9: #2400b7a9;
+ --violetA10: #2300abb2;
+ --violetA11: #1f0099af;
+ --violetA12: #0b0043d9;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --violetA1: color(display-p3 0.349 0.024 0.675 / 0.012);
+ --violetA2: color(display-p3 0.161 0.024 0.863 / 0.028);
+ --violetA3: color(display-p3 0.204 0.004 0.871 / 0.059);
+ --violetA4: color(display-p3 0.196 0.004 1 / 0.102);
+ --violetA5: color(display-p3 0.165 0.008 1 / 0.15);
+ --violetA6: color(display-p3 0.153 0.004 0.906 / 0.208);
+ --violetA7: color(display-p3 0.141 0.004 0.796 / 0.287);
+ --violetA8: color(display-p3 0.133 0.004 0.753 / 0.397);
+ --violetA9: color(display-p3 0.114 0 0.675 / 0.659);
+ --violetA10: color(display-p3 0.11 0 0.627 / 0.695);
+ --violetA11: color(display-p3 0.383 0.317 0.702);
+ --violetA12: color(display-p3 0.179 0.15 0.359);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --violetA1: #4422ff0f;
+ --violetA2: #853ff916;
+ --violetA3: #8354fe36;
+ --violetA4: #7d51fd50;
+ --violetA5: #845ffd5f;
+ --violetA6: #8f6cfd6d;
+ --violetA7: #9879ff83;
+ --violetA8: #977dfea8;
+ --violetA9: #8668ffcc;
+ --violetA10: #9176fed7;
+ --violetA11: #baa7ff;
+ --violetA12: #e3defffe;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --violetA1: color(display-p3 0.282 0.141 0.996 / 0.055);
+ --violetA2: color(display-p3 0.51 0.263 1 / 0.08);
+ --violetA3: color(display-p3 0.494 0.337 0.996 / 0.202);
+ --violetA4: color(display-p3 0.49 0.345 1 / 0.299);
+ --violetA5: color(display-p3 0.525 0.392 1 / 0.353);
+ --violetA6: color(display-p3 0.569 0.455 1 / 0.408);
+ --violetA7: color(display-p3 0.588 0.494 1 / 0.496);
+ --violetA8: color(display-p3 0.596 0.51 1 / 0.631);
+ --violetA9: color(display-p3 0.522 0.424 1 / 0.769);
+ --violetA10: color(display-p3 0.576 0.482 1 / 0.811);
+ --violetA11: color(display-p3 0.72 0.65 1);
+ --violetA12: color(display-p3 0.883 0.867 0.986);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --violet1: #14121f;
+ --violet2: #1b1525;
+ --violet3: #291f43;
+ --violet4: #33255b;
+ --violet5: #3c2e69;
+ --violet6: #473876;
+ --violet7: #56468b;
+ --violet8: #6958ad;
+ --violet9: #6e56cf;
+ --violet10: #7d66d9;
+ --violet11: #baa7ff;
+ --violet12: #e2ddfe;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --violet1: color(display-p3 0.077 0.071 0.118);
+ --violet2: color(display-p3 0.101 0.084 0.141);
+ --violet3: color(display-p3 0.154 0.123 0.256);
+ --violet4: color(display-p3 0.191 0.148 0.345);
+ --violet5: color(display-p3 0.226 0.182 0.396);
+ --violet6: color(display-p3 0.269 0.223 0.449);
+ --violet7: color(display-p3 0.326 0.277 0.53);
+ --violet8: color(display-p3 0.399 0.346 0.656);
+ --violet9: color(display-p3 0.417 0.341 0.784);
+ --violet10: color(display-p3 0.477 0.402 0.823);
+ --violet11: color(display-p3 0.72 0.65 1);
+ --violet12: color(display-p3 0.883 0.867 0.986);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --violet1: #fdfcfe;
+ --violet2: #faf8ff;
+ --violet3: #f4f0fe;
+ --violet4: #ebe4ff;
+ --violet5: #e1d9ff;
+ --violet6: #d4cafe;
+ --violet7: #c2b5f5;
+ --violet8: #aa99ec;
+ --violet9: #6e56cf;
+ --violet10: #654dc4;
+ --violet11: #6550b9;
+ --violet12: #2f265f;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --violet1: color(display-p3 0.991 0.988 0.995);
+ --violet2: color(display-p3 0.978 0.974 0.998);
+ --violet3: color(display-p3 0.953 0.943 0.993);
+ --violet4: color(display-p3 0.916 0.897 1);
+ --violet5: color(display-p3 0.876 0.851 1);
+ --violet6: color(display-p3 0.825 0.793 0.981);
+ --violet7: color(display-p3 0.752 0.712 0.943);
+ --violet8: color(display-p3 0.654 0.602 0.902);
+ --violet9: color(display-p3 0.417 0.341 0.784);
+ --violet10: color(display-p3 0.381 0.306 0.741);
+ --violet11: color(display-p3 0.383 0.317 0.702);
+ --violet12: color(display-p3 0.179 0.15 0.359);
+ }
+ }
+}
+
+:root {
+ --whiteA1: rgba(255, 255, 255, 0.05);
+ --whiteA2: rgba(255, 255, 255, 0.1);
+ --whiteA3: rgba(255, 255, 255, 0.15);
+ --whiteA4: rgba(255, 255, 255, 0.2);
+ --whiteA5: rgba(255, 255, 255, 0.3);
+ --whiteA6: rgba(255, 255, 255, 0.4);
+ --whiteA7: rgba(255, 255, 255, 0.5);
+ --whiteA8: rgba(255, 255, 255, 0.6);
+ --whiteA9: rgba(255, 255, 255, 0.7);
+ --whiteA10: rgba(255, 255, 255, 0.8);
+ --whiteA11: rgba(255, 255, 255, 0.9);
+ --whiteA12: rgba(255, 255, 255, 0.95);
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root {
+ --whiteA1: color(display-p3 1 1 1 / 0.05);
+ --whiteA2: color(display-p3 1 1 1 / 0.1);
+ --whiteA3: color(display-p3 1 1 1 / 0.15);
+ --whiteA4: color(display-p3 1 1 1 / 0.2);
+ --whiteA5: color(display-p3 1 1 1 / 0.3);
+ --whiteA6: color(display-p3 1 1 1 / 0.4);
+ --whiteA7: color(display-p3 1 1 1 / 0.5);
+ --whiteA8: color(display-p3 1 1 1 / 0.6);
+ --whiteA9: color(display-p3 1 1 1 / 0.7);
+ --whiteA10: color(display-p3 1 1 1 / 0.8);
+ --whiteA11: color(display-p3 1 1 1 / 0.9);
+ --whiteA12: color(display-p3 1 1 1 / 0.95);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --yellowA1: #aaaa0006;
+ --yellowA2: #f4dd0016;
+ --yellowA3: #ffee0047;
+ --yellowA4: #ffe3016b;
+ --yellowA5: #ffd5008f;
+ --yellowA6: #ebbc0097;
+ --yellowA7: #d2a10098;
+ --yellowA8: #c99700c6;
+ --yellowA9: #ffe100d6;
+ --yellowA10: #ffdc00;
+ --yellowA11: #9e6c00;
+ --yellowA12: #2e2000e0;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --yellowA1: color(display-p3 0.675 0.675 0.024 / 0.024);
+ --yellowA2: color(display-p3 0.953 0.855 0.008 / 0.079);
+ --yellowA3: color(display-p3 0.988 0.925 0.004 / 0.251);
+ --yellowA4: color(display-p3 0.98 0.875 0.004 / 0.373);
+ --yellowA5: color(display-p3 0.969 0.816 0.004 / 0.491);
+ --yellowA6: color(display-p3 0.875 0.71 0 / 0.526);
+ --yellowA7: color(display-p3 0.769 0.604 0 / 0.542);
+ --yellowA8: color(display-p3 0.725 0.549 0 / 0.687);
+ --yellowA9: color(display-p3 1 0.898 0 / 0.781);
+ --yellowA10: color(display-p3 0.969 0.812 0 / 0.71);
+ --yellowA11: color(display-p3 0.6 0.44 0);
+ --yellowA12: color(display-p3 0.271 0.233 0.137);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --yellowA1: #d1510004;
+ --yellowA2: #f9b4000b;
+ --yellowA3: #ffaa001e;
+ --yellowA4: #fdb70028;
+ --yellowA5: #febb0036;
+ --yellowA6: #fec40046;
+ --yellowA7: #fdcb225c;
+ --yellowA8: #fdca327b;
+ --yellowA9: #ffe629;
+ --yellowA10: #ffff57;
+ --yellowA11: #fee949f5;
+ --yellowA12: #fef6baf6;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --yellowA1: color(display-p3 0.973 0.369 0 / 0.013);
+ --yellowA2: color(display-p3 0.996 0.792 0 / 0.038);
+ --yellowA3: color(display-p3 0.996 0.71 0 / 0.11);
+ --yellowA4: color(display-p3 0.996 0.741 0 / 0.152);
+ --yellowA5: color(display-p3 0.996 0.765 0 / 0.202);
+ --yellowA6: color(display-p3 0.996 0.816 0.082 / 0.261);
+ --yellowA7: color(display-p3 1 0.831 0.263 / 0.345);
+ --yellowA8: color(display-p3 1 0.831 0.314 / 0.463);
+ --yellowA9: color(display-p3 1 0.922 0.22);
+ --yellowA10: color(display-p3 1 1 0.455);
+ --yellowA11: color(display-p3 0.948 0.885 0.392);
+ --yellowA12: color(display-p3 0.959 0.934 0.731);
+ }
+ }
+}
+
+.dark,
+.dark-theme {
+ --yellow1: #14120b;
+ --yellow2: #1b180f;
+ --yellow3: #2d2305;
+ --yellow4: #362b00;
+ --yellow5: #433500;
+ --yellow6: #524202;
+ --yellow7: #665417;
+ --yellow8: #836a21;
+ --yellow9: #ffe629;
+ --yellow10: #ffff57;
+ --yellow11: #f5e147;
+ --yellow12: #f6eeb4;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ .dark,
+ .dark-theme {
+ --yellow1: color(display-p3 0.078 0.069 0.047);
+ --yellow2: color(display-p3 0.103 0.094 0.063);
+ --yellow3: color(display-p3 0.168 0.137 0.039);
+ --yellow4: color(display-p3 0.209 0.169 0);
+ --yellow5: color(display-p3 0.255 0.209 0);
+ --yellow6: color(display-p3 0.31 0.261 0.07);
+ --yellow7: color(display-p3 0.389 0.331 0.135);
+ --yellow8: color(display-p3 0.497 0.42 0.182);
+ --yellow9: color(display-p3 1 0.92 0.22);
+ --yellow10: color(display-p3 1 1 0.456);
+ --yellow11: color(display-p3 0.948 0.885 0.392);
+ --yellow12: color(display-p3 0.959 0.934 0.731);
+ }
+ }
+}
+
+:root,
+.light,
+.light-theme {
+ --yellow1: #fdfdf9;
+ --yellow2: #fefce9;
+ --yellow3: #fffab8;
+ --yellow4: #fff394;
+ --yellow5: #ffe770;
+ --yellow6: #f3d768;
+ --yellow7: #e4c767;
+ --yellow8: #d5ae39;
+ --yellow9: #ffe629;
+ --yellow10: #ffdc00;
+ --yellow11: #9e6c00;
+ --yellow12: #473b1f;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root,
+ .light,
+ .light-theme {
+ --yellow1: color(display-p3 0.992 0.992 0.978);
+ --yellow2: color(display-p3 0.995 0.99 0.922);
+ --yellow3: color(display-p3 0.997 0.982 0.749);
+ --yellow4: color(display-p3 0.992 0.953 0.627);
+ --yellow5: color(display-p3 0.984 0.91 0.51);
+ --yellow6: color(display-p3 0.934 0.847 0.474);
+ --yellow7: color(display-p3 0.876 0.785 0.46);
+ --yellow8: color(display-p3 0.811 0.689 0.313);
+ --yellow9: color(display-p3 1 0.92 0.22);
+ --yellow10: color(display-p3 0.977 0.868 0.291);
+ --yellow11: color(display-p3 0.6 0.44 0);
+ --yellow12: color(display-p3 0.271 0.233 0.137);
+ }
+ }
+}
+
+@tailwind components;
+
+@tailwind utilities;
+
+@tailwind base;
+
+:root {
+ /* --background: 0 0% 100%;
+ --foreground: 222.2 47.4% 11.2%;
+ --muted: 210 40% 96.1%;
+ --muted-foreground: 215.4 16.3% 46.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 222.2 47.4% 11.2%;
+ --popover: var(--red9);
+ --popover-foreground: 222.2 47.4% 11.2%;
+ --border: 214.3 31.8% 91.4%;
+ --input: 214.3 31.8% 91.4%;
+ --primary: 222.2 47.4% 11.2%;
+ --primary-foreground: 210 40% 98%;
+ --secondary: 210 40% 96.1%;
+ --secondary-foreground: 222.2 47.4% 11.2%;
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
+ --destructive: 0 100% 50%;
+ --destructive-foreground: 210 40% 98%;
+ --ring: 215 20.2% 65.1%;
+ --radius: 0.5rem; */
+}
+
+[data-accent-color='amber'] {
+ --accent1: var(--amber1);
+ --accent2: var(--amber2);
+ --accent3: var(--amber3);
+ --accent4: var(--amber4);
+ --accent5: var(--amber5);
+ --accent6: var(--amber6);
+ --accent7: var(--amber7);
+ --accent8: var(--amber8);
+ --accent9: var(--amber9);
+ --accent10: var(--amber10);
+ --accent11: var(--amber11);
+ --accent12: var(--amber12);
+ --accentA1: var(--amberA1);
+ --accentA2: var(--amberA2);
+ --accentA3: var(--amberA3);
+ --accentA4: var(--amberA4);
+ --accentA5: var(--amberA5);
+ --accentA6: var(--amberA6);
+ --accentA7: var(--amberA7);
+ --accentA8: var(--amberA8);
+ --accentA9: var(--amberA9);
+ --accentA10: var(--amberA10);
+ --accentA11: var(--amberA11);
+ --accentA12: var(--amberA12);
+}
+
+[data-accent-color='blue'] {
+ --accent1: var(--blue1);
+ --accent2: var(--blue2);
+ --accent3: var(--blue3);
+ --accent4: var(--blue4);
+ --accent5: var(--blue5);
+ --accent6: var(--blue6);
+ --accent7: var(--blue7);
+ --accent8: var(--blue8);
+ --accent9: var(--blue9);
+ --accent10: var(--blue10);
+ --accent11: var(--blue11);
+ --accent12: var(--blue12);
+ --accentA1: var(--blueA1);
+ --accentA2: var(--blueA2);
+ --accentA3: var(--blueA3);
+ --accentA4: var(--blueA4);
+ --accentA5: var(--blueA5);
+ --accentA6: var(--blueA6);
+ --accentA7: var(--blueA7);
+ --accentA8: var(--blueA8);
+ --accentA9: var(--blueA9);
+ --accentA10: var(--blueA10);
+ --accentA11: var(--blueA11);
+ --accentA12: var(--blueA12);
+}
+
+[data-accent-color='bronze'] {
+ --accent1: var(--bronze1);
+ --accent2: var(--bronze2);
+ --accent3: var(--bronze3);
+ --accent4: var(--bronze4);
+ --accent5: var(--bronze5);
+ --accent6: var(--bronze6);
+ --accent7: var(--bronze7);
+ --accent8: var(--bronze8);
+ --accent9: var(--bronze9);
+ --accent10: var(--bronze10);
+ --accent11: var(--bronze11);
+ --accent12: var(--bronze12);
+ --accentA1: var(--bronzeA1);
+ --accentA2: var(--bronzeA2);
+ --accentA3: var(--bronzeA3);
+ --accentA4: var(--bronzeA4);
+ --accentA5: var(--bronzeA5);
+ --accentA6: var(--bronzeA6);
+ --accentA7: var(--bronzeA7);
+ --accentA8: var(--bronzeA8);
+ --accentA9: var(--bronzeA9);
+ --accentA10: var(--bronzeA10);
+ --accentA11: var(--bronzeA11);
+ --accentA12: var(--bronzeA12);
+}
+
+[data-accent-color='brown'] {
+ --accent1: var(--brown1);
+ --accent2: var(--brown2);
+ --accent3: var(--brown3);
+ --accent4: var(--brown4);
+ --accent5: var(--brown5);
+ --accent6: var(--brown6);
+ --accent7: var(--brown7);
+ --accent8: var(--brown8);
+ --accent9: var(--brown9);
+ --accent10: var(--brown10);
+ --accent11: var(--brown11);
+ --accent12: var(--brown12);
+ --accentA1: var(--brownA1);
+ --accentA2: var(--brownA2);
+ --accentA3: var(--brownA3);
+ --accentA4: var(--brownA4);
+ --accentA5: var(--brownA5);
+ --accentA6: var(--brownA6);
+ --accentA7: var(--brownA7);
+ --accentA8: var(--brownA8);
+ --accentA9: var(--brownA9);
+ --accentA10: var(--brownA10);
+ --accentA11: var(--brownA11);
+ --accentA12: var(--brownA12);
+}
+
+[data-accent-color='crimson'] {
+ --accent1: var(--crimson1);
+ --accent2: var(--crimson2);
+ --accent3: var(--crimson3);
+ --accent4: var(--crimson4);
+ --accent5: var(--crimson5);
+ --accent6: var(--crimson6);
+ --accent7: var(--crimson7);
+ --accent8: var(--crimson8);
+ --accent9: var(--crimson9);
+ --accent10: var(--crimson10);
+ --accent11: var(--crimson11);
+ --accent12: var(--crimson12);
+ --accentA1: var(--crimsonA1);
+ --accentA2: var(--crimsonA2);
+ --accentA3: var(--crimsonA3);
+ --accentA4: var(--crimsonA4);
+ --accentA5: var(--crimsonA5);
+ --accentA6: var(--crimsonA6);
+ --accentA7: var(--crimsonA7);
+ --accentA8: var(--crimsonA8);
+ --accentA9: var(--crimsonA9);
+ --accentA10: var(--crimsonA10);
+ --accentA11: var(--crimsonA11);
+ --accentA12: var(--crimsonA12);
+}
+
+[data-accent-color='cyan'] {
+ --accent1: var(--cyan1);
+ --accent2: var(--cyan2);
+ --accent3: var(--cyan3);
+ --accent4: var(--cyan4);
+ --accent5: var(--cyan5);
+ --accent6: var(--cyan6);
+ --accent7: var(--cyan7);
+ --accent8: var(--cyan8);
+ --accent9: var(--cyan9);
+ --accent10: var(--cyan10);
+ --accent11: var(--cyan11);
+ --accent12: var(--cyan12);
+ --accentA1: var(--cyanA1);
+ --accentA2: var(--cyanA2);
+ --accentA3: var(--cyanA3);
+ --accentA4: var(--cyanA4);
+ --accentA5: var(--cyanA5);
+ --accentA6: var(--cyanA6);
+ --accentA7: var(--cyanA7);
+ --accentA8: var(--cyanA8);
+ --accentA9: var(--cyanA9);
+ --accentA10: var(--cyanA10);
+ --accentA11: var(--cyanA11);
+ --accentA12: var(--cyanA12);
+}
+
+[data-accent-color='gold'] {
+ --accent1: var(--gold1);
+ --accent2: var(--gold2);
+ --accent3: var(--gold3);
+ --accent4: var(--gold4);
+ --accent5: var(--gold5);
+ --accent6: var(--gold6);
+ --accent7: var(--gold7);
+ --accent8: var(--gold8);
+ --accent9: var(--gold9);
+ --accent10: var(--gold10);
+ --accent11: var(--gold11);
+ --accent12: var(--gold12);
+ --accentA1: var(--goldA1);
+ --accentA2: var(--goldA2);
+ --accentA3: var(--goldA3);
+ --accentA4: var(--goldA4);
+ --accentA5: var(--goldA5);
+ --accentA6: var(--goldA6);
+ --accentA7: var(--goldA7);
+ --accentA8: var(--goldA8);
+ --accentA9: var(--goldA9);
+ --accentA10: var(--goldA10);
+ --accentA11: var(--goldA11);
+ --accentA12: var(--goldA12);
+}
+
+[data-accent-color='grass'] {
+ --accent1: var(--grass1);
+ --accent2: var(--grass2);
+ --accent3: var(--grass3);
+ --accent4: var(--grass4);
+ --accent5: var(--grass5);
+ --accent6: var(--grass6);
+ --accent7: var(--grass7);
+ --accent8: var(--grass8);
+ --accent9: var(--grass9);
+ --accent10: var(--grass10);
+ --accent11: var(--grass11);
+ --accent12: var(--grass12);
+ --accentA1: var(--grassA1);
+ --accentA2: var(--grassA2);
+ --accentA3: var(--grassA3);
+ --accentA4: var(--grassA4);
+ --accentA5: var(--grassA5);
+ --accentA6: var(--grassA6);
+ --accentA7: var(--grassA7);
+ --accentA8: var(--grassA8);
+ --accentA9: var(--grassA9);
+ --accentA10: var(--grassA10);
+ --accentA11: var(--grassA11);
+ --accentA12: var(--grassA12);
+}
+
+[data-accent-color='gray'] {
+ --accent1: var(--gray1);
+ --accent2: var(--gray2);
+ --accent3: var(--gray3);
+ --accent4: var(--gray4);
+ --accent5: var(--gray5);
+ --accent6: var(--gray6);
+ --accent7: var(--gray7);
+ --accent8: var(--gray8);
+ --accent9: var(--gray9);
+ --accent10: var(--gray10);
+ --accent11: var(--gray11);
+ --accent12: var(--gray12);
+ --accentA1: var(--grayA1);
+ --accentA2: var(--grayA2);
+ --accentA3: var(--grayA3);
+ --accentA4: var(--grayA4);
+ --accentA5: var(--grayA5);
+ --accentA6: var(--grayA6);
+ --accentA7: var(--grayA7);
+ --accentA8: var(--grayA8);
+ --accentA9: var(--grayA9);
+ --accentA10: var(--grayA10);
+ --accentA11: var(--grayA11);
+ --accentA12: var(--grayA12);
+}
+
+[data-accent-color='green'] {
+ --accent1: var(--green1);
+ --accent2: var(--green2);
+ --accent3: var(--green3);
+ --accent4: var(--green4);
+ --accent5: var(--green5);
+ --accent6: var(--green6);
+ --accent7: var(--green7);
+ --accent8: var(--green8);
+ --accent9: var(--green9);
+ --accent10: var(--green10);
+ --accent11: var(--green11);
+ --accent12: var(--green12);
+ --accentA1: var(--greenA1);
+ --accentA2: var(--greenA2);
+ --accentA3: var(--greenA3);
+ --accentA4: var(--greenA4);
+ --accentA5: var(--greenA5);
+ --accentA6: var(--greenA6);
+ --accentA7: var(--greenA7);
+ --accentA8: var(--greenA8);
+ --accentA9: var(--greenA9);
+ --accentA10: var(--greenA10);
+ --accentA11: var(--greenA11);
+ --accentA12: var(--greenA12);
+}
+
+[data-accent-color='indigo'] {
+ --accent1: var(--indigo1);
+ --accent2: var(--indigo2);
+ --accent3: var(--indigo3);
+ --accent4: var(--indigo4);
+ --accent5: var(--indigo5);
+ --accent6: var(--indigo6);
+ --accent7: var(--indigo7);
+ --accent8: var(--indigo8);
+ --accent9: var(--indigo9);
+ --accent10: var(--indigo10);
+ --accent11: var(--indigo11);
+ --accent12: var(--indigo12);
+ --accentA1: var(--indigoA1);
+ --accentA2: var(--indigoA2);
+ --accentA3: var(--indigoA3);
+ --accentA4: var(--indigoA4);
+ --accentA5: var(--indigoA5);
+ --accentA6: var(--indigoA6);
+ --accentA7: var(--indigoA7);
+ --accentA8: var(--indigoA8);
+ --accentA9: var(--indigoA9);
+ --accentA10: var(--indigoA10);
+ --accentA11: var(--indigoA11);
+ --accentA12: var(--indigoA12);
+}
+
+[data-accent-color='iris'] {
+ --accent1: var(--iris1);
+ --accent2: var(--iris2);
+ --accent3: var(--iris3);
+ --accent4: var(--iris4);
+ --accent5: var(--iris5);
+ --accent6: var(--iris6);
+ --accent7: var(--iris7);
+ --accent8: var(--iris8);
+ --accent9: var(--iris9);
+ --accent10: var(--iris10);
+ --accent11: var(--iris11);
+ --accent12: var(--iris12);
+ --accentA1: var(--irisA1);
+ --accentA2: var(--irisA2);
+ --accentA3: var(--irisA3);
+ --accentA4: var(--irisA4);
+ --accentA5: var(--irisA5);
+ --accentA6: var(--irisA6);
+ --accentA7: var(--irisA7);
+ --accentA8: var(--irisA8);
+ --accentA9: var(--irisA9);
+ --accentA10: var(--irisA10);
+ --accentA11: var(--irisA11);
+ --accentA12: var(--irisA12);
+}
+
+[data-accent-color='jade'] {
+ --accent1: var(--jade1);
+ --accent2: var(--jade2);
+ --accent3: var(--jade3);
+ --accent4: var(--jade4);
+ --accent5: var(--jade5);
+ --accent6: var(--jade6);
+ --accent7: var(--jade7);
+ --accent8: var(--jade8);
+ --accent9: var(--jade9);
+ --accent10: var(--jade10);
+ --accent11: var(--jade11);
+ --accent12: var(--jade12);
+ --accentA1: var(--jadeA1);
+ --accentA2: var(--jadeA2);
+ --accentA3: var(--jadeA3);
+ --accentA4: var(--jadeA4);
+ --accentA5: var(--jadeA5);
+ --accentA6: var(--jadeA6);
+ --accentA7: var(--jadeA7);
+ --accentA8: var(--jadeA8);
+ --accentA9: var(--jadeA9);
+ --accentA10: var(--jadeA10);
+ --accentA11: var(--jadeA11);
+ --accentA12: var(--jadeA12);
+}
+
+[data-accent-color='lime'] {
+ --accent1: var(--lime1);
+ --accent2: var(--lime2);
+ --accent3: var(--lime3);
+ --accent4: var(--lime4);
+ --accent5: var(--lime5);
+ --accent6: var(--lime6);
+ --accent7: var(--lime7);
+ --accent8: var(--lime8);
+ --accent9: var(--lime9);
+ --accent10: var(--lime10);
+ --accent11: var(--lime11);
+ --accent12: var(--lime12);
+ --accentA1: var(--limeA1);
+ --accentA2: var(--limeA2);
+ --accentA3: var(--limeA3);
+ --accentA4: var(--limeA4);
+ --accentA5: var(--limeA5);
+ --accentA6: var(--limeA6);
+ --accentA7: var(--limeA7);
+ --accentA8: var(--limeA8);
+ --accentA9: var(--limeA9);
+ --accentA10: var(--limeA10);
+ --accentA11: var(--limeA11);
+ --accentA12: var(--limeA12);
+}
+
+[data-accent-color='mint'] {
+ --accent1: var(--mint1);
+ --accent2: var(--mint2);
+ --accent3: var(--mint3);
+ --accent4: var(--mint4);
+ --accent5: var(--mint5);
+ --accent6: var(--mint6);
+ --accent7: var(--mint7);
+ --accent8: var(--mint8);
+ --accent9: var(--mint9);
+ --accent10: var(--mint10);
+ --accent11: var(--mint11);
+ --accent12: var(--mint12);
+ --accentA1: var(--mintA1);
+ --accentA2: var(--mintA2);
+ --accentA3: var(--mintA3);
+ --accentA4: var(--mintA4);
+ --accentA5: var(--mintA5);
+ --accentA6: var(--mintA6);
+ --accentA7: var(--mintA7);
+ --accentA8: var(--mintA8);
+ --accentA9: var(--mintA9);
+ --accentA10: var(--mintA10);
+ --accentA11: var(--mintA11);
+ --accentA12: var(--mintA12);
+}
+
+[data-accent-color='orange'] {
+ --accent1: var(--orange1);
+ --accent2: var(--orange2);
+ --accent3: var(--orange3);
+ --accent4: var(--orange4);
+ --accent5: var(--orange5);
+ --accent6: var(--orange6);
+ --accent7: var(--orange7);
+ --accent8: var(--orange8);
+ --accent9: var(--orange9);
+ --accent10: var(--orange10);
+ --accent11: var(--orange11);
+ --accent12: var(--orange12);
+ --accentA1: var(--orangeA1);
+ --accentA2: var(--orangeA2);
+ --accentA3: var(--orangeA3);
+ --accentA4: var(--orangeA4);
+ --accentA5: var(--orangeA5);
+ --accentA6: var(--orangeA6);
+ --accentA7: var(--orangeA7);
+ --accentA8: var(--orangeA8);
+ --accentA9: var(--orangeA9);
+ --accentA10: var(--orangeA10);
+ --accentA11: var(--orangeA11);
+ --accentA12: var(--orangeA12);
+}
+
+[data-accent-color='pink'] {
+ --accent1: var(--pink1);
+ --accent2: var(--pink2);
+ --accent3: var(--pink3);
+ --accent4: var(--pink4);
+ --accent5: var(--pink5);
+ --accent6: var(--pink6);
+ --accent7: var(--pink7);
+ --accent8: var(--pink8);
+ --accent9: var(--pink9);
+ --accent10: var(--pink10);
+ --accent11: var(--pink11);
+ --accent12: var(--pink12);
+ --accentA1: var(--pinkA1);
+ --accentA2: var(--pinkA2);
+ --accentA3: var(--pinkA3);
+ --accentA4: var(--pinkA4);
+ --accentA5: var(--pinkA5);
+ --accentA6: var(--pinkA6);
+ --accentA7: var(--pinkA7);
+ --accentA8: var(--pinkA8);
+ --accentA9: var(--pinkA9);
+ --accentA10: var(--pinkA10);
+ --accentA11: var(--pinkA11);
+ --accentA12: var(--pinkA12);
+}
+
+[data-accent-color='plum'] {
+ --accent1: var(--plum1);
+ --accent2: var(--plum2);
+ --accent3: var(--plum3);
+ --accent4: var(--plum4);
+ --accent5: var(--plum5);
+ --accent6: var(--plum6);
+ --accent7: var(--plum7);
+ --accent8: var(--plum8);
+ --accent9: var(--plum9);
+ --accent10: var(--plum10);
+ --accent11: var(--plum11);
+ --accent12: var(--plum12);
+ --accentA1: var(--plumA1);
+ --accentA2: var(--plumA2);
+ --accentA3: var(--plumA3);
+ --accentA4: var(--plumA4);
+ --accentA5: var(--plumA5);
+ --accentA6: var(--plumA6);
+ --accentA7: var(--plumA7);
+ --accentA8: var(--plumA8);
+ --accentA9: var(--plumA9);
+ --accentA10: var(--plumA10);
+ --accentA11: var(--plumA11);
+ --accentA12: var(--plumA12);
+}
+
+[data-accent-color='purple'] {
+ --accent1: var(--purple1);
+ --accent2: var(--purple2);
+ --accent3: var(--purple3);
+ --accent4: var(--purple4);
+ --accent5: var(--purple5);
+ --accent6: var(--purple6);
+ --accent7: var(--purple7);
+ --accent8: var(--purple8);
+ --accent9: var(--purple9);
+ --accent10: var(--purple10);
+ --accent11: var(--purple11);
+ --accent12: var(--purple12);
+ --accentA1: var(--purpleA1);
+ --accentA2: var(--purpleA2);
+ --accentA3: var(--purpleA3);
+ --accentA4: var(--purpleA4);
+ --accentA5: var(--purpleA5);
+ --accentA6: var(--purpleA6);
+ --accentA7: var(--purpleA7);
+ --accentA8: var(--purpleA8);
+ --accentA9: var(--purpleA9);
+ --accentA10: var(--purpleA10);
+ --accentA11: var(--purpleA11);
+ --accentA12: var(--purpleA12);
+}
+
+[data-accent-color='red'] {
+ --accent1: var(--red1);
+ --accent2: var(--red2);
+ --accent3: var(--red3);
+ --accent4: var(--red4);
+ --accent5: var(--red5);
+ --accent6: var(--red6);
+ --accent7: var(--red7);
+ --accent8: var(--red8);
+ --accent9: var(--red9);
+ --accent10: var(--red10);
+ --accent11: var(--red11);
+ --accent12: var(--red12);
+ --accentA1: var(--redA1);
+ --accentA2: var(--redA2);
+ --accentA3: var(--redA3);
+ --accentA4: var(--redA4);
+ --accentA5: var(--redA5);
+ --accentA6: var(--redA6);
+ --accentA7: var(--redA7);
+ --accentA8: var(--redA8);
+ --accentA9: var(--redA9);
+ --accentA10: var(--redA10);
+ --accentA11: var(--redA11);
+ --accentA12: var(--redA12);
+}
+
+[data-accent-color='ruby'] {
+ --accent1: var(--ruby1);
+ --accent2: var(--ruby2);
+ --accent3: var(--ruby3);
+ --accent4: var(--ruby4);
+ --accent5: var(--ruby5);
+ --accent6: var(--ruby6);
+ --accent7: var(--ruby7);
+ --accent8: var(--ruby8);
+ --accent9: var(--ruby9);
+ --accent10: var(--ruby10);
+ --accent11: var(--ruby11);
+ --accent12: var(--ruby12);
+ --accentA1: var(--rubyA1);
+ --accentA2: var(--rubyA2);
+ --accentA3: var(--rubyA3);
+ --accentA4: var(--rubyA4);
+ --accentA5: var(--rubyA5);
+ --accentA6: var(--rubyA6);
+ --accentA7: var(--rubyA7);
+ --accentA8: var(--rubyA8);
+ --accentA9: var(--rubyA9);
+ --accentA10: var(--rubyA10);
+ --accentA11: var(--rubyA11);
+ --accentA12: var(--rubyA12);
+}
+
+[data-accent-color='sky'] {
+ --accent1: var(--sky1);
+ --accent2: var(--sky2);
+ --accent3: var(--sky3);
+ --accent4: var(--sky4);
+ --accent5: var(--sky5);
+ --accent6: var(--sky6);
+ --accent7: var(--sky7);
+ --accent8: var(--sky8);
+ --accent9: var(--sky9);
+ --accent10: var(--sky10);
+ --accent11: var(--sky11);
+ --accent12: var(--sky12);
+ --accentA1: var(--skyA1);
+ --accentA2: var(--skyA2);
+ --accentA3: var(--skyA3);
+ --accentA4: var(--skyA4);
+ --accentA5: var(--skyA5);
+ --accentA6: var(--skyA6);
+ --accentA7: var(--skyA7);
+ --accentA8: var(--skyA8);
+ --accentA9: var(--skyA9);
+ --accentA10: var(--skyA10);
+ --accentA11: var(--skyA11);
+ --accentA12: var(--skyA12);
+}
+
+[data-accent-color='teal'] {
+ --accent1: var(--teal1);
+ --accent2: var(--teal2);
+ --accent3: var(--teal3);
+ --accent4: var(--teal4);
+ --accent5: var(--teal5);
+ --accent6: var(--teal6);
+ --accent7: var(--teal7);
+ --accent8: var(--teal8);
+ --accent9: var(--teal9);
+ --accent10: var(--teal10);
+ --accent11: var(--teal11);
+ --accent12: var(--teal12);
+ --accentA1: var(--tealA1);
+ --accentA2: var(--tealA2);
+ --accentA3: var(--tealA3);
+ --accentA4: var(--tealA4);
+ --accentA5: var(--tealA5);
+ --accentA6: var(--tealA6);
+ --accentA7: var(--tealA7);
+ --accentA8: var(--tealA8);
+ --accentA9: var(--tealA9);
+ --accentA10: var(--tealA10);
+ --accentA11: var(--tealA11);
+ --accentA12: var(--tealA12);
+}
+
+[data-accent-color='tomato'] {
+ --accent1: var(--tomato1);
+ --accent2: var(--tomato2);
+ --accent3: var(--tomato3);
+ --accent4: var(--tomato4);
+ --accent5: var(--tomato5);
+ --accent6: var(--tomato6);
+ --accent7: var(--tomato7);
+ --accent8: var(--tomato8);
+ --accent9: var(--tomato9);
+ --accent10: var(--tomato10);
+ --accent11: var(--tomato11);
+ --accent12: var(--tomato12);
+ --accentA1: var(--tomatoA1);
+ --accentA2: var(--tomatoA2);
+ --accentA3: var(--tomatoA3);
+ --accentA4: var(--tomatoA4);
+ --accentA5: var(--tomatoA5);
+ --accentA6: var(--tomatoA6);
+ --accentA7: var(--tomatoA7);
+ --accentA8: var(--tomatoA8);
+ --accentA9: var(--tomatoA9);
+ --accentA10: var(--tomatoA10);
+ --accentA11: var(--tomatoA11);
+ --accentA12: var(--tomatoA12);
+}
+
+[data-accent-color='violet'] {
+ --accent1: var(--violet1);
+ --accent2: var(--violet2);
+ --accent3: var(--violet3);
+ --accent4: var(--violet4);
+ --accent5: var(--violet5);
+ --accent6: var(--violet6);
+ --accent7: var(--violet7);
+ --accent8: var(--violet8);
+ --accent9: var(--violet9);
+ --accent10: var(--violet10);
+ --accent11: var(--violet11);
+ --accent12: var(--violet12);
+ --accentA1: var(--violetA1);
+ --accentA2: var(--violetA2);
+ --accentA3: var(--violetA3);
+ --accentA4: var(--violetA4);
+ --accentA5: var(--violetA5);
+ --accentA6: var(--violetA6);
+ --accentA7: var(--violetA7);
+ --accentA8: var(--violetA8);
+ --accentA9: var(--violetA9);
+ --accentA10: var(--violetA10);
+ --accentA11: var(--violetA11);
+ --accentA12: var(--violetA12);
+}
+
+[data-accent-color='yellow'] {
+ --accent1: var(--yellow1);
+ --accent2: var(--yellow2);
+ --accent3: var(--yellow3);
+ --accent4: var(--yellow4);
+ --accent5: var(--yellow5);
+ --accent6: var(--yellow6);
+ --accent7: var(--yellow7);
+ --accent8: var(--yellow8);
+ --accent9: var(--yellow9);
+ --accent10: var(--yellow10);
+ --accent11: var(--yellow11);
+ --accent12: var(--yellow12);
+ --accentA1: var(--yellowA1);
+ --accentA2: var(--yellowA2);
+ --accentA3: var(--yellowA3);
+ --accentA4: var(--yellowA4);
+ --accentA5: var(--yellowA5);
+ --accentA6: var(--yellowA6);
+ --accentA7: var(--yellowA7);
+ --accentA8: var(--yellowA8);
+ --accentA9: var(--yellowA9);
+ --accentA10: var(--yellowA10);
+ --accentA11: var(--yellowA11);
+ --accentA12: var(--yellowA12);
+}
+
+[data-gray-color='mauve'],
+.radix-themes:where([data-gray-color='mauve']) {
+ --gray1: var(--mauve1);
+ --gray2: var(--mauve2);
+ --gray3: var(--mauve3);
+ --gray4: var(--mauve4);
+ --gray5: var(--mauve5);
+ --gray6: var(--mauve6);
+ --gray7: var(--mauve7);
+ --gray8: var(--mauve8);
+ --gray9: var(--mauve9);
+ --gray10: var(--mauve10);
+ --gray11: var(--mauve11);
+ --gray12: var(--mauve12);
+ --grayA1: var(--mauveA1);
+ --grayA2: var(--mauveA2);
+ --grayA3: var(--mauveA3);
+ --grayA4: var(--mauveA4);
+ --grayA5: var(--mauveA5);
+ --grayA6: var(--mauveA6);
+ --grayA7: var(--mauveA7);
+ --grayA8: var(--mauveA8);
+ --grayA9: var(--mauveA9);
+ --grayA10: var(--mauveA10);
+ --grayA11: var(--mauveA11);
+ --grayA12: var(--mauveA12);
+}
+
+[data-gray-color='olive'],
+.radix-themes:where([data-gray-color='olive']) {
+ --gray1: var(--olive1);
+ --gray2: var(--olive2);
+ --gray3: var(--olive3);
+ --gray4: var(--olive4);
+ --gray5: var(--olive5);
+ --gray6: var(--olive6);
+ --gray7: var(--olive7);
+ --gray8: var(--olive8);
+ --gray9: var(--olive9);
+ --gray10: var(--olive10);
+ --gray11: var(--olive11);
+ --gray12: var(--olive12);
+ --grayA1: var(--oliveA1);
+ --grayA2: var(--oliveA2);
+ --grayA3: var(--oliveA3);
+ --grayA4: var(--oliveA4);
+ --grayA5: var(--oliveA5);
+ --grayA6: var(--oliveA6);
+ --grayA7: var(--oliveA7);
+ --grayA8: var(--oliveA8);
+ --grayA9: var(--oliveA9);
+ --grayA10: var(--oliveA10);
+ --grayA11: var(--oliveA11);
+ --grayA12: var(--oliveA12);
+}
+
+[data-gray-color='sage'],
+.radix-themes:where([data-gray-color='sage']) {
+ --gray1: var(--sage1);
+ --gray2: var(--sage2);
+ --gray3: var(--sage3);
+ --gray4: var(--sage4);
+ --gray5: var(--sage5);
+ --gray6: var(--sage6);
+ --gray7: var(--sage7);
+ --gray8: var(--sage8);
+ --gray9: var(--sage9);
+ --gray10: var(--sage10);
+ --gray11: var(--sage11);
+ --gray12: var(--sage12);
+ --grayA1: var(--sageA1);
+ --grayA2: var(--sageA2);
+ --grayA3: var(--sageA3);
+ --grayA4: var(--sageA4);
+ --grayA5: var(--sageA5);
+ --grayA6: var(--sageA6);
+ --grayA7: var(--sageA7);
+ --grayA8: var(--sageA8);
+ --grayA9: var(--sageA9);
+ --grayA10: var(--sageA10);
+ --grayA11: var(--sageA11);
+ --grayA12: var(--sageA12);
+}
+
+[data-gray-color='sand'],
+.radix-themes:where([data-gray-color='sand']) {
+ --gray1: var(--sand1);
+ --gray2: var(--sand2);
+ --gray3: var(--sand3);
+ --gray4: var(--sand4);
+ --gray5: var(--sand5);
+ --gray6: var(--sand6);
+ --gray7: var(--sand7);
+ --gray8: var(--sand8);
+ --gray9: var(--sand9);
+ --gray10: var(--sand10);
+ --gray11: var(--sand11);
+ --gray12: var(--sand12);
+ --grayA1: var(--sandA1);
+ --grayA2: var(--sandA2);
+ --grayA3: var(--sandA3);
+ --grayA4: var(--sandA4);
+ --grayA5: var(--sandA5);
+ --grayA6: var(--sandA6);
+ --grayA7: var(--sandA7);
+ --grayA8: var(--sandA8);
+ --grayA9: var(--sandA9);
+ --grayA10: var(--sandA10);
+ --grayA11: var(--sandA11);
+ --grayA12: var(--sandA12);
+}
+
+[data-gray-color='slate'],
+.radix-themes:where([data-gray-color='slate']) {
+ --gray1: var(--slate1);
+ --gray2: var(--slate2);
+ --gray3: var(--slate3);
+ --gray4: var(--slate4);
+ --gray5: var(--slate5);
+ --gray6: var(--slate6);
+ --gray7: var(--slate7);
+ --gray8: var(--slate8);
+ --gray9: var(--slate9);
+ --gray10: var(--slate10);
+ --gray11: var(--slate11);
+ --gray12: var(--slate12);
+ --grayA1: var(--slateA1);
+ --grayA2: var(--slateA2);
+ --grayA3: var(--slateA3);
+ --grayA4: var(--slateA4);
+ --grayA5: var(--slateA5);
+ --grayA6: var(--slateA6);
+ --grayA7: var(--slateA7);
+ --grayA8: var(--slateA8);
+ --grayA9: var(--slateA9);
+ --grayA10: var(--slateA10);
+ --grayA11: var(--slateA11);
+ --grayA12: var(--slateA12);
+}
+
+@font-face {
+ font-family: 'Geist Sans';
+
+ src: url('./GeistVariable.ttf') format('truetype');
+
+ font-weight: 100 900;
+
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Geist Mono';
+
+ src: url('./GeistMonoVariable.ttf') format('truetype');
+
+ font-weight: 100 900;
+
+ font-style: normal;
+}
+
+/* ibm-plex-mono-latin-100-normal */
+
+@font-face {
+ font-family: 'IBM Plex Mono';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 100;
+
+ src:
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-100-normal.woff2')
+ format('woff2'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-100-normal.woff') format('woff'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-100-normal.ttf')
+ format('truetype');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* ibm-plex-mono-latin-200-normal */
+
+@font-face {
+ font-family: 'IBM Plex Mono';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 200;
+
+ src:
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-200-normal.woff2')
+ format('woff2'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-200-normal.woff') format('woff'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-200-normal.ttf')
+ format('truetype');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* ibm-plex-mono-latin-300-normal */
+
+@font-face {
+ font-family: 'IBM Plex Mono';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 300;
+
+ src:
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-300-normal.woff2')
+ format('woff2'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-300-normal.woff') format('woff'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-300-normal.ttf')
+ format('truetype');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* ibm-plex-mono-latin-400-normal */
+
+@font-face {
+ font-family: 'IBM Plex Mono';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 400;
+
+ src:
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-400-normal.woff2')
+ format('woff2'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-400-normal.woff') format('woff'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-400-normal.ttf')
+ format('truetype');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* ibm-plex-mono-latin-500-normal */
+
+@font-face {
+ font-family: 'IBM Plex Mono';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 500;
+
+ src:
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-500-normal.woff2')
+ format('woff2'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-500-normal.woff') format('woff'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-500-normal.ttf')
+ format('truetype');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* ibm-plex-mono-latin-600-normal */
+
+@font-face {
+ font-family: 'IBM Plex Mono';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 600;
+
+ src:
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-600-normal.woff2')
+ format('woff2'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-600-normal.woff') format('woff'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-600-normal.ttf')
+ format('truetype');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* ibm-plex-mono-latin-700-normal */
+
+@font-face {
+ font-family: 'IBM Plex Mono';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 700;
+
+ src:
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-700-normal.woff2')
+ format('woff2'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-700-normal.woff') format('woff'),
+ url('./001-IBMPlexMono/ibm-plex-mono-latin-700-normal.ttf')
+ format('truetype');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 100;
+
+ font-style: normal;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-Hairline.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 200;
+
+ font-style: normal;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-Fine.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 300;
+
+ font-style: normal;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-Thin.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 400;
+
+ font-style: normal;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-Light.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 500;
+
+ font-style: normal;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-Regular.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 600;
+
+ font-style: normal;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-Medium.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 700;
+
+ font-style: normal;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-Bold.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 800;
+
+ font-style: normal;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-Black.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 100;
+
+ font-style: italic;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-HairlineItalic.woff')
+ format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 200;
+
+ font-style: italic;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-FineItalic.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 300;
+
+ font-style: italic;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-ThinItalic.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 400;
+
+ font-style: italic;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-LightItalic.woff')
+ format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 500;
+
+ font-style: italic;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-RegularItalic.woff')
+ format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 600;
+
+ font-style: italic;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-MediumItalic.woff')
+ format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 700;
+
+ font-style: italic;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-BoldItalic.woff') format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+
+ font-weight: 800;
+
+ font-style: italic;
+
+ src: url('./010-LabilGrotesk/LabilGroteskLite-BlackItalic.woff')
+ format('woff');
+
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk Variable';
+
+ font-display: swap;
+
+ src:
+ url('./900-Variable/LabilGroteskLite-Variable.woff2')
+ format('woff2-variations'),
+ url('./010-LabilGrotesk/LabilGroteskLite-Regular.woff') format('woff');
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 100;
+
+ font-style: normal;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-Hairline.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 200;
+
+ font-style: normal;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-Fine.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 300;
+
+ font-style: normal;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-Thin.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 400;
+
+ font-style: normal;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-Light.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 500;
+
+ font-style: normal;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-Regular.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 600;
+
+ font-style: normal;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-Medium.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 700;
+
+ font-style: normal;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-Bold.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 800;
+
+ font-style: normal;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-Black.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 100;
+
+ font-style: italic;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-HairlineItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 200;
+
+ font-style: italic;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-FineItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 300;
+
+ font-style: italic;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-ThinItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 400;
+
+ font-style: italic;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-LightItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 500;
+
+ font-style: italic;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-RegularItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 600;
+
+ font-style: italic;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-MediumItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 700;
+
+ font-style: italic;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-BoldItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk';
+
+ font-weight: 800;
+
+ font-style: italic;
+
+ src: url('./011-StabilGrotesk/StabilGroteskLite-BlackItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Stabil Grotesk Variable';
+
+ font-display: block;
+
+ src:
+ url('./900-Variable/StabilGroteskLite-Variable.woff2')
+ format('woff2-variations'),
+ url('./011-StabilGrotesk/StabilGroteskLite-Regular.woff') format('woff');
+}
+
+@font-face {
+ font-family: 'Attila Sans Classic';
+
+ font-weight: 100;
+
+ font-style: normal;
+
+ src: url('./021-AttilaSansClassic/AttilaSansClassicLite-Hairline.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Classic';
+
+ font-weight: 300;
+
+ font-style: normal;
+
+ src: url('./021-AttilaSansClassic/AttilaSansClassicLite-Light.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Classic';
+
+ font-weight: 400;
+
+ font-style: normal;
+
+ src: url('./021-AttilaSansClassic/AttilaSansClassicLite-Regular.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Classic';
+
+ font-weight: 500;
+
+ font-style: normal;
+
+ src: url('./021-AttilaSansClassic/AttilaSansClassicLite-Medium.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Classic';
+
+ font-weight: 600;
+
+ font-style: normal;
+
+ src: url('./021-AttilaSansClassic/AttilaSansClassicLite-Semibold.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Classic';
+
+ font-weight: 700;
+
+ font-style: normal;
+
+ src: url('./021-AttilaSansClassic/AttilaSansClassicLite-Bold.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Classic';
+
+ font-weight: 800;
+
+ font-style: normal;
+
+ src: url('./021-AttilaSansClassic/AttilaSansClassicLite-Black.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Sharp';
+
+ font-weight: 100;
+
+ font-style: normal;
+
+ src: url('./022-AttilaSansSharp/AttilaSansSharpLite-Hairline.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Sharp';
+
+ font-weight: 200;
+
+ font-style: normal;
+
+ src: url('./022-AttilaSansSharp/AttilaSansSharpLite-Thin.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Sharp';
+
+ font-weight: 300;
+
+ font-style: normal;
+
+ src: url('./022-AttilaSansSharp/AttilaSansSharpLite-Light.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Sharp';
+
+ font-weight: 400;
+
+ font-style: normal;
+
+ src: url('./022-AttilaSansSharp/AttilaSansSharpLite-Regular.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Sharp';
+
+ font-weight: 500;
+
+ font-style: normal;
+
+ src: url('./022-AttilaSansSharp/AttilaSansSharpLite-Medium.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Sharp';
+
+ font-weight: 600;
+
+ font-style: normal;
+
+ src: url('./022-AttilaSansSharp/AttilaSansSharpLite-Semibold.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Sharp';
+
+ font-weight: 700;
+
+ font-style: normal;
+
+ src: url('./022-AttilaSansSharp/AttilaSansSharpLite-Bold.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Attila Sans Sharp';
+
+ font-weight: 800;
+
+ font-style: normal;
+
+ src: url('./022-AttilaSansSharp/AttilaSansSharpLite-Black.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 100;
+
+ font-style: normal;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-Hairline.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 200;
+
+ font-style: normal;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-Thin.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 300;
+
+ font-style: normal;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-Light.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 400;
+
+ font-style: normal;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-Regular.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 500;
+
+ font-style: normal;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-Medium.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 600;
+
+ font-style: normal;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-Semibold.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 700;
+
+ font-style: normal;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-Bold.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 800;
+
+ font-style: normal;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-Black.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 100;
+
+ font-style: italic;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-HairlineItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 200;
+
+ font-style: italic;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-ThinItalic.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 300;
+
+ font-style: italic;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-LightItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 400;
+
+ font-style: italic;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-RegularItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 500;
+
+ font-style: italic;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-MediumItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 600;
+
+ font-style: italic;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-SemiboldItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 700;
+
+ font-style: italic;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-BoldItalic.woff') format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow';
+
+ font-weight: 800;
+
+ font-style: italic;
+
+ src: url('./031-VictorNarrow/VictorNarrowLite-BlackItalic.woff')
+ format('woff');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Narrow Variable';
+
+ font-display: block;
+
+ src:
+ url('./900-Variable/VictorNarrowLite-Variable.woff2')
+ format('woff2-variations'),
+ url('./031-VictorNarrow/VictorNarrowLite-Regular.woff') format('woff');
+}
+
+@font-face {
+ font-family: 'Attila Sans Variable';
+
+ font-display: block;
+
+ src: url('./900-Variable/AttilaSansLite-Variable.woff2')
+ format('woff2-variations');
+}
+
+@font-face {
+ font-family: 'Victor Serif Italic Variable';
+
+ font-display: block;
+
+ src: url('./900-Variable/VictorSerifLite-ItalicVariable.woff2')
+ format('woff2-variations');
+}
+
+@font-face {
+ font-family: 'Victor Narrow Italic Variable';
+
+ font-display: block;
+
+ src: url('./900-Variable/VictorNarrowLite-ItalicVariable.woff2')
+ format('woff2-variations');
+}
+
+@font-face {
+ font-family: 'Victor Serif Preview';
+
+ font-weight: 400;
+
+ font-style: normal;
+
+ src: url('./030-VictorSerif/VictorSerifPreview-40Regular.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif Preview';
+
+ font-weight: 400;
+
+ font-style: italic;
+
+ src: url('./030-VictorSerif/VictorSerifPreview-45RegularItalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 100;
+
+ font-style: normal;
+
+ src: url('./030-VictorSerif/VictorSerifLite-10Hairline.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 100;
+
+ font-style: italic;
+
+ src: url('./030-VictorSerif/VictorSerifLite-15HairlineItalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 200;
+
+ font-style: normal;
+
+ src: url('./030-VictorSerif/VictorSerifLite-20Thin.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 200;
+
+ font-style: italic;
+
+ src: url('./030-VictorSerif/VictorSerifLite-25ThinItalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 300;
+
+ font-style: normal;
+
+ src: url('./030-VictorSerif/VictorSerifLite-30Light.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 300;
+
+ font-style: italic;
+
+ src: url('./030-VictorSerif/VictorSerifLite-35LightItalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 400;
+
+ font-style: normal;
+
+ src: url('./030-VictorSerif/VictorSerifLite-40Regular.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 400;
+
+ font-style: italic;
+
+ src: url('./030-VictorSerif/VictorSerifLite-45RegularItalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 500;
+
+ font-style: normal;
+
+ src: url('./030-VictorSerif/VictorSerifLite-50Medium.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 500;
+
+ font-style: italic;
+
+ src: url('./030-VictorSerif/VictorSerifLite-55MediumItalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 600;
+
+ font-style: normal;
+
+ src: url('./030-VictorSerif/VictorSerifLite-60Semibold.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 600;
+
+ font-style: italic;
+
+ src: url('./030-VictorSerif/VictorSerifLite-65SemiboldItalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 700;
+
+ font-style: normal;
+
+ src: url('./030-VictorSerif/VictorSerifLite-70Bold.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 700;
+
+ font-style: italic;
+
+ src: url('./030-VictorSerif/VictorSerifLite-75BoldItalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 800;
+
+ font-style: normal;
+
+ src: url('./030-VictorSerif/VictorSerifLite-80Black.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif';
+
+ font-weight: 800;
+
+ font-style: italic;
+
+ src: url('./030-VictorSerif/VictorSerifLite-85BlackItalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Victor Serif Variable';
+
+ font-display: block;
+
+ src: url('./900-Variable/VictorSerifLite-Variable.woff2')
+ format('woff2-variations');
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 100;
+
+ font-style: normal;
+
+ src: url('./023-Uniforma/KUniformaPreview-10Hairline.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 100;
+
+ font-style: italic;
+
+ src: url('./023-Uniforma/KUniformaPreview-15HairlineRitalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 200;
+
+ font-style: normal;
+
+ src: url('./023-Uniforma/KUniformaPreview-20Thin.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 200;
+
+ font-style: italic;
+
+ src: url('./023-Uniforma/KUniformaPreview-25ThinRitalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 300;
+
+ font-style: normal;
+
+ src: url('./023-Uniforma/KUniformaPreview-30Extralight.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 300;
+
+ font-style: italic;
+
+ src: url('./023-Uniforma/KUniformaPreview-35ExtralightRitalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 400;
+
+ font-style: normal;
+
+ src: url('./023-Uniforma/KUniformaPreview-40Light.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 400;
+
+ font-style: italic;
+
+ src: url('./023-Uniforma/KUniformaPreview-45LightRitalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 500;
+
+ font-style: normal;
+
+ src: url('./023-Uniforma/KUniformaPreview-50Regular.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 500;
+
+ font-style: italic;
+
+ src: url('./023-Uniforma/KUniformaPreview-55RegularRitalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 600;
+
+ font-style: normal;
+
+ src: url('./023-Uniforma/KUniformaPreview-60Medium.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 600;
+
+ font-style: italic;
+
+ src: url('./023-Uniforma/KUniformaPreview-65MediumRitalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 700;
+
+ font-style: normal;
+
+ src: url('./023-Uniforma/KUniformaPreview-70Semibold.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 700;
+
+ font-style: italic;
+
+ src: url('./023-Uniforma/KUniformaPreview-75SemiboldRitalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 800;
+
+ font-style: normal;
+
+ src: url('./023-Uniforma/KUniformaPreview-80Bold.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 800;
+
+ font-style: italic;
+
+ src: url('./023-Uniforma/KUniformaPreview-85BoldRitalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 900;
+
+ font-style: normal;
+
+ src: url('./023-Uniforma/KUniformaPreview-90Black.woff2') format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: Uniforma;
+
+ font-weight: 900;
+
+ font-style: italic;
+
+ src: url('./023-Uniforma/KUniformaPreview-95BlackRitalic.woff2')
+ format('woff2');
+
+ font-display: block;
+}
+
+@font-face {
+ font-family: 'Uniforma Variable';
+
+ font-weight: 100 900;
+
+ src:
+ url('./900-Variable/KUniformaVariableVF.woff2')
+ format('woff2 supports variations'),
+ url('./900-Variable/KUniformaVariableVF.woff2') format('woff2-variations');
+
+ font-display: block;
+}
+
+/* space-grotesk-latin-wght-normal */
+
+@font-face {
+ font-family: 'Space Grotesk Variable';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 300 700;
+
+ src: url('./002-SpaceGrotesk/space-grotesk-latin-wght-normal.woff2')
+ format('woff2-variations');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* space-grotesk-latin-ext-wght-normal */
+
+@font-face {
+ font-family: 'Space Grotesk Variable';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 300 700;
+
+ src: url('./002-SpaceGrotesk/space-grotesk-latin-ext-wght-normal.woff2')
+ format('woff2-variations');
+
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
+ U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+
+/* space-grotesk-latin-300-normal */
+
+@font-face {
+ font-family: 'Space Grotesk';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 300;
+
+ src:
+ url('./002-SpaceGrotesk/space-grotesk-latin-300-normal.woff2')
+ format('woff2'),
+ url('./002-SpaceGrotesk/space-grotesk-latin-300-normal.woff') format('woff');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* space-grotesk-latin-400-normal */
+
+@font-face {
+ font-family: 'Space Grotesk';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 400;
+
+ src:
+ url('./002-SpaceGrotesk/space-grotesk-latin-400-normal.woff2')
+ format('woff2'),
+ url('./002-SpaceGrotesk/space-grotesk-latin-400-normal.woff') format('woff');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* space-grotesk-latin-500-normal */
+
+@font-face {
+ font-family: 'Space Grotesk';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 500;
+
+ src:
+ url('./002-SpaceGrotesk/space-grotesk-latin-500-normal.woff2')
+ format('woff2'),
+ url('./002-SpaceGrotesk/space-grotesk-latin-500-normal.woff') format('woff');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* space-grotesk-latin-600-normal */
+
+@font-face {
+ font-family: 'Space Grotesk';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 600;
+
+ src:
+ url('./002-SpaceGrotesk/space-grotesk-latin-600-normal.woff2')
+ format('woff2'),
+ url('./002-SpaceGrotesk/space-grotesk-latin-600-normal.woff') format('woff');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* space-grotesk-latin-700-normal */
+
+@font-face {
+ font-family: 'Space Grotesk';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 700;
+
+ src:
+ url('./002-SpaceGrotesk/space-grotesk-latin-700-normal.woff2')
+ format('woff2'),
+ url('./002-SpaceGrotesk/space-grotesk-latin-700-normal.woff') format('woff');
+
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* space-grotesk-latin-ext-300-normal */
+
+@font-face {
+ font-family: 'Space Grotesk';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 300;
+
+ src:
+ url('./002-SpaceGrotesk/space-grotesk-latin-ext-300-normal.woff2')
+ format('woff2'),
+ url('./002-SpaceGrotesk/space-grotesk-latin-ext-300-normal.woff')
+ format('woff');
+
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
+ U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+
+/* space-grotesk-latin-ext-400-normal */
+
+@font-face {
+ font-family: 'Space Grotesk';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 400;
+
+ src:
+ url('./002-SpaceGrotesk/space-grotesk-latin-ext-400-normal.woff2')
+ format('woff2'),
+ url('./002-SpaceGrotesk/space-grotesk-latin-ext-400-normal.woff')
+ format('woff');
+
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
+ U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+
+/* space-grotesk-latin-ext-500-normal */
+
+@font-face {
+ font-family: 'Space Grotesk';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 500;
+
+ src:
+ url('./002-SpaceGrotesk/space-grotesk-latin-ext-500-normal.woff2')
+ format('woff2'),
+ url('./002-SpaceGrotesk/space-grotesk-latin-ext-500-normal.woff')
+ format('woff');
+
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
+ U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+
+/* space-grotesk-latin-ext-600-normal */
+
+@font-face {
+ font-family: 'Space Grotesk';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 600;
+
+ src:
+ url('./002-SpaceGrotesk/space-grotesk-latin-ext-600-normal.woff2')
+ format('woff2'),
+ url('./002-SpaceGrotesk/space-grotesk-latin-ext-600-normal.woff')
+ format('woff');
+
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
+ U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+
+/* space-grotesk-latin-ext-700-normal */
+
+@font-face {
+ font-family: 'Space Grotesk';
+
+ font-style: normal;
+
+ font-display: swap;
+
+ font-weight: 700;
+
+ src:
+ url('./002-SpaceGrotesk/space-grotesk-latin-ext-700-normal.woff2')
+ format('woff2'),
+ url('./002-SpaceGrotesk/space-grotesk-latin-ext-700-normal.woff')
+ format('woff');
+
+ unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF,
+ U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
+}
+
+:root {
+ --font-geist-sans: 'Geist Sans';
+ --font-geist-mono: 'Geist Mono';
+ --font-labil-grotesk: 'Labil Grotesk Variable';
+ --font-ibm-plex-mono: 'IBM Plex Mono';
+}
+
+/* this will be exported as base.css and can be used for a basic styling */
+
+/* these are the necessary styles for React/Svelte Flow, they get used by base.css and style.css */
+
+.react-flow {
+ direction: ltr;
+ --xy-edge-stroke-default: #b1b1b7;
+ --xy-edge-stroke-width-default: 1;
+ --xy-edge-stroke-selected-default: #555;
+ --xy-connectionline-stroke-default: #b1b1b7;
+ --xy-connectionline-stroke-width-default: 1;
+ --xy-attribution-background-color-default: rgba(255, 255, 255, 0.5);
+ --xy-minimap-background-color-default: #fff;
+ --xy-minimap-mask-background-color-default: rgb(240, 240, 240, 0.6);
+ --xy-minimap-mask-stroke-color-default: transparent;
+ --xy-minimap-mask-stroke-width-default: 1;
+ --xy-minimap-node-background-color-default: #e2e2e2;
+ --xy-minimap-node-stroke-color-default: transparent;
+ --xy-minimap-node-stroke-width-default: 2;
+ --xy-background-color-default: transparent;
+ --xy-background-pattern-dots-color-default: #91919a;
+ --xy-background-pattern-lines-color-default: #eee;
+ --xy-background-pattern-cross-color-default: #e2e2e2;
+ background-color: var(
+ --xy-background-color,
+ var(--xy-background-color-default)
+ );
+ --xy-node-border-default: 1px solid #bbb;
+ --xy-node-border-selected-default: 1px solid #555;
+ --xy-handle-background-color-default: #333;
+ --xy-selection-background-color-default: rgba(150, 150, 180, 0.1);
+ --xy-selection-border-default: 1px dotted rgba(155, 155, 155, 0.8);
+ --xy-resize-background-color-default: #3367d9;
+}
+
+.react-flow.dark {
+ --xy-edge-stroke-default: #3e3e3e;
+ --xy-edge-stroke-width-default: 1;
+ --xy-edge-stroke-selected-default: #727272;
+ --xy-connectionline-stroke-default: #b1b1b7;
+ --xy-connectionline-stroke-width-default: 1;
+ --xy-attribution-background-color-default: rgba(150, 150, 150, 0.25);
+ --xy-minimap-background-color-default: #141414;
+ --xy-minimap-mask-background-color-default: rgb(60, 60, 60, 0.6);
+ --xy-minimap-mask-stroke-color-default: transparent;
+ --xy-minimap-mask-stroke-width-default: 1;
+ --xy-minimap-node-background-color-default: #2b2b2b;
+ --xy-minimap-node-stroke-color-default: transparent;
+ --xy-minimap-node-stroke-width-default: 2;
+ --xy-background-color-default: #141414;
+ --xy-background-pattern-dots-color-default: #777;
+ --xy-background-pattern-lines-color-default: #777;
+ --xy-background-pattern-cross-color-default: #777;
+ --xy-node-color-default: #f8f8f8;
+}
+
+.react-flow__background {
+ background-color: var(
+ --xy-background-color,
+ var(--xy-background-color-props, var(--xy-background-color-default))
+ );
+ pointer-events: none;
+ z-index: -1;
+}
+
+.react-flow__container {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+}
+
+.react-flow__pane {
+ z-index: 1;
+}
+
+.react-flow__pane.draggable {
+ cursor: grab;
+}
+
+.react-flow__pane.dragging {
+ cursor: grabbing;
+}
+
+.react-flow__pane.selection {
+ cursor: pointer;
+}
+
+.react-flow__viewport {
+ transform-origin: 0 0;
+ z-index: 2;
+ pointer-events: none;
+}
+
+.react-flow__renderer {
+ z-index: 4;
+}
+
+.react-flow__selection {
+ z-index: 6;
+}
+
+.react-flow__nodesselection-rect:focus,
+.react-flow__nodesselection-rect:focus-visible {
+ outline: none;
+}
+
+.react-flow__edge-path {
+ stroke: var(--xy-edge-stroke, var(--xy-edge-stroke-default));
+ stroke-width: var(
+ --xy-edge-stroke-width,
+ var(--xy-edge-stroke-width-default)
+ );
+ fill: none;
+}
+
+.react-flow__connection-path {
+ stroke: var(
+ --xy-connectionline-stroke,
+ var(--xy-connectionline-stroke-default)
+ );
+ stroke-width: var(
+ --xy-connectionline-stroke-width,
+ var(--xy-connectionline-stroke-width-default)
+ );
+ fill: none;
+}
+
+.react-flow .react-flow__edges {
+ position: absolute;
+}
+
+.react-flow .react-flow__edges svg {
+ overflow: visible;
+ position: absolute;
+ pointer-events: none;
+}
+
+.react-flow__edge {
+ pointer-events: visibleStroke;
+}
+
+.react-flow__edge.selectable {
+ cursor: pointer;
+}
+
+.react-flow__edge.animated path {
+ stroke-dasharray: 5;
+ animation: dashdraw 0.5s linear infinite;
+}
+
+.react-flow__edge.animated path.react-flow__edge-interaction {
+ stroke-dasharray: none;
+ animation: none;
+}
+
+.react-flow__edge.inactive {
+ pointer-events: none;
+}
+
+.react-flow__edge.selected,
+.react-flow__edge:focus,
+.react-flow__edge:focus-visible {
+ outline: none;
+}
+
+.react-flow__edge.selected .react-flow__edge-path,
+.react-flow__edge.selectable:focus .react-flow__edge-path,
+.react-flow__edge.selectable:focus-visible .react-flow__edge-path {
+ stroke: var(
+ --xy-edge-stroke-selected,
+ var(--xy-edge-stroke-selected-default)
+ );
+}
+
+.react-flow__edge-textwrapper {
+ pointer-events: all;
+}
+
+.react-flow__edge .react-flow__edge-text {
+ pointer-events: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+
+.react-flow__connection {
+ pointer-events: none;
+}
+
+.react-flow__connection .animated {
+ stroke-dasharray: 5;
+ animation: dashdraw 0.5s linear infinite;
+}
+
+svg.react-flow__connectionline {
+ z-index: 1001;
+ overflow: visible;
+ position: absolute;
+}
+
+.react-flow__nodes {
+ pointer-events: none;
+ transform-origin: 0 0;
+}
+
+.react-flow__node {
+ position: absolute;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ pointer-events: all;
+ transform-origin: 0 0;
+ box-sizing: border-box;
+ cursor: default;
+}
+
+.react-flow__node.selectable {
+ cursor: pointer;
+}
+
+.react-flow__node.draggable {
+ cursor: grab;
+ pointer-events: all;
+}
+
+.react-flow__node.draggable.dragging {
+ cursor: grabbing;
+}
+
+.react-flow__nodesselection {
+ z-index: 3;
+ transform-origin: left top;
+ pointer-events: none;
+}
+
+.react-flow__nodesselection-rect {
+ position: absolute;
+ pointer-events: all;
+ cursor: grab;
+}
+
+.react-flow__handle {
+ position: absolute;
+ pointer-events: none;
+ min-width: 5px;
+ min-height: 5px;
+ background-color: var(
+ --xy-handle-background-color,
+ var(--xy-handle-background-color-default)
+ );
+}
+
+.react-flow__handle.connectingfrom {
+ pointer-events: all;
+}
+
+.react-flow__handle.connectionindicator {
+ pointer-events: all;
+ cursor: crosshair;
+}
+
+.react-flow__handle-bottom {
+ top: auto;
+ left: 50%;
+ bottom: 0;
+ transform: translate(-50%, 50%);
+}
+
+.react-flow__handle-top {
+ top: 0;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.react-flow__handle-left {
+ top: 50%;
+ left: 0;
+ transform: translate(-50%, -50%);
+}
+
+.react-flow__handle-right {
+ top: 50%;
+ right: 0;
+ transform: translate(50%, -50%);
+}
+
+.react-flow__edgeupdater {
+ cursor: move;
+ pointer-events: all;
+}
+
+.react-flow__panel {
+ position: absolute;
+ z-index: 5;
+ margin: 15px;
+}
+
+.react-flow__panel.top {
+ top: 0;
+}
+
+.react-flow__panel.bottom {
+ bottom: 0;
+}
+
+.react-flow__panel.left {
+ left: 0;
+}
+
+.react-flow__panel.right {
+ right: 0;
+}
+
+.react-flow__panel.center {
+ left: 50%;
+ transform: translateX(-50%);
+}
+
+.react-flow__attribution {
+ font-size: 10px;
+ background: var(
+ --xy-attribution-background-color,
+ var(--xy-attribution-background-color-default)
+ );
+ padding: 2px 3px;
+ margin: 0;
+}
+
+.react-flow__attribution a {
+ text-decoration: none;
+ color: #999;
+}
+
+@keyframes dashdraw {
+ from {
+ stroke-dashoffset: 10;
+ }
+}
+
+.react-flow__edgelabel-renderer {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ left: 0;
+ top: 0;
+}
+
+.react-flow__viewport-portal {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ left: 0;
+ top: 0;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+
+.react-flow__minimap {
+ background: var(
+ --xy-minimap-background-color-props,
+ var(
+ --xy-minimap-background-color,
+ var(--xy-minimap-background-color-default)
+ )
+ );
+}
+
+.react-flow__minimap-svg {
+ display: block;
+}
+
+.react-flow__minimap-mask {
+ fill: var(
+ --xy-minimap-mask-background-color-props,
+ var(
+ --xy-minimap-mask-background-color,
+ var(--xy-minimap-mask-background-color-default)
+ )
+ );
+ stroke: var(
+ --xy-minimap-mask-stroke-color-props,
+ var(
+ --xy-minimap-mask-stroke-color,
+ var(--xy-minimap-mask-stroke-color-default)
+ )
+ );
+ stroke-width: var(
+ --xy-minimap-mask-stroke-width-props,
+ var(
+ --xy-minimap-mask-stroke-width,
+ var(--xy-minimap-mask-stroke-width-default)
+ )
+ );
+}
+
+.react-flow__minimap-node {
+ fill: var(
+ --xy-minimap-node-background-color-props,
+ var(
+ --xy-minimap-node-background-color,
+ var(--xy-minimap-node-background-color-default)
+ )
+ );
+ stroke: var(
+ --xy-minimap-node-stroke-color-props,
+ var(
+ --xy-minimap-node-stroke-color,
+ var(--xy-minimap-node-stroke-color-default)
+ )
+ );
+ stroke-width: var(
+ --xy-minimap-node-stroke-width-props,
+ var(
+ --xy-minimap-node-stroke-width,
+ var(--xy-minimap-node-stroke-width-default)
+ )
+ );
+}
+
+.react-flow__background-pattern.dots {
+ fill: var(
+ --xy-background-pattern-color-props,
+ var(
+ --xy-background-pattern-color,
+ var(--xy-background-pattern-dots-color-default)
+ )
+ );
+}
+
+.react-flow__background-pattern.lines {
+ stroke: var(
+ --xy-background-pattern-color-props,
+ var(
+ --xy-background-pattern-color,
+ var(--xy-background-pattern-lines-color-default)
+ )
+ );
+}
+
+.react-flow__background-pattern.cross {
+ stroke: var(
+ --xy-background-pattern-color-props,
+ var(
+ --xy-background-pattern-color,
+ var(--xy-background-pattern-cross-color-default)
+ )
+ );
+}
+
+.react-flow__controls {
+ display: flex;
+ flex-direction: column;
+}
+
+.react-flow__controls.horizontal {
+ flex-direction: row;
+}
+
+.react-flow__controls-button {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 26px;
+ width: 26px;
+ padding: 4px;
+}
+
+.react-flow__controls-button svg {
+ width: 100%;
+ max-width: 12px;
+ max-height: 12px;
+ fill: currentColor;
+}
+
+.react-flow__node-input,
+.react-flow__node-default,
+.react-flow__node-output,
+.react-flow__node-group {
+ border: var(--xy-node-border, var(--xy-node-border-default));
+ color: var(--xy-node-color, var(--xy-node-color-default));
+}
+
+.react-flow__node-input.selected,
+.react-flow__node-input:focus,
+.react-flow__node-input:focus-visible,
+.react-flow__node-default.selected,
+.react-flow__node-default:focus,
+.react-flow__node-default:focus-visible,
+.react-flow__node-output.selected,
+.react-flow__node-output:focus,
+.react-flow__node-output:focus-visible,
+.react-flow__node-group.selected,
+.react-flow__node-group:focus,
+.react-flow__node-group:focus-visible {
+ outline: none;
+ border: var(
+ --xy-node-border-selected,
+ var(--xy-node-border-selected-default)
+ );
+}
+
+.react-flow__nodesselection-rect,
+.react-flow__selection {
+ background: var(
+ --xy-selection-background-color,
+ var(--xy-selection-background-color-default)
+ );
+ border: var(--xy-selection-border, var(--xy-selection-border-default));
+}
+
+.react-flow__resize-control {
+ position: absolute;
+}
+
+.react-flow__resize-control.left,
+.react-flow__resize-control.right {
+ cursor: ew-resize;
+}
+
+.react-flow__resize-control.top,
+.react-flow__resize-control.bottom {
+ cursor: ns-resize;
+}
+
+.react-flow__resize-control.top.left,
+.react-flow__resize-control.bottom.right {
+ cursor: nwse-resize;
+}
+
+.react-flow__resize-control.bottom.left,
+.react-flow__resize-control.top.right {
+ cursor: nesw-resize;
+}
+
+/* handle styles */
+
+.react-flow__resize-control.handle {
+ width: 4px;
+ height: 4px;
+ border: 1px solid #fff;
+ border-radius: 1px;
+ background-color: var(
+ --xy-resize-background-color,
+ var(--xy-resize-background-color-default)
+ );
+ transform: translate(-50%, -50%);
+}
+
+.react-flow__resize-control.handle.left {
+ left: 0;
+ top: 50%;
+}
+
+.react-flow__resize-control.handle.right {
+ left: 100%;
+ top: 50%;
+}
+
+.react-flow__resize-control.handle.top {
+ left: 50%;
+ top: 0;
+}
+
+.react-flow__resize-control.handle.bottom {
+ left: 50%;
+ top: 100%;
+}
+
+.react-flow__resize-control.handle.top.left {
+ left: 0;
+}
+
+.react-flow__resize-control.handle.bottom.left {
+ left: 0;
+}
+
+.react-flow__resize-control.handle.top.right {
+ left: 100%;
+}
+
+.react-flow__resize-control.handle.bottom.right {
+ left: 100%;
+}
+
+/* line styles */
+
+.react-flow__resize-control.line {
+ border-color: var(
+ --xy-resize-background-color,
+ var(--xy-resize-background-color-default)
+ );
+ border-width: 0;
+ border-style: solid;
+}
+
+.react-flow__resize-control.line.left,
+.react-flow__resize-control.line.right {
+ width: 1px;
+ transform: translate(-50%, 0);
+ top: 0;
+ height: 100%;
+}
+
+.react-flow__resize-control.line.left {
+ left: 0;
+ border-left-width: 1px;
+}
+
+.react-flow__resize-control.line.right {
+ left: 100%;
+ border-right-width: 1px;
+}
+
+.react-flow__resize-control.line.top,
+.react-flow__resize-control.line.bottom {
+ height: 1px;
+ transform: translate(0, -50%);
+ left: 0;
+ width: 100%;
+}
+
+.react-flow__resize-control.line.top {
+ top: 0;
+ border-top-width: 1px;
+}
+
+.react-flow__resize-control.line.bottom {
+ border-bottom-width: 1px;
+ top: 100%;
+}
+
+:root {
+ --edge-stroke-default: var(--gray9);
+ --edge-stroke-width-default: 10;
+ --edge-stroke-selected-default: #555;
+ --connectionline-stroke-default: #b1b1b7;
+ --connectionline-stroke-width-default: 1;
+ --attribution-background-color-default: rgba(255, 255, 255, 0.5);
+ --minimap-background-color-default: #fff;
+ --background-pattern-dot-color-default: #91919a;
+ --background-pattern-line-color-default: #eee;
+ --background-pattern-cross-color-default: #e2e2e2;
+ --node-color-default: inherit;
+ --node-border-default: 1px solid green;
+ --node-background-color-default: #fff;
+ --node-group-background-color-default: rgba(240, 240, 240, 0.25);
+ --node-boxshadow-hover-default: 0 1px 4px 1px rgba(0, 0, 0, 0.08);
+ --node-boxshadow-selected-default: 0 0 0 0.5px #1a192b;
+ --handle-background-color-default: #1a192b;
+ --handle-border-color-default: red;
+ --selection-background-color-default: rgba(0, 89, 220, 0.08);
+ --selection-border-default: 1px dotted rgba(0, 89, 220, 0.8);
+ --controls-button-background-color-default: #fefefe;
+ --controls-button-background-color-hover-default: #f4f4f4;
+ --controls-button-color-default: inherit;
+ --controls-button-color-hover-default: inherit;
+ --controls-button-border-color-default: #eee;
+ --controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, 0.08);
+}
+
+.react-flow__attribution {
+ visibility: hidden;
+ display: none;
+}
+
+/* The outermost container */
+
+.react-flow {
+}
+
+/* The inner container */
+
+.react-flow__renderer {
+ background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
+ --tw-gradient-from: var(--grayA1) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+ --tw-gradient-to: var(--gray1) var(--tw-gradient-to-position);
+}
+
+/* Zoom & pan pane */
+
+.react-flow__zoompane {
+}
+
+/* Selection pane */
+
+.react-flow__selectionpane {
+}
+
+/* User selection */
+
+.react-flow__selection {
+}
+
+/* The element containing all edges in the flow */
+
+.react-flow__edges {
+}
+
+/* Applied to each Edge in the flow */
+
+.react-flow__edge {
+}
+
+/* .selected Added to an Edge when selected */
+
+.react-flow__edge {
+}
+
+/* .animated Added to an Edge when its animated prop is true */
+
+.react-flow__edge {
+}
+
+/* .updating Added to an Edge while it gets updated via onReconnect */
+
+.react-flow__edge {
+}
+
+/* The SVG element of an Edge */
+
+.react-flow__edge-path {
+ stroke: var(--grayA9);
+ stroke-width: 1;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+/* The SVG element of an Edge label */
+
+.react-flow__edge-text {
+}
+
+/* The SVG element behind an Edge label */
+
+.react-flow__edge-textbg {
+}
+
+/* Applied to the current connection line */
+
+.react-flow__connection {
+}
+
+/* The SVG of a connection line */
+
+.react-flow__connection-path {
+}
+
+/* The element containing all nodes in the flow */
+
+.react-flow__nodes {
+}
+
+/* Applied to each Node in the flow */
+
+.react-flow__node {
+ border-radius: 1rem;
+ border-color: var(--grayA4);
+ background-color: var(--grayA4);
+ padding-left: 2rem;
+ padding-right: 2rem;
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+ --tw-backdrop-blur: blur(8px);
+ -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
+ var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale)
+ var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
+ var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
+ var(--tw-backdrop-sepia);
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
+ var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale)
+ var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
+ var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
+ var(--tw-backdrop-sepia);
+ --tw-shadow-color: var(--grayA2);
+ --tw-shadow: var(--tw-shadow-colored);
+ --tw-drop-shadow: drop-shadow(0 25px 25px rgb(0 0 0 / 0.15));
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+ & .selected {
+ }
+}
+
+/* .selected Added to a Node when selected. */
+
+.react-flow__node::after {
+ position: absolute;
+ top: 0px;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+ z-index: 10;
+ height: 100%;
+ width: 100%;
+ background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
+ --tw-gradient-from: var(--grayA1) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+ --tw-gradient-to: var(--grayA1) var(--tw-gradient-to-position);
+ content: var(--tw-content);
+ --tw-blur: blur(64px);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+/* Added when Node type is "default" */
+
+.react-flow__node-default {
+}
+
+/* Added when Node type is "input" */
+
+.react-flow__node-input {
+}
+
+/* Added when Node type is "output" */
+
+.react-flow__node-output {
+}
+
+/* Nodes selection */
+
+.react-flow__nodesselection {
+}
+
+/* Nodes selection rect */
+
+.react-flow__nodesselection-rect {
+}
+
+/* Applied to each component */
+
+.react-flow__handle {
+}
+
+/* Applied when a handle's Position is set to "top" */
+
+.react-flow__handle-top {
+}
+
+/* Applied when a handle's Position is set to "right" */
+
+.react-flow__handle-right {
+}
+
+/* Applied when a handle's Position is set to "bottom" */
+
+.react-flow__handle-bottom {
+}
+
+/* Applied when a handle's Position is set to "left" */
+
+.react-flow__handle-left {
+}
+
+/* Added to a Handle when a connection line is above a handle. */
+
+.connectingfrom {
+}
+
+/* Added to a Handle when a connection line is above a handle. */
+
+.connectingto {
+}
+
+/* */
+
+.valid
+ Added
+ to
+ a
+ Handle
+ when
+ a
+ connection
+ line
+ is
+ above
+ and
+ the
+ connection
+ is
+ valid {
+}
+
+/* Applied to the component */
+
+.react-flow__background {
+ background-color: var(--gray2);
+}
+
+/* Applied to the component */
+
+.react-flow__minimap {
+ overflow: clip;
+ border-radius: 1rem;
+ border-width: 1px;
+ background-color: var(--grayA1);
+ --tw-backdrop-blur: blur(8px);
+ -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
+ var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale)
+ var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
+ var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
+ var(--tw-backdrop-sepia);
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
+ var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale)
+ var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
+ var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
+ var(--tw-backdrop-sepia);
+}
+
+.react-flow__minimap::before {
+ content: var(--tw-content);
+ opacity: 0;
+}
+
+.react-flow__minimap::after {
+ content: var(--tw-content);
+ opacity: 0;
+}
+
+/* Applied to the component */
+
+.react-flow__controls {
+ border-radius: 0.5rem;
+ border-width: 1px;
+ border-color: var(--grayA3);
+ background-color: var(--gray1);
+ color: var(--grayA10);
+ --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1),
+ 0 8px 10px -6px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color),
+ 0 8px 10px -6px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+ --tw-shadow-color: var(--grayA1);
+ --tw-shadow: var(--tw-shadow-colored);
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+ --tw-ring-color: var(--grayA3);
+}
+
+.react-flow__panel {
+ background-color: var(--grayA1);
+ --tw-backdrop-blur: blur(8px);
+ -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
+ var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale)
+ var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
+ var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
+ var(--tw-backdrop-sepia);
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
+ var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale)
+ var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
+ var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
+ var(--tw-backdrop-sepia);
+}
+
+.react-flow__minimap::before {
+ background-color: var(--gray1);
+}
+
+.react-flow__minimap-mask {
+ background-color: var(--grayA1);
+ opacity: 0;
+}
+
+.react-flow__minimap-node {
+ border-radius: 9999px;
+ border-style: none;
+ fill: var(--gray9);
+ opacity: 1;
+ --tw-contrast: contrast(2);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+ transition-property: all;
+ transition-duration: 1000ms;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ animation-duration: 1000ms;
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+*,
+::before,
+::after {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-gradient-from-position: ;
+ --tw-gradient-via-position: ;
+ --tw-gradient-to-position: ;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia: ;
+ --tw-contain-size: ;
+ --tw-contain-layout: ;
+ --tw-contain-paint: ;
+ --tw-contain-style: ;
+}
+
+::backdrop {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-gradient-from-position: ;
+ --tw-gradient-via-position: ;
+ --tw-gradient-to-position: ;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia: ;
+ --tw-contain-size: ;
+ --tw-contain-layout: ;
+ --tw-contain-paint: ;
+ --tw-contain-style: ;
+}
+
+/* ! tailwindcss v3.4.12 | MIT License | https://tailwindcss.com */
+
+/*
+1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
+2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
+*/
+
+*,
+::before,
+::after {
+ box-sizing: border-box;
+ /* 1 */
+ border-width: 0;
+ /* 2 */
+ border-style: solid;
+ /* 2 */
+ border-color: #e5e7eb;
+ /* 2 */
+}
+
+::before,
+::after {
+ --tw-content: '';
+}
+
+/*
+1. Use a consistent sensible line-height in all browsers.
+2. Prevent adjustments of font size after orientation changes in iOS.
+3. Use a more readable tab size.
+4. Use the user's configured `sans` font-family by default.
+5. Use the user's configured `sans` font-feature-settings by default.
+6. Use the user's configured `sans` font-variation-settings by default.
+7. Disable tap highlights on iOS
+*/
+
+html,
+:host {
+ line-height: 1.5;
+ /* 1 */
+ -webkit-text-size-adjust: 100%;
+ /* 2 */
+ -moz-tab-size: 4;
+ /* 3 */
+ -o-tab-size: 4;
+ tab-size: 4;
+ /* 3 */
+ font-family: var(--font-labil-grotesk);
+ /* 4 */
+ font-feature-settings: normal;
+ /* 5 */
+ font-variation-settings: normal;
+ /* 6 */
+ -webkit-tap-highlight-color: transparent;
+ /* 7 */
+}
+
+/*
+1. Remove the margin in all browsers.
+2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
+*/
+
+body {
+ margin: 0;
+ /* 1 */
+ line-height: inherit;
+ /* 2 */
+}
+
+/*
+1. Add the correct height in Firefox.
+2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
+3. Ensure horizontal rules are visible by default.
+*/
+
+hr {
+ height: 0;
+ /* 1 */
+ color: inherit;
+ /* 2 */
+ border-top-width: 1px;
+ /* 3 */
+}
+
+/*
+Add the correct text decoration in Chrome, Edge, and Safari.
+*/
+
+abbr:where([title]) {
+ -webkit-text-decoration: underline dotted;
+ text-decoration: underline dotted;
+}
+
+/*
+Remove the default font size and weight for headings.
+*/
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-size: inherit;
+ font-weight: inherit;
+}
+
+/*
+Reset links to optimize for opt-in styling instead of opt-out.
+*/
+
+a {
+ color: inherit;
+ text-decoration: inherit;
+}
+
+/*
+Add the correct font weight in Edge and Safari.
+*/
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/*
+1. Use the user's configured `mono` font-family by default.
+2. Use the user's configured `mono` font-feature-settings by default.
+3. Use the user's configured `mono` font-variation-settings by default.
+4. Correct the odd `em` font sizing in all browsers.
+*/
+
+code,
+kbd,
+samp,
+pre {
+ font-family: var(--font-ibm-plex-mono);
+ /* 1 */
+ font-feature-settings: normal;
+ /* 2 */
+ font-variation-settings: normal;
+ /* 3 */
+ font-size: 1em;
+ /* 4 */
+}
+
+/*
+Add the correct font size in all browsers.
+*/
+
+small {
+ font-size: 80%;
+}
+
+/*
+Prevent `sub` and `sup` elements from affecting the line height in all browsers.
+*/
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/*
+1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
+2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
+3. Remove gaps between table borders by default.
+*/
+
+table {
+ text-indent: 0;
+ /* 1 */
+ border-color: inherit;
+ /* 2 */
+ border-collapse: collapse;
+ /* 3 */
+}
+
+/*
+1. Change the font styles in all browsers.
+2. Remove the margin in Firefox and Safari.
+3. Remove default padding in all browsers.
+*/
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit;
+ /* 1 */
+ font-feature-settings: inherit;
+ /* 1 */
+ font-variation-settings: inherit;
+ /* 1 */
+ font-size: 100%;
+ /* 1 */
+ font-weight: inherit;
+ /* 1 */
+ line-height: inherit;
+ /* 1 */
+ letter-spacing: inherit;
+ /* 1 */
+ color: inherit;
+ /* 1 */
+ margin: 0;
+ /* 2 */
+ padding: 0;
+ /* 3 */
+}
+
+/*
+Remove the inheritance of text transform in Edge and Firefox.
+*/
+
+button,
+select {
+ text-transform: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Remove default button styles.
+*/
+
+button,
+input:where([type='button']),
+input:where([type='reset']),
+input:where([type='submit']) {
+ -webkit-appearance: button;
+ /* 1 */
+ background-color: transparent;
+ /* 2 */
+ background-image: none;
+ /* 2 */
+}
+
+/*
+Use the modern Firefox focus style for all focusable elements.
+*/
+
+:-moz-focusring {
+ outline: auto;
+}
+
+/*
+Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
+*/
+
+:-moz-ui-invalid {
+ box-shadow: none;
+}
+
+/*
+Add the correct vertical alignment in Chrome and Firefox.
+*/
+
+progress {
+ vertical-align: baseline;
+}
+
+/*
+Correct the cursor style of increment and decrement buttons in Safari.
+*/
+
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/*
+1. Correct the odd appearance in Chrome and Safari.
+2. Correct the outline style in Safari.
+*/
+
+[type='search'] {
+ -webkit-appearance: textfield;
+ /* 1 */
+ outline-offset: -2px;
+ /* 2 */
+}
+
+/*
+Remove the inner padding in Chrome and Safari on macOS.
+*/
+
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Change font properties to `inherit` in Safari.
+*/
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ /* 1 */
+ font: inherit;
+ /* 2 */
+}
+
+/*
+Add the correct display in Chrome and Safari.
+*/
+
+summary {
+ display: list-item;
+}
+
+/*
+Removes the default spacing and border for appropriate elements.
+*/
+
+blockquote,
+dl,
+dd,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+figure,
+p,
+pre {
+ margin: 0;
+}
+
+fieldset {
+ margin: 0;
+ padding: 0;
+}
+
+legend {
+ padding: 0;
+}
+
+ol,
+ul,
+menu {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+/*
+Reset default styling for dialogs.
+*/
+
+dialog {
+ padding: 0;
+}
+
+/*
+Prevent resizing textareas horizontally by default.
+*/
+
+textarea {
+ resize: vertical;
+}
+
+/*
+1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
+2. Set the default placeholder color to the user's configured gray 400 color.
+*/
+
+input::-moz-placeholder,
+textarea::-moz-placeholder {
+ opacity: 1;
+ /* 1 */
+ color: #9ca3af;
+ /* 2 */
+}
+
+input::placeholder,
+textarea::placeholder {
+ opacity: 1;
+ /* 1 */
+ color: #9ca3af;
+ /* 2 */
+}
+
+/*
+Set the default cursor for buttons.
+*/
+
+button,
+[role='button'] {
+ cursor: pointer;
+}
+
+/*
+Make sure disabled buttons don't get the pointer cursor.
+*/
+
+:disabled {
+ cursor: default;
+}
+
+/*
+1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
+2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
+ This can trigger a poorly considered lint error in some tools but is included by design.
+*/
+
+img,
+svg,
+video,
+canvas,
+audio,
+iframe,
+embed,
+object {
+ display: block;
+ /* 1 */
+ vertical-align: middle;
+ /* 2 */
+}
+
+/*
+Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
+*/
+
+img,
+video {
+ max-width: 100%;
+ height: auto;
+}
+
+/* Make elements with the HTML hidden attribute stay hidden by default */
+
+[hidden] {
+ display: none;
+}
+
+[type='text'],
+input:where(:not([type])),
+[type='email'],
+[type='url'],
+[type='password'],
+[type='number'],
+[type='date'],
+[type='datetime-local'],
+[type='month'],
+[type='search'],
+[type='tel'],
+[type='time'],
+[type='week'],
+[multiple],
+textarea,
+select {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ background-color: #fff;
+ border-color: #6b7280;
+ border-width: 1px;
+ border-radius: 0px;
+ padding-top: 0.5rem;
+ padding-right: 0.75rem;
+ padding-bottom: 0.5rem;
+ padding-left: 0.75rem;
+ font-size: 1rem;
+ line-height: 1.5rem;
+ --tw-shadow: 0 0 #0000;
+}
+
+[type='text']:focus,
+input:where(:not([type])):focus,
+[type='email']:focus,
+[type='url']:focus,
+[type='password']:focus,
+[type='number']:focus,
+[type='date']:focus,
+[type='datetime-local']:focus,
+[type='month']:focus,
+[type='search']:focus,
+[type='tel']:focus,
+[type='time']:focus,
+[type='week']:focus,
+[multiple]:focus,
+textarea:focus,
+select:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ --tw-ring-inset: var(--tw-empty, /*!*/ /*!*/);
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: #2563eb;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow);
+ border-color: #2563eb;
+}
+
+input::-moz-placeholder,
+textarea::-moz-placeholder {
+ color: #6b7280;
+ opacity: 1;
+}
+
+input::placeholder,
+textarea::placeholder {
+ color: #6b7280;
+ opacity: 1;
+}
+
+::-webkit-datetime-edit-fields-wrapper {
+ padding: 0;
+}
+
+::-webkit-date-and-time-value {
+ min-height: 1.5em;
+ text-align: inherit;
+}
+
+::-webkit-datetime-edit {
+ display: inline-flex;
+}
+
+::-webkit-datetime-edit,
+::-webkit-datetime-edit-year-field,
+::-webkit-datetime-edit-month-field,
+::-webkit-datetime-edit-day-field,
+::-webkit-datetime-edit-hour-field,
+::-webkit-datetime-edit-minute-field,
+::-webkit-datetime-edit-second-field,
+::-webkit-datetime-edit-millisecond-field,
+::-webkit-datetime-edit-meridiem-field {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+
+select {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
+ background-position: right 0.5rem center;
+ background-repeat: no-repeat;
+ background-size: 1.5em 1.5em;
+ padding-right: 2.5rem;
+ print-color-adjust: exact;
+}
+
+[multiple],
+[size]:where(select:not([size='1'])) {
+ background-image: initial;
+ background-position: initial;
+ background-repeat: unset;
+ background-size: initial;
+ padding-right: 0.75rem;
+ print-color-adjust: unset;
+}
+
+[type='checkbox'],
+[type='radio'] {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ padding: 0;
+ print-color-adjust: exact;
+ display: inline-block;
+ vertical-align: middle;
+ background-origin: border-box;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ flex-shrink: 0;
+ height: 1rem;
+ width: 1rem;
+ color: #2563eb;
+ background-color: #fff;
+ border-color: #6b7280;
+ border-width: 1px;
+ --tw-shadow: 0 0 #0000;
+}
+
+[type='checkbox'] {
+ border-radius: 0px;
+}
+
+[type='radio'] {
+ border-radius: 100%;
+}
+
+[type='checkbox']:focus,
+[type='radio']:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ --tw-ring-inset: var(--tw-empty, /*!*/ /*!*/);
+ --tw-ring-offset-width: 2px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: #2563eb;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow);
+}
+
+[type='checkbox']:checked,
+[type='radio']:checked {
+ border-color: transparent;
+ background-color: currentColor;
+ background-size: 100% 100%;
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+[type='checkbox']:checked {
+ background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
+}
+
+@media (forced-colors: active) {
+ [type='checkbox']:checked {
+ -webkit-appearance: auto;
+ -moz-appearance: auto;
+ appearance: auto;
+ }
+}
+
+[type='radio']:checked {
+ background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
+}
+
+@media (forced-colors: active) {
+ [type='radio']:checked {
+ -webkit-appearance: auto;
+ -moz-appearance: auto;
+ appearance: auto;
+ }
+}
+
+[type='checkbox']:checked:hover,
+[type='checkbox']:checked:focus,
+[type='radio']:checked:hover,
+[type='radio']:checked:focus {
+ border-color: transparent;
+ background-color: currentColor;
+}
+
+[type='checkbox']:indeterminate {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");
+ border-color: transparent;
+ background-color: currentColor;
+ background-size: 100% 100%;
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+@media (forced-colors: active) {
+ [type='checkbox']:indeterminate {
+ -webkit-appearance: auto;
+ -moz-appearance: auto;
+ appearance: auto;
+ }
+}
+
+[type='checkbox']:indeterminate:hover,
+[type='checkbox']:indeterminate:focus {
+ border-color: transparent;
+ background-color: currentColor;
+}
+
+[type='file'] {
+ background: unset;
+ border-color: inherit;
+ border-width: 0;
+ border-radius: 0;
+ padding: 0;
+ font-size: unset;
+ line-height: inherit;
+}
+
+[type='file']:focus {
+ outline: 1px solid ButtonText;
+ outline: 1px auto -webkit-focus-ring-color;
+}
+
+:root {
+ --amber1: #fefdfb;
+ --amber2: #fefbe9;
+ --amber3: #fff7c2;
+ --amber4: #ffee9c;
+ --amber5: #fbe577;
+ --amber6: #f3d673;
+ --amber7: #e9c162;
+ --amber8: #e2a336;
+ --amber9: #ffc53d;
+ --amber10: #ffba18;
+ --amber11: #ab6400;
+ --amber12: #4f3422;
+ --amberA1: #c0800004;
+ --amberA2: #f4d10016;
+ --amberA3: #ffde003d;
+ --amberA4: #ffd40063;
+ --amberA5: #f8cf0088;
+ --amberA6: #eab5008c;
+ --amberA7: #dc9b009d;
+ --amberA8: #da8a00c9;
+ --amberA9: #ffb300c2;
+ --amberA10: #ffb300e7;
+ --amberA11: #ab6400;
+ --amberA12: #341500dd;
+ --blackA1: rgba(0, 0, 0, 0.05);
+ --blackA2: rgba(0, 0, 0, 0.1);
+ --blackA3: rgba(0, 0, 0, 0.15);
+ --blackA4: rgba(0, 0, 0, 0.2);
+ --blackA5: rgba(0, 0, 0, 0.3);
+ --blackA6: rgba(0, 0, 0, 0.4);
+ --blackA7: rgba(0, 0, 0, 0.5);
+ --blackA8: rgba(0, 0, 0, 0.6);
+ --blackA9: rgba(0, 0, 0, 0.7);
+ --blackA10: rgba(0, 0, 0, 0.8);
+ --blackA11: rgba(0, 0, 0, 0.9);
+ --blackA12: rgba(0, 0, 0, 0.95);
+ --blue1: #fbfdff;
+ --blue2: #f4faff;
+ --blue3: #e6f4fe;
+ --blue4: #d5efff;
+ --blue5: #c2e5ff;
+ --blue6: #acd8fc;
+ --blue7: #8ec8f6;
+ --blue8: #5eb1ef;
+ --blue9: #0090ff;
+ --blue10: #0588f0;
+ --blue11: #0d74ce;
+ --blue12: #113264;
+ --blueA1: #0080ff04;
+ --blueA2: #008cff0b;
+ --blueA3: #008ff519;
+ --blueA4: #009eff2a;
+ --blueA5: #0093ff3d;
+ --blueA6: #0088f653;
+ --blueA7: #0083eb71;
+ --blueA8: #0084e6a1;
+ --blueA9: #0090ff;
+ --blueA10: #0086f0fa;
+ --blueA11: #006dcbf2;
+ --blueA12: #002359ee;
+ --bronze1: #fdfcfc;
+ --bronze2: #fdf7f5;
+ --bronze3: #f6edea;
+ --bronze4: #efe4df;
+ --bronze5: #e7d9d3;
+ --bronze6: #dfcdc5;
+ --bronze7: #d3bcb3;
+ --bronze8: #c2a499;
+ --bronze9: #a18072;
+ --bronze10: #957468;
+ --bronze11: #7d5e54;
+ --bronze12: #43302b;
+ --bronzeA1: #55000003;
+ --bronzeA2: #cc33000a;
+ --bronzeA3: #92250015;
+ --bronzeA4: #80280020;
+ --bronzeA5: #7423002c;
+ --bronzeA6: #7324003a;
+ --bronzeA7: #6c1f004c;
+ --bronzeA8: #671c0066;
+ --bronzeA9: #551a008d;
+ --bronzeA10: #4c150097;
+ --bronzeA11: #3d0f00ab;
+ --bronzeA12: #1d0600d4;
+ --brown1: #fefdfc;
+ --brown2: #fcf9f6;
+ --brown3: #f6eee7;
+ --brown4: #f0e4d9;
+ --brown5: #ebdaca;
+ --brown6: #e4cdb7;
+ --brown7: #dcbc9f;
+ --brown8: #cea37e;
+ --brown9: #ad7f58;
+ --brown10: #a07553;
+ --brown11: #815e46;
+ --brown12: #3e332e;
+ --brownA1: #aa550003;
+ --brownA2: #aa550009;
+ --brownA3: #a04b0018;
+ --brownA4: #9b4a0026;
+ --brownA5: #9f4d0035;
+ --brownA6: #a04e0048;
+ --brownA7: #a34e0060;
+ --brownA8: #9f4a0081;
+ --brownA9: #823c00a7;
+ --brownA10: #723300ac;
+ --brownA11: #522100b9;
+ --brownA12: #140600d1;
+ --crimson1: #fffcfd;
+ --crimson2: #fef7f9;
+ --crimson3: #ffe9f0;
+ --crimson4: #fedce7;
+ --crimson5: #facedd;
+ --crimson6: #f3bed1;
+ --crimson7: #eaacc3;
+ --crimson8: #e093b2;
+ --crimson9: #e93d82;
+ --crimson10: #df3478;
+ --crimson11: #cb1d63;
+ --crimson12: #621639;
+ --crimsonA1: #ff005503;
+ --crimsonA2: #e0004008;
+ --crimsonA3: #ff005216;
+ --crimsonA4: #f8005123;
+ --crimsonA5: #e5004f31;
+ --crimsonA6: #d0004b41;
+ --crimsonA7: #bf004753;
+ --crimsonA8: #b6004a6c;
+ --crimsonA9: #e2005bc2;
+ --crimsonA10: #d70056cb;
+ --crimsonA11: #c4004fe2;
+ --crimsonA12: #530026e9;
+ --cyan1: #fafdfe;
+ --cyan2: #f2fafb;
+ --cyan3: #def7f9;
+ --cyan4: #caf1f6;
+ --cyan5: #b5e9f0;
+ --cyan6: #9ddde7;
+ --cyan7: #7dcedc;
+ --cyan8: #3db9cf;
+ --cyan9: #00a2c7;
+ --cyan10: #0797b9;
+ --cyan11: #107d98;
+ --cyan12: #0d3c48;
+ --cyanA1: #0099cc05;
+ --cyanA2: #009db10d;
+ --cyanA3: #00c2d121;
+ --cyanA4: #00bcd435;
+ --cyanA5: #01b4cc4a;
+ --cyanA6: #00a7c162;
+ --cyanA7: #009fbb82;
+ --cyanA8: #00a3c0c2;
+ --cyanA9: #00a2c7;
+ --cyanA10: #0094b7f8;
+ --cyanA11: #007491ef;
+ --cyanA12: #00323ef2;
+ --gold1: #fdfdfc;
+ --gold2: #faf9f2;
+ --gold3: #f2f0e7;
+ --gold4: #eae6db;
+ --gold5: #e1dccf;
+ --gold6: #d8d0bf;
+ --gold7: #cbc0aa;
+ --gold8: #b9a88d;
+ --gold9: #978365;
+ --gold10: #8c7a5e;
+ --gold11: #71624b;
+ --gold12: #3b352b;
+ --goldA1: #55550003;
+ --goldA2: #9d8a000d;
+ --goldA3: #75600018;
+ --goldA4: #6b4e0024;
+ --goldA5: #60460030;
+ --goldA6: #64440040;
+ --goldA7: #63420055;
+ --goldA8: #633d0072;
+ --goldA9: #5332009a;
+ --goldA10: #492d00a1;
+ --goldA11: #362100b4;
+ --goldA12: #130c00d4;
+ --grass1: #fbfefb;
+ --grass2: #f5fbf5;
+ --grass3: #e9f6e9;
+ --grass4: #daf1db;
+ --grass5: #c9e8ca;
+ --grass6: #b2ddb5;
+ --grass7: #94ce9a;
+ --grass8: #65ba74;
+ --grass9: #46a758;
+ --grass10: #3e9b4f;
+ --grass11: #2a7e3b;
+ --grass12: #203c25;
+ --grassA1: #00c00004;
+ --grassA2: #0099000a;
+ --grassA3: #00970016;
+ --grassA4: #009f0725;
+ --grassA5: #00930536;
+ --grassA6: #008f0a4d;
+ --grassA7: #018b0f6b;
+ --grassA8: #008d199a;
+ --grassA9: #008619b9;
+ --grassA10: #007b17c1;
+ --grassA11: #006514d5;
+ --grassA12: #002006df;
+ --gray1: #fcfcfc;
+ --gray2: #f9f9f9;
+ --gray3: #f0f0f0;
+ --gray4: #e8e8e8;
+ --gray5: #e0e0e0;
+ --gray6: #d9d9d9;
+ --gray7: #cecece;
+ --gray8: #bbbbbb;
+ --gray9: #8d8d8d;
+ --gray10: #838383;
+ --gray11: #646464;
+ --gray12: #202020;
+ --grayA1: #00000003;
+ --grayA2: #00000006;
+ --grayA3: #0000000f;
+ --grayA4: #00000017;
+ --grayA5: #0000001f;
+ --grayA6: #00000026;
+ --grayA7: #00000031;
+ --grayA8: #00000044;
+ --grayA9: #00000072;
+ --grayA10: #0000007c;
+ --grayA11: #0000009b;
+ --grayA12: #000000df;
+ --green1: #fbfefc;
+ --green2: #f4fbf6;
+ --green3: #e6f6eb;
+ --green4: #d6f1df;
+ --green5: #c4e8d1;
+ --green6: #adddc0;
+ --green7: #8eceaa;
+ --green8: #5bb98b;
+ --green9: #30a46c;
+ --green10: #2b9a66;
+ --green11: #218358;
+ --green12: #193b2d;
+ --greenA1: #00c04004;
+ --greenA2: #00a32f0b;
+ --greenA3: #00a43319;
+ --greenA4: #00a83829;
+ --greenA5: #019c393b;
+ --greenA6: #00963c52;
+ --greenA7: #00914071;
+ --greenA8: #00924ba4;
+ --greenA9: #008f4acf;
+ --greenA10: #008647d4;
+ --greenA11: #00713fde;
+ --greenA12: #002616e6;
+ --indigo1: #fdfdfe;
+ --indigo2: #f7f9ff;
+ --indigo3: #edf2fe;
+ --indigo4: #e1e9ff;
+ --indigo5: #d2deff;
+ --indigo6: #c1d0ff;
+ --indigo7: #abbdf9;
+ --indigo8: #8da4ef;
+ --indigo9: #3e63dd;
+ --indigo10: #3358d4;
+ --indigo11: #3a5bc7;
+ --indigo12: #1f2d5c;
+ --indigoA1: #00008002;
+ --indigoA2: #0040ff08;
+ --indigoA3: #0047f112;
+ --indigoA4: #0044ff1e;
+ --indigoA5: #0044ff2d;
+ --indigoA6: #003eff3e;
+ --indigoA7: #0037ed54;
+ --indigoA8: #0034dc72;
+ --indigoA9: #0031d2c1;
+ --indigoA10: #002ec9cc;
+ --indigoA11: #002bb7c5;
+ --indigoA12: #001046e0;
+ --iris1: #fdfdff;
+ --iris2: #f8f8ff;
+ --iris3: #f0f1fe;
+ --iris4: #e6e7ff;
+ --iris5: #dadcff;
+ --iris6: #cbcdff;
+ --iris7: #b8baf8;
+ --iris8: #9b9ef0;
+ --iris9: #5b5bd6;
+ --iris10: #5151cd;
+ --iris11: #5753c6;
+ --iris12: #272962;
+ --irisA1: #0000ff02;
+ --irisA2: #0000ff07;
+ --irisA3: #0011ee0f;
+ --irisA4: #000bff19;
+ --irisA5: #000eff25;
+ --irisA6: #000aff34;
+ --irisA7: #0008e647;
+ --irisA8: #0008d964;
+ --irisA9: #0000c0a4;
+ --irisA10: #0000b6ae;
+ --irisA11: #0600abac;
+ --irisA12: #000246d8;
+ --jade1: #fbfefd;
+ --jade2: #f4fbf7;
+ --jade3: #e6f7ed;
+ --jade4: #d6f1e3;
+ --jade5: #c3e9d7;
+ --jade6: #acdec8;
+ --jade7: #8bceb6;
+ --jade8: #56ba9f;
+ --jade9: #29a383;
+ --jade10: #26997b;
+ --jade11: #208368;
+ --jade12: #1d3b31;
+ --jadeA1: #00c08004;
+ --jadeA2: #00a3460b;
+ --jadeA3: #00ae4819;
+ --jadeA4: #00a85129;
+ --jadeA5: #00a2553c;
+ --jadeA6: #009a5753;
+ --jadeA7: #00945f74;
+ --jadeA8: #00976ea9;
+ --jadeA9: #00916bd6;
+ --jadeA10: #008764d9;
+ --jadeA11: #007152df;
+ --jadeA12: #002217e2;
+ --lime1: #fcfdfa;
+ --lime2: #f8faf3;
+ --lime3: #eef6d6;
+ --lime4: #e2f0bd;
+ --lime5: #d3e7a6;
+ --lime6: #c2da91;
+ --lime7: #abc978;
+ --lime8: #8db654;
+ --lime9: #bdee63;
+ --lime10: #b0e64c;
+ --lime11: #5c7c2f;
+ --lime12: #37401c;
+ --limeA1: #66990005;
+ --limeA2: #6b95000c;
+ --limeA3: #96c80029;
+ --limeA4: #8fc60042;
+ --limeA5: #81bb0059;
+ --limeA6: #72aa006e;
+ --limeA7: #61990087;
+ --limeA8: #559200ab;
+ --limeA9: #93e4009c;
+ --limeA10: #8fdc00b3;
+ --limeA11: #375f00d0;
+ --limeA12: #1e2900e3;
+ --mauve1: #fdfcfd;
+ --mauve2: #faf9fb;
+ --mauve3: #f2eff3;
+ --mauve4: #eae7ec;
+ --mauve5: #e3dfe6;
+ --mauve6: #dbd8e0;
+ --mauve7: #d0cdd7;
+ --mauve8: #bcbac7;
+ --mauve9: #8e8c99;
+ --mauve10: #84828e;
+ --mauve11: #65636d;
+ --mauve12: #211f26;
+ --mauveA1: #55005503;
+ --mauveA2: #2b005506;
+ --mauveA3: #30004010;
+ --mauveA4: #20003618;
+ --mauveA5: #20003820;
+ --mauveA6: #14003527;
+ --mauveA7: #10003332;
+ --mauveA8: #08003145;
+ --mauveA9: #05001d73;
+ --mauveA10: #0500197d;
+ --mauveA11: #0400119c;
+ --mauveA12: #020008e0;
+ --mint1: #f9fefd;
+ --mint2: #f2fbf9;
+ --mint3: #ddf9f2;
+ --mint4: #c8f4e9;
+ --mint5: #b3ecde;
+ --mint6: #9ce0d0;
+ --mint7: #7ecfbd;
+ --mint8: #4cbba5;
+ --mint9: #86ead4;
+ --mint10: #7de0cb;
+ --mint11: #027864;
+ --mint12: #16433c;
+ --mintA1: #00d5aa06;
+ --mintA2: #00b18a0d;
+ --mintA3: #00d29e22;
+ --mintA4: #00cc9937;
+ --mintA5: #00c0914c;
+ --mintA6: #00b08663;
+ --mintA7: #00a17d81;
+ --mintA8: #009e7fb3;
+ --mintA9: #00d3a579;
+ --mintA10: #00c39982;
+ --mintA11: #007763fd;
+ --mintA12: #00312ae9;
+ --olive1: #fcfdfc;
+ --olive2: #f8faf8;
+ --olive3: #eff1ef;
+ --olive4: #e7e9e7;
+ --olive5: #dfe2df;
+ --olive6: #d7dad7;
+ --olive7: #cccfcc;
+ --olive8: #b9bcb8;
+ --olive9: #898e87;
+ --olive10: #7f847d;
+ --olive11: #60655f;
+ --olive12: #1d211c;
+ --oliveA1: #00550003;
+ --oliveA2: #00490007;
+ --oliveA3: #00200010;
+ --oliveA4: #00160018;
+ --oliveA5: #00180020;
+ --oliveA6: #00140028;
+ --oliveA7: #000f0033;
+ --oliveA8: #040f0047;
+ --oliveA9: #050f0078;
+ --oliveA10: #040e0082;
+ --oliveA11: #020a00a0;
+ --oliveA12: #010600e3;
+ --orange1: #fefcfb;
+ --orange2: #fff7ed;
+ --orange3: #ffefd6;
+ --orange4: #ffdfb5;
+ --orange5: #ffd19a;
+ --orange6: #ffc182;
+ --orange7: #f5ae73;
+ --orange8: #ec9455;
+ --orange9: #f76b15;
+ --orange10: #ef5f00;
+ --orange11: #cc4e00;
+ --orange12: #582d1d;
+ --orangeA1: #c0400004;
+ --orangeA2: #ff8e0012;
+ --orangeA3: #ff9c0029;
+ --orangeA4: #ff91014a;
+ --orangeA5: #ff8b0065;
+ --orangeA6: #ff81007d;
+ --orangeA7: #ed6c008c;
+ --orangeA8: #e35f00aa;
+ --orangeA9: #f65e00ea;
+ --orangeA10: #ef5f00;
+ --orangeA11: #cc4e00;
+ --orangeA12: #431200e2;
+ --pink1: #fffcfe;
+ --pink2: #fef7fb;
+ --pink3: #fee9f5;
+ --pink4: #fbdcef;
+ --pink5: #f6cee7;
+ --pink6: #efbfdd;
+ --pink7: #e7acd0;
+ --pink8: #dd93c2;
+ --pink9: #d6409f;
+ --pink10: #cf3897;
+ --pink11: #c2298a;
+ --pink12: #651249;
+ --pinkA1: #ff00aa03;
+ --pinkA2: #e0008008;
+ --pinkA3: #f4008c16;
+ --pinkA4: #e2008b23;
+ --pinkA5: #d1008331;
+ --pinkA6: #c0007840;
+ --pinkA7: #b6006f53;
+ --pinkA8: #af006f6c;
+ --pinkA9: #c8007fbf;
+ --pinkA10: #c2007ac7;
+ --pinkA11: #b60074d6;
+ --pinkA12: #59003bed;
+ --plum1: #fefcff;
+ --plum2: #fdf7fd;
+ --plum3: #fbebfb;
+ --plum4: #f7def8;
+ --plum5: #f2d1f3;
+ --plum6: #e9c2ec;
+ --plum7: #deade3;
+ --plum8: #cf91d8;
+ --plum9: #ab4aba;
+ --plum10: #a144af;
+ --plum11: #953ea3;
+ --plum12: #53195d;
+ --plumA1: #aa00ff03;
+ --plumA2: #c000c008;
+ --plumA3: #cc00cc14;
+ --plumA4: #c200c921;
+ --plumA5: #b700bd2e;
+ --plumA6: #a400b03d;
+ --plumA7: #9900a852;
+ --plumA8: #9000a56e;
+ --plumA9: #89009eb5;
+ --plumA10: #7f0092bb;
+ --plumA11: #730086c1;
+ --plumA12: #40004be6;
+ --purple1: #fefcfe;
+ --purple2: #fbf7fe;
+ --purple3: #f7edfe;
+ --purple4: #f2e2fc;
+ --purple5: #ead5f9;
+ --purple6: #e0c4f4;
+ --purple7: #d1afec;
+ --purple8: #be93e4;
+ --purple9: #8e4ec6;
+ --purple10: #8347b9;
+ --purple11: #8145b5;
+ --purple12: #402060;
+ --purpleA1: #aa00aa03;
+ --purpleA2: #8000e008;
+ --purpleA3: #8e00f112;
+ --purpleA4: #8d00e51d;
+ --purpleA5: #8000db2a;
+ --purpleA6: #7a01d03b;
+ --purpleA7: #6d00c350;
+ --purpleA8: #6600c06c;
+ --purpleA9: #5c00adb1;
+ --purpleA10: #53009eb8;
+ --purpleA11: #52009aba;
+ --purpleA12: #250049df;
+ --red1: #fffcfc;
+ --red2: #fff7f7;
+ --red3: #feebec;
+ --red4: #ffdbdc;
+ --red5: #ffcdce;
+ --red6: #fdbdbe;
+ --red7: #f4a9aa;
+ --red8: #eb8e90;
+ --red9: #e5484d;
+ --red10: #dc3e42;
+ --red11: #ce2c31;
+ --red12: #641723;
+ --redA1: #ff000003;
+ --redA2: #ff000008;
+ --redA3: #f3000d14;
+ --redA4: #ff000824;
+ --redA5: #ff000632;
+ --redA6: #f8000442;
+ --redA7: #df000356;
+ --redA8: #d2000571;
+ --redA9: #db0007b7;
+ --redA10: #d10005c1;
+ --redA11: #c40006d3;
+ --redA12: #55000de8;
+ --ruby1: #fffcfd;
+ --ruby2: #fff7f8;
+ --ruby3: #feeaed;
+ --ruby4: #ffdce1;
+ --ruby5: #ffced6;
+ --ruby6: #f8bfc8;
+ --ruby7: #efacb8;
+ --ruby8: #e592a3;
+ --ruby9: #e54666;
+ --ruby10: #dc3b5d;
+ --ruby11: #ca244d;
+ --ruby12: #64172b;
+ --rubyA1: #ff005503;
+ --rubyA2: #ff002008;
+ --rubyA3: #f3002515;
+ --rubyA4: #ff002523;
+ --rubyA5: #ff002a31;
+ --rubyA6: #e4002440;
+ --rubyA7: #ce002553;
+ --rubyA8: #c300286d;
+ --rubyA9: #db002cb9;
+ --rubyA10: #d2002cc4;
+ --rubyA11: #c10030db;
+ --rubyA12: #550016e8;
+ --sage1: #fbfdfc;
+ --sage2: #f7f9f8;
+ --sage3: #eef1f0;
+ --sage4: #e6e9e8;
+ --sage5: #dfe2e0;
+ --sage6: #d7dad9;
+ --sage7: #cbcfcd;
+ --sage8: #b8bcba;
+ --sage9: #868e8b;
+ --sage10: #7c8481;
+ --sage11: #5f6563;
+ --sage12: #1a211e;
+ --sageA1: #00804004;
+ --sageA2: #00402008;
+ --sageA3: #002d1e11;
+ --sageA4: #001f1519;
+ --sageA5: #00180820;
+ --sageA6: #00140d28;
+ --sageA7: #00140a34;
+ --sageA8: #000f0847;
+ --sageA9: #00110b79;
+ --sageA10: #00100a83;
+ --sageA11: #000a07a0;
+ --sageA12: #000805e5;
+ --sand1: #fdfdfc;
+ --sand2: #f9f9f8;
+ --sand3: #f1f0ef;
+ --sand4: #e9e8e6;
+ --sand5: #e2e1de;
+ --sand6: #dad9d6;
+ --sand7: #cfceca;
+ --sand8: #bcbbb5;
+ --sand9: #8d8d86;
+ --sand10: #82827c;
+ --sand11: #63635e;
+ --sand12: #21201c;
+ --sandA1: #55550003;
+ --sandA2: #25250007;
+ --sandA3: #20100010;
+ --sandA4: #1f150019;
+ --sandA5: #1f180021;
+ --sandA6: #19130029;
+ --sandA7: #19140035;
+ --sandA8: #1915014a;
+ --sandA9: #0f0f0079;
+ --sandA10: #0c0c0083;
+ --sandA11: #080800a1;
+ --sandA12: #060500e3;
+ --sky1: #f9feff;
+ --sky2: #f1fafd;
+ --sky3: #e1f6fd;
+ --sky4: #d1f0fa;
+ --sky5: #bee7f5;
+ --sky6: #a9daed;
+ --sky7: #8dcae3;
+ --sky8: #60b3d7;
+ --sky9: #7ce2fe;
+ --sky10: #74daf8;
+ --sky11: #00749e;
+ --sky12: #1d3e56;
+ --skyA1: #00d5ff06;
+ --skyA2: #00a4db0e;
+ --skyA3: #00b3ee1e;
+ --skyA4: #00ace42e;
+ --skyA5: #00a1d841;
+ --skyA6: #0092ca56;
+ --skyA7: #0089c172;
+ --skyA8: #0085bf9f;
+ --skyA9: #00c7fe83;
+ --skyA10: #00bcf38b;
+ --skyA11: #00749e;
+ --skyA12: #002540e2;
+ --slate1: #fcfcfd;
+ --slate2: #f9f9fb;
+ --slate3: #f0f0f3;
+ --slate4: #e8e8ec;
+ --slate5: #e0e1e6;
+ --slate6: #d9d9e0;
+ --slate7: #cdced6;
+ --slate8: #b9bbc6;
+ --slate9: #8b8d98;
+ --slate10: #80838d;
+ --slate11: #60646c;
+ --slate12: #1c2024;
+ --slateA1: #00005503;
+ --slateA2: #00005506;
+ --slateA3: #0000330f;
+ --slateA4: #00002d17;
+ --slateA5: #0009321f;
+ --slateA6: #00002f26;
+ --slateA7: #00062e32;
+ --slateA8: #00083046;
+ --slateA9: #00051d74;
+ --slateA10: #00071b7f;
+ --slateA11: #0007149f;
+ --slateA12: #000509e3;
+ --teal1: #fafefd;
+ --teal2: #f3fbf9;
+ --teal3: #e0f8f3;
+ --teal4: #ccf3ea;
+ --teal5: #b8eae0;
+ --teal6: #a1ded2;
+ --teal7: #83cdc1;
+ --teal8: #53b9ab;
+ --teal9: #12a594;
+ --teal10: #0d9b8a;
+ --teal11: #008573;
+ --teal12: #0d3d38;
+ --tealA1: #00cc9905;
+ --tealA2: #00aa800c;
+ --tealA3: #00c69d1f;
+ --tealA4: #00c39633;
+ --tealA5: #00b49047;
+ --tealA6: #00a6855e;
+ --tealA7: #0099807c;
+ --tealA8: #009783ac;
+ --tealA9: #009e8ced;
+ --tealA10: #009684f2;
+ --tealA11: #008573;
+ --tealA12: #00332df2;
+ --tomato1: #fffcfc;
+ --tomato2: #fff8f7;
+ --tomato3: #feebe7;
+ --tomato4: #ffdcd3;
+ --tomato5: #ffcdc2;
+ --tomato6: #fdbdaf;
+ --tomato7: #f5a898;
+ --tomato8: #ec8e7b;
+ --tomato9: #e54d2e;
+ --tomato10: #dd4425;
+ --tomato11: #d13415;
+ --tomato12: #5c271f;
+ --tomatoA1: #ff000003;
+ --tomatoA2: #ff200008;
+ --tomatoA3: #f52b0018;
+ --tomatoA4: #ff35002c;
+ --tomatoA5: #ff2e003d;
+ --tomatoA6: #f92d0050;
+ --tomatoA7: #e7280067;
+ --tomatoA8: #db250084;
+ --tomatoA9: #df2600d1;
+ --tomatoA10: #d72400da;
+ --tomatoA11: #cd2200ea;
+ --tomatoA12: #460900e0;
+ --violet1: #fdfcfe;
+ --violet2: #faf8ff;
+ --violet3: #f4f0fe;
+ --violet4: #ebe4ff;
+ --violet5: #e1d9ff;
+ --violet6: #d4cafe;
+ --violet7: #c2b5f5;
+ --violet8: #aa99ec;
+ --violet9: #6e56cf;
+ --violet10: #654dc4;
+ --violet11: #6550b9;
+ --violet12: #2f265f;
+ --violetA1: #5500aa03;
+ --violetA2: #4900ff07;
+ --violetA3: #4400ee0f;
+ --violetA4: #4300ff1b;
+ --violetA5: #3600ff26;
+ --violetA6: #3100fb35;
+ --violetA7: #2d01dd4a;
+ --violetA8: #2b00d066;
+ --violetA9: #2400b7a9;
+ --violetA10: #2300abb2;
+ --violetA11: #1f0099af;
+ --violetA12: #0b0043d9;
+ --whiteA1: rgba(255, 255, 255, 0.05);
+ --whiteA2: rgba(255, 255, 255, 0.1);
+ --whiteA3: rgba(255, 255, 255, 0.15);
+ --whiteA4: rgba(255, 255, 255, 0.2);
+ --whiteA5: rgba(255, 255, 255, 0.3);
+ --whiteA6: rgba(255, 255, 255, 0.4);
+ --whiteA7: rgba(255, 255, 255, 0.5);
+ --whiteA8: rgba(255, 255, 255, 0.6);
+ --whiteA9: rgba(255, 255, 255, 0.7);
+ --whiteA10: rgba(255, 255, 255, 0.8);
+ --whiteA11: rgba(255, 255, 255, 0.9);
+ --whiteA12: rgba(255, 255, 255, 0.95);
+ --yellow1: #fdfdf9;
+ --yellow2: #fefce9;
+ --yellow3: #fffab8;
+ --yellow4: #fff394;
+ --yellow5: #ffe770;
+ --yellow6: #f3d768;
+ --yellow7: #e4c767;
+ --yellow8: #d5ae39;
+ --yellow9: #ffe629;
+ --yellow10: #ffdc00;
+ --yellow11: #9e6c00;
+ --yellow12: #473b1f;
+ --yellowA1: #aaaa0006;
+ --yellowA2: #f4dd0016;
+ --yellowA3: #ffee0047;
+ --yellowA4: #ffe3016b;
+ --yellowA5: #ffd5008f;
+ --yellowA6: #ebbc0097;
+ --yellowA7: #d2a10098;
+ --yellowA8: #c99700c6;
+ --yellowA9: #ffe100d6;
+ --yellowA10: #ffdc00;
+ --yellowA11: #9e6c00;
+ --yellowA12: #2e2000e0;
+}
+
+.dark {
+ --amber1: #16120c;
+ --amber2: #1d180f;
+ --amber3: #302008;
+ --amber4: #3f2700;
+ --amber5: #4d3000;
+ --amber6: #5c3d05;
+ --amber7: #714f19;
+ --amber8: #8f6424;
+ --amber9: #ffc53d;
+ --amber10: #ffd60a;
+ --amber11: #ffca16;
+ --amber12: #ffe7b3;
+ --amberA1: #e63c0006;
+ --amberA2: #fd9b000d;
+ --amberA3: #fa820022;
+ --amberA4: #fc820032;
+ --amberA5: #fd8b0041;
+ --amberA6: #fd9b0051;
+ --amberA7: #ffab2567;
+ --amberA8: #ffae3587;
+ --amberA9: #ffc53d;
+ --amberA10: #ffd60a;
+ --amberA11: #ffca16;
+ --amberA12: #ffe7b3;
+ --blue1: #0d1520;
+ --blue2: #111927;
+ --blue3: #0d2847;
+ --blue4: #003362;
+ --blue5: #004074;
+ --blue6: #104d87;
+ --blue7: #205d9e;
+ --blue8: #2870bd;
+ --blue9: #0090ff;
+ --blue10: #3b9eff;
+ --blue11: #70b8ff;
+ --blue12: #c2e6ff;
+ --blueA1: #004df211;
+ --blueA2: #1166fb18;
+ --blueA3: #0077ff3a;
+ --blueA4: #0075ff57;
+ --blueA5: #0081fd6b;
+ --blueA6: #0f89fd7f;
+ --blueA7: #2a91fe98;
+ --blueA8: #3094feb9;
+ --blueA9: #0090ff;
+ --blueA10: #3b9eff;
+ --blueA11: #70b8ff;
+ --blueA12: #c2e6ff;
+ --bronze1: #141110;
+ --bronze2: #1c1917;
+ --bronze3: #262220;
+ --bronze4: #302a27;
+ --bronze5: #3b3330;
+ --bronze6: #493e3a;
+ --bronze7: #5a4c47;
+ --bronze8: #6f5f58;
+ --bronze9: #a18072;
+ --bronze10: #ae8c7e;
+ --bronze11: #d4b3a5;
+ --bronze12: #ede0d9;
+ --bronzeA1: #d1110004;
+ --bronzeA2: #fbbc910c;
+ --bronzeA3: #faceb817;
+ --bronzeA4: #facdb622;
+ --bronzeA5: #ffd2c12d;
+ --bronzeA6: #ffd1c03c;
+ --bronzeA7: #fdd0c04f;
+ --bronzeA8: #ffd6c565;
+ --bronzeA9: #fec7b09b;
+ --bronzeA10: #fecab5a9;
+ --bronzeA11: #ffd7c6d1;
+ --bronzeA12: #fff1e9ec;
+ --brown1: #12110f;
+ --brown2: #1c1816;
+ --brown3: #28211d;
+ --brown4: #322922;
+ --brown5: #3e3128;
+ --brown6: #4d3c2f;
+ --brown7: #614a39;
+ --brown8: #7c5f46;
+ --brown9: #ad7f58;
+ --brown10: #b88c67;
+ --brown11: #dbb594;
+ --brown12: #f2e1ca;
+ --brownA1: #91110002;
+ --brownA2: #fba67c0c;
+ --brownA3: #fcb58c19;
+ --brownA4: #fbbb8a24;
+ --brownA5: #fcb88931;
+ --brownA6: #fdba8741;
+ --brownA7: #ffbb8856;
+ --brownA8: #ffbe8773;
+ --brownA9: #feb87da8;
+ --brownA10: #ffc18cb3;
+ --brownA11: #fed1aad9;
+ --brownA12: #feecd4f2;
+ --crimson1: #191114;
+ --crimson2: #201318;
+ --crimson3: #381525;
+ --crimson4: #4d122f;
+ --crimson5: #5c1839;
+ --crimson6: #6d2545;
+ --crimson7: #873356;
+ --crimson8: #b0436e;
+ --crimson9: #e93d82;
+ --crimson10: #ee518a;
+ --crimson11: #ff92ad;
+ --crimson12: #fdd3e8;
+ --crimsonA1: #f4126709;
+ --crimsonA2: #f22f7a11;
+ --crimsonA3: #fe2a8b2a;
+ --crimsonA4: #fd158741;
+ --crimsonA5: #fd278f51;
+ --crimsonA6: #fe459763;
+ --crimsonA7: #fd559b7f;
+ --crimsonA8: #fe5b9bab;
+ --crimsonA9: #fe418de8;
+ --crimsonA10: #ff5693ed;
+ --crimsonA11: #ff92ad;
+ --crimsonA12: #ffd5eafd;
+ --cyan1: #0b161a;
+ --cyan2: #101b20;
+ --cyan3: #082c36;
+ --cyan4: #003848;
+ --cyan5: #004558;
+ --cyan6: #045468;
+ --cyan7: #12677e;
+ --cyan8: #11809c;
+ --cyan9: #00a2c7;
+ --cyan10: #23afd0;
+ --cyan11: #4ccce6;
+ --cyan12: #b6ecf7;
+ --cyanA1: #0091f70a;
+ --cyanA2: #02a7f211;
+ --cyanA3: #00befd28;
+ --cyanA4: #00baff3b;
+ --cyanA5: #00befd4d;
+ --cyanA6: #00c7fd5e;
+ --cyanA7: #14cdff75;
+ --cyanA8: #11cfff95;
+ --cyanA9: #00cfffc3;
+ --cyanA10: #28d6ffcd;
+ --cyanA11: #52e1fee5;
+ --cyanA12: #bbf3fef7;
+ --gold1: #121211;
+ --gold2: #1b1a17;
+ --gold3: #24231f;
+ --gold4: #2d2b26;
+ --gold5: #38352e;
+ --gold6: #444039;
+ --gold7: #544f46;
+ --gold8: #696256;
+ --gold9: #978365;
+ --gold10: #a39073;
+ --gold11: #cbb99f;
+ --gold12: #e8e2d9;
+ --goldA1: #91911102;
+ --goldA2: #f9e29d0b;
+ --goldA3: #f8ecbb15;
+ --goldA4: #ffeec41e;
+ --goldA5: #feecc22a;
+ --goldA6: #feebcb37;
+ --goldA7: #ffedcd48;
+ --goldA8: #fdeaca5f;
+ --goldA9: #ffdba690;
+ --goldA10: #fedfb09d;
+ --goldA11: #fee7c6c8;
+ --goldA12: #fef7ede7;
+ --grass1: #0e1511;
+ --grass2: #141a15;
+ --grass3: #1b2a1e;
+ --grass4: #1d3a24;
+ --grass5: #25482d;
+ --grass6: #2d5736;
+ --grass7: #366740;
+ --grass8: #3e7949;
+ --grass9: #46a758;
+ --grass10: #53b365;
+ --grass11: #71d083;
+ --grass12: #c2f0c2;
+ --grassA1: #00de1205;
+ --grassA2: #5ef7780a;
+ --grassA3: #70fe8c1b;
+ --grassA4: #57ff802c;
+ --grassA5: #68ff8b3b;
+ --grassA6: #71ff8f4b;
+ --grassA7: #77fd925d;
+ --grassA8: #77fd9070;
+ --grassA9: #65ff82a1;
+ --grassA10: #72ff8dae;
+ --grassA11: #89ff9fcd;
+ --grassA12: #ceffceef;
+ --gray1: #111111;
+ --gray2: #191919;
+ --gray3: #222222;
+ --gray4: #2a2a2a;
+ --gray5: #313131;
+ --gray6: #3a3a3a;
+ --gray7: #484848;
+ --gray8: #606060;
+ --gray9: #6e6e6e;
+ --gray10: #7b7b7b;
+ --gray11: #b4b4b4;
+ --gray12: #eeeeee;
+ --grayA1: #00000000;
+ --grayA2: #ffffff09;
+ --grayA3: #ffffff12;
+ --grayA4: #ffffff1b;
+ --grayA5: #ffffff22;
+ --grayA6: #ffffff2c;
+ --grayA7: #ffffff3b;
+ --grayA8: #ffffff55;
+ --grayA9: #ffffff64;
+ --grayA10: #ffffff72;
+ --grayA11: #ffffffaf;
+ --grayA12: #ffffffed;
+ --green1: #0e1512;
+ --green2: #121b17;
+ --green3: #132d21;
+ --green4: #113b29;
+ --green5: #174933;
+ --green6: #20573e;
+ --green7: #28684a;
+ --green8: #2f7c57;
+ --green9: #30a46c;
+ --green10: #33b074;
+ --green11: #3dd68c;
+ --green12: #b1f1cb;
+ --greenA1: #00de4505;
+ --greenA2: #29f99d0b;
+ --greenA3: #22ff991e;
+ --greenA4: #11ff992d;
+ --greenA5: #2bffa23c;
+ --greenA6: #44ffaa4b;
+ --greenA7: #50fdac5e;
+ --greenA8: #54ffad73;
+ --greenA9: #44ffa49e;
+ --greenA10: #43fea4ab;
+ --greenA11: #46fea5d4;
+ --greenA12: #bbffd7f0;
+ --indigo1: #11131f;
+ --indigo2: #141726;
+ --indigo3: #182449;
+ --indigo4: #1d2e62;
+ --indigo5: #253974;
+ --indigo6: #304384;
+ --indigo7: #3a4f97;
+ --indigo8: #435db1;
+ --indigo9: #3e63dd;
+ --indigo10: #5472e4;
+ --indigo11: #9eb1ff;
+ --indigo12: #d6e1ff;
+ --indigoA1: #1133ff0f;
+ --indigoA2: #3354fa17;
+ --indigoA3: #2f62ff3c;
+ --indigoA4: #3566ff57;
+ --indigoA5: #4171fd6b;
+ --indigoA6: #5178fd7c;
+ --indigoA7: #5a7fff90;
+ --indigoA8: #5b81feac;
+ --indigoA9: #4671ffdb;
+ --indigoA10: #5c7efee3;
+ --indigoA11: #9eb1ff;
+ --indigoA12: #d6e1ff;
+ --iris1: #13131e;
+ --iris2: #171625;
+ --iris3: #202248;
+ --iris4: #262a65;
+ --iris5: #303374;
+ --iris6: #3d3e82;
+ --iris7: #4a4a95;
+ --iris8: #5958b1;
+ --iris9: #5b5bd6;
+ --iris10: #6e6ade;
+ --iris11: #b1a9ff;
+ --iris12: #e0dffe;
+ --irisA1: #3636fe0e;
+ --irisA2: #564bf916;
+ --irisA3: #525bff3b;
+ --irisA4: #4d58ff5a;
+ --irisA5: #5b62fd6b;
+ --irisA6: #6d6ffd7a;
+ --irisA7: #7777fe8e;
+ --irisA8: #7b7afeac;
+ --irisA9: #6a6afed4;
+ --irisA10: #7d79ffdc;
+ --irisA11: #b1a9ff;
+ --irisA12: #e1e0fffe;
+ --jade1: #0d1512;
+ --jade2: #121c18;
+ --jade3: #0f2e22;
+ --jade4: #0b3b2c;
+ --jade5: #114837;
+ --jade6: #1b5745;
+ --jade7: #246854;
+ --jade8: #2a7e68;
+ --jade9: #29a383;
+ --jade10: #27b08b;
+ --jade11: #1fd8a4;
+ --jade12: #adf0d4;
+ --jadeA1: #00de4505;
+ --jadeA2: #27fba60c;
+ --jadeA3: #02f99920;
+ --jadeA4: #00ffaa2d;
+ --jadeA5: #11ffb63b;
+ --jadeA6: #34ffc24b;
+ --jadeA7: #45fdc75e;
+ --jadeA8: #48ffcf75;
+ --jadeA9: #38feca9d;
+ --jadeA10: #31fec7ab;
+ --jadeA11: #21fec0d6;
+ --jadeA12: #b8ffe1ef;
+ --lime1: #11130c;
+ --lime2: #151a10;
+ --lime3: #1f2917;
+ --lime4: #29371d;
+ --lime5: #334423;
+ --lime6: #3d522a;
+ --lime7: #496231;
+ --lime8: #577538;
+ --lime9: #bdee63;
+ --lime10: #d4ff70;
+ --lime11: #bde56c;
+ --lime12: #e3f7ba;
+ --limeA1: #11bb0003;
+ --limeA2: #78f7000a;
+ --limeA3: #9bfd4c1a;
+ --limeA4: #a7fe5c29;
+ --limeA5: #affe6537;
+ --limeA6: #b2fe6d46;
+ --limeA7: #b6ff6f57;
+ --limeA8: #b6fd6d6c;
+ --limeA9: #caff69ed;
+ --limeA10: #d4ff70;
+ --limeA11: #d1fe77e4;
+ --limeA12: #e9febff7;
+ --mauve1: #121113;
+ --mauve2: #1a191b;
+ --mauve3: #232225;
+ --mauve4: #2b292d;
+ --mauve5: #323035;
+ --mauve6: #3c393f;
+ --mauve7: #49474e;
+ --mauve8: #625f69;
+ --mauve9: #6f6d78;
+ --mauve10: #7c7a85;
+ --mauve11: #b5b2bc;
+ --mauve12: #eeeef0;
+ --mauveA1: #00000000;
+ --mauveA2: #f5f4f609;
+ --mauveA3: #ebeaf814;
+ --mauveA4: #eee5f81d;
+ --mauveA5: #efe6fe25;
+ --mauveA6: #f1e6fd30;
+ --mauveA7: #eee9ff40;
+ --mauveA8: #eee7ff5d;
+ --mauveA9: #eae6fd6e;
+ --mauveA10: #ece9fd7c;
+ --mauveA11: #f5f1ffb7;
+ --mauveA12: #fdfdffef;
+ --mint1: #0e1515;
+ --mint2: #0f1b1b;
+ --mint3: #092c2b;
+ --mint4: #003a38;
+ --mint5: #004744;
+ --mint6: #105650;
+ --mint7: #1e685f;
+ --mint8: #277f70;
+ --mint9: #86ead4;
+ --mint10: #a8f5e5;
+ --mint11: #58d5ba;
+ --mint12: #c4f5e1;
+ --mintA1: #00dede05;
+ --mintA2: #00f9f90b;
+ --mintA3: #00fff61d;
+ --mintA4: #00fff42c;
+ --mintA5: #00fff23a;
+ --mintA6: #0effeb4a;
+ --mintA7: #34fde55e;
+ --mintA8: #41ffdf76;
+ --mintA9: #92ffe7e9;
+ --mintA10: #aefeedf5;
+ --mintA11: #67ffded2;
+ --mintA12: #cbfee9f5;
+ --olive1: #111210;
+ --olive2: #181917;
+ --olive3: #212220;
+ --olive4: #282a27;
+ --olive5: #2f312e;
+ --olive6: #383a36;
+ --olive7: #454843;
+ --olive8: #5c625b;
+ --olive9: #687066;
+ --olive10: #767d74;
+ --olive11: #afb5ad;
+ --olive12: #eceeec;
+ --oliveA1: #00000000;
+ --oliveA2: #f1f2f008;
+ --oliveA3: #f4f5f312;
+ --oliveA4: #f3fef21a;
+ --oliveA5: #f2fbf122;
+ --oliveA6: #f4faed2c;
+ --oliveA7: #f2fced3b;
+ --oliveA8: #edfdeb57;
+ --oliveA9: #ebfde766;
+ --oliveA10: #f0fdec74;
+ --oliveA11: #f6fef4b0;
+ --oliveA12: #fdfffded;
+ --orange1: #17120e;
+ --orange2: #1e160f;
+ --orange3: #331e0b;
+ --orange4: #462100;
+ --orange5: #562800;
+ --orange6: #66350c;
+ --orange7: #7e451d;
+ --orange8: #a35829;
+ --orange9: #f76b15;
+ --orange10: #ff801f;
+ --orange11: #ffa057;
+ --orange12: #ffe0c2;
+ --orangeA1: #ec360007;
+ --orangeA2: #fe6d000e;
+ --orangeA3: #fb6a0025;
+ --orangeA4: #ff590039;
+ --orangeA5: #ff61004a;
+ --orangeA6: #fd75045c;
+ --orangeA7: #ff832c75;
+ --orangeA8: #fe84389d;
+ --orangeA9: #fe6d15f7;
+ --orangeA10: #ff801f;
+ --orangeA11: #ffa057;
+ --orangeA12: #ffe0c2;
+ --pink1: #191117;
+ --pink2: #21121d;
+ --pink3: #37172f;
+ --pink4: #4b143d;
+ --pink5: #591c47;
+ --pink6: #692955;
+ --pink7: #833869;
+ --pink8: #a84885;
+ --pink9: #d6409f;
+ --pink10: #de51a8;
+ --pink11: #ff8dcc;
+ --pink12: #fdd1ea;
+ --pinkA1: #f412bc09;
+ --pinkA2: #f420bb12;
+ --pinkA3: #fe37cc29;
+ --pinkA4: #fc1ec43f;
+ --pinkA5: #fd35c24e;
+ --pinkA6: #fd51c75f;
+ --pinkA7: #fd62c87b;
+ --pinkA8: #ff68c8a2;
+ --pinkA9: #fe49bcd4;
+ --pinkA10: #ff5cc0dc;
+ --pinkA11: #ff8dcc;
+ --pinkA12: #ffd3ecfd;
+ --plum1: #181118;
+ --plum2: #201320;
+ --plum3: #351a35;
+ --plum4: #451d47;
+ --plum5: #512454;
+ --plum6: #5e3061;
+ --plum7: #734079;
+ --plum8: #92549c;
+ --plum9: #ab4aba;
+ --plum10: #b658c4;
+ --plum11: #e796f3;
+ --plum12: #f4d4f4;
+ --plumA1: #f112f108;
+ --plumA2: #f22ff211;
+ --plumA3: #fd4cfd27;
+ --plumA4: #f646ff3a;
+ --plumA5: #f455ff48;
+ --plumA6: #f66dff56;
+ --plumA7: #f07cfd70;
+ --plumA8: #ee84ff95;
+ --plumA9: #e961feb6;
+ --plumA10: #ed70ffc0;
+ --plumA11: #f19cfef3;
+ --plumA12: #feddfef4;
+ --purple1: #18111b;
+ --purple2: #1e1523;
+ --purple3: #301c3b;
+ --purple4: #3d224e;
+ --purple5: #48295c;
+ --purple6: #54346b;
+ --purple7: #664282;
+ --purple8: #8457aa;
+ --purple9: #8e4ec6;
+ --purple10: #9a5cd0;
+ --purple11: #d19dff;
+ --purple12: #ecd9fa;
+ --purpleA1: #b412f90b;
+ --purpleA2: #b744f714;
+ --purpleA3: #c150ff2d;
+ --purpleA4: #bb53fd42;
+ --purpleA5: #be5cfd51;
+ --purpleA6: #c16dfd61;
+ --purpleA7: #c378fd7a;
+ --purpleA8: #c47effa4;
+ --purpleA9: #b661ffc2;
+ --purpleA10: #bc6fffcd;
+ --purpleA11: #d19dff;
+ --purpleA12: #f1ddfffa;
+ --red1: #191111;
+ --red2: #201314;
+ --red3: #3b1219;
+ --red4: #500f1c;
+ --red5: #611623;
+ --red6: #72232d;
+ --red7: #8c333a;
+ --red8: #b54548;
+ --red9: #e5484d;
+ --red10: #ec5d5e;
+ --red11: #ff9592;
+ --red12: #ffd1d9;
+ --redA1: #f4121209;
+ --redA2: #f22f3e11;
+ --redA3: #ff173f2d;
+ --redA4: #fe0a3b44;
+ --redA5: #ff204756;
+ --redA6: #ff3e5668;
+ --redA7: #ff536184;
+ --redA8: #ff5d61b0;
+ --redA9: #fe4e54e4;
+ --redA10: #ff6465eb;
+ --redA11: #ff9592;
+ --redA12: #ffd1d9;
+ --ruby1: #191113;
+ --ruby2: #1e1517;
+ --ruby3: #3a141e;
+ --ruby4: #4e1325;
+ --ruby5: #5e1a2e;
+ --ruby6: #6f2539;
+ --ruby7: #883447;
+ --ruby8: #b3445a;
+ --ruby9: #e54666;
+ --ruby10: #ec5a72;
+ --ruby11: #ff949d;
+ --ruby12: #fed2e1;
+ --rubyA1: #f4124a09;
+ --rubyA2: #fe5a7f0e;
+ --rubyA3: #ff235d2c;
+ --rubyA4: #fd195e42;
+ --rubyA5: #fe2d6b53;
+ --rubyA6: #ff447665;
+ --rubyA7: #ff577d80;
+ --rubyA8: #ff5c7cae;
+ --rubyA9: #fe4c70e4;
+ --rubyA10: #ff617beb;
+ --rubyA11: #ff949d;
+ --rubyA12: #ffd3e2fe;
+ --sage1: #101211;
+ --sage2: #171918;
+ --sage3: #202221;
+ --sage4: #272a29;
+ --sage5: #2e3130;
+ --sage6: #373b39;
+ --sage7: #444947;
+ --sage8: #5b625f;
+ --sage9: #63706b;
+ --sage10: #717d79;
+ --sage11: #adb5b2;
+ --sage12: #eceeed;
+ --sageA1: #00000000;
+ --sageA2: #f0f2f108;
+ --sageA3: #f3f5f412;
+ --sageA4: #f2fefd1a;
+ --sageA5: #f1fbfa22;
+ --sageA6: #edfbf42d;
+ --sageA7: #edfcf73c;
+ --sageA8: #ebfdf657;
+ --sageA9: #dffdf266;
+ --sageA10: #e5fdf674;
+ --sageA11: #f4fefbb0;
+ --sageA12: #fdfffeed;
+ --sand1: #111110;
+ --sand2: #191918;
+ --sand3: #222221;
+ --sand4: #2a2a28;
+ --sand5: #31312e;
+ --sand6: #3b3a37;
+ --sand7: #494844;
+ --sand8: #62605b;
+ --sand9: #6f6d66;
+ --sand10: #7c7b74;
+ --sand11: #b5b3ad;
+ --sand12: #eeeeec;
+ --sandA1: #00000000;
+ --sandA2: #f4f4f309;
+ --sandA3: #f6f6f513;
+ --sandA4: #fefef31b;
+ --sandA5: #fbfbeb23;
+ --sandA6: #fffaed2d;
+ --sandA7: #fffbed3c;
+ --sandA8: #fff9eb57;
+ --sandA9: #fffae965;
+ --sandA10: #fffdee73;
+ --sandA11: #fffcf4b0;
+ --sandA12: #fffffded;
+ --sky1: #0d141f;
+ --sky2: #111a27;
+ --sky3: #112840;
+ --sky4: #113555;
+ --sky5: #154467;
+ --sky6: #1b537b;
+ --sky7: #1f6692;
+ --sky8: #197cae;
+ --sky9: #7ce2fe;
+ --sky10: #a8eeff;
+ --sky11: #75c7f0;
+ --sky12: #c2f3ff;
+ --skyA1: #0044ff0f;
+ --skyA2: #1171fb18;
+ --skyA3: #1184fc33;
+ --skyA4: #128fff49;
+ --skyA5: #1c9dfd5d;
+ --skyA6: #28a5ff72;
+ --skyA7: #2badfe8b;
+ --skyA8: #1db2fea9;
+ --skyA9: #7ce3fffe;
+ --skyA10: #a8eeff;
+ --skyA11: #7cd3ffef;
+ --skyA12: #c2f3ff;
+ --slate1: #111113;
+ --slate2: #18191b;
+ --slate3: #212225;
+ --slate4: #272a2d;
+ --slate5: #2e3135;
+ --slate6: #363a3f;
+ --slate7: #43484e;
+ --slate8: #5a6169;
+ --slate9: #696e77;
+ --slate10: #777b84;
+ --slate11: #b0b4ba;
+ --slate12: #edeef0;
+ --slateA1: #00000000;
+ --slateA2: #d8f4f609;
+ --slateA3: #ddeaf814;
+ --slateA4: #d3edf81d;
+ --slateA5: #d9edfe25;
+ --slateA6: #d6ebfd30;
+ --slateA7: #d9edff40;
+ --slateA8: #d9edff5d;
+ --slateA9: #dfebfd6d;
+ --slateA10: #e5edfd7b;
+ --slateA11: #f1f7feb5;
+ --slateA12: #fcfdffef;
+ --teal1: #0d1514;
+ --teal2: #111c1b;
+ --teal3: #0d2d2a;
+ --teal4: #023b37;
+ --teal5: #084843;
+ --teal6: #145750;
+ --teal7: #1c6961;
+ --teal8: #207e73;
+ --teal9: #12a594;
+ --teal10: #0eb39e;
+ --teal11: #0bd8b6;
+ --teal12: #adf0dd;
+ --tealA1: #00deab05;
+ --tealA2: #12fbe60c;
+ --tealA3: #00ffe61e;
+ --tealA4: #00ffe92d;
+ --tealA5: #00ffea3b;
+ --tealA6: #1cffe84b;
+ --tealA7: #2efde85f;
+ --tealA8: #32ffe775;
+ --tealA9: #13ffe49f;
+ --tealA10: #0dffe0ae;
+ --tealA11: #0afed5d6;
+ --tealA12: #b8ffebef;
+ --tomato1: #181111;
+ --tomato2: #1f1513;
+ --tomato3: #391714;
+ --tomato4: #4e1511;
+ --tomato5: #5e1c16;
+ --tomato6: #6e2920;
+ --tomato7: #853a2d;
+ --tomato8: #ac4d39;
+ --tomato9: #e54d2e;
+ --tomato10: #ec6142;
+ --tomato11: #ff977d;
+ --tomato12: #fbd3cb;
+ --tomatoA1: #f1121208;
+ --tomatoA2: #ff55330f;
+ --tomatoA3: #ff35232b;
+ --tomatoA4: #fd201142;
+ --tomatoA5: #fe332153;
+ --tomatoA6: #ff4f3864;
+ --tomatoA7: #fd644a7d;
+ --tomatoA8: #fe6d4ea7;
+ --tomatoA9: #fe5431e4;
+ --tomatoA10: #ff6847eb;
+ --tomatoA11: #ff977d;
+ --tomatoA12: #ffd6cefb;
+ --violet1: #14121f;
+ --violet2: #1b1525;
+ --violet3: #291f43;
+ --violet4: #33255b;
+ --violet5: #3c2e69;
+ --violet6: #473876;
+ --violet7: #56468b;
+ --violet8: #6958ad;
+ --violet9: #6e56cf;
+ --violet10: #7d66d9;
+ --violet11: #baa7ff;
+ --violet12: #e2ddfe;
+ --violetA1: #4422ff0f;
+ --violetA2: #853ff916;
+ --violetA3: #8354fe36;
+ --violetA4: #7d51fd50;
+ --violetA5: #845ffd5f;
+ --violetA6: #8f6cfd6d;
+ --violetA7: #9879ff83;
+ --violetA8: #977dfea8;
+ --violetA9: #8668ffcc;
+ --violetA10: #9176fed7;
+ --violetA11: #baa7ff;
+ --violetA12: #e3defffe;
+ --yellow1: #14120b;
+ --yellow2: #1b180f;
+ --yellow3: #2d2305;
+ --yellow4: #362b00;
+ --yellow5: #433500;
+ --yellow6: #524202;
+ --yellow7: #665417;
+ --yellow8: #836a21;
+ --yellow9: #ffe629;
+ --yellow10: #ffff57;
+ --yellow11: #f5e147;
+ --yellow12: #f6eeb4;
+ --yellowA1: #d1510004;
+ --yellowA2: #f9b4000b;
+ --yellowA3: #ffaa001e;
+ --yellowA4: #fdb70028;
+ --yellowA5: #febb0036;
+ --yellowA6: #fec40046;
+ --yellowA7: #fdcb225c;
+ --yellowA8: #fdca327b;
+ --yellowA9: #ffe629;
+ --yellowA10: #ffff57;
+ --yellowA11: #fee949f5;
+ --yellowA12: #fef6baf6;
+}
+
+@supports (color: color(display-p3 1 1 1)) {
+ @media (color-gamut: p3) {
+ :root {
+ --amber1: color(display-p3 0.995 0.992 0.985);
+ --amber2: color(display-p3 0.994 0.986 0.921);
+ --amber3: color(display-p3 0.994 0.969 0.782);
+ --amber4: color(display-p3 0.989 0.937 0.65);
+ --amber5: color(display-p3 0.97 0.902 0.527);
+ --amber6: color(display-p3 0.936 0.844 0.506);
+ --amber7: color(display-p3 0.89 0.762 0.443);
+ --amber8: color(display-p3 0.85 0.65 0.3);
+ --amber9: color(display-p3 1 0.77 0.26);
+ --amber10: color(display-p3 0.959 0.741 0.274);
+ --amber11: color(display-p3 0.64 0.4 0);
+ --amber12: color(display-p3 0.294 0.208 0.145);
+ --amberA1: color(display-p3 0.757 0.514 0.024 / 0.016);
+ --amberA2: color(display-p3 0.902 0.804 0.008 / 0.079);
+ --amberA3: color(display-p3 0.965 0.859 0.004 / 0.22);
+ --amberA4: color(display-p3 0.969 0.82 0.004 / 0.35);
+ --amberA5: color(display-p3 0.933 0.796 0.004 / 0.475);
+ --amberA6: color(display-p3 0.875 0.682 0.004 / 0.495);
+ --amberA7: color(display-p3 0.804 0.573 0 / 0.557);
+ --amberA8: color(display-p3 0.788 0.502 0 / 0.699);
+ --amberA9: color(display-p3 1 0.686 0 / 0.742);
+ --amberA10: color(display-p3 0.945 0.643 0 / 0.726);
+ --amberA11: color(display-p3 0.64 0.4 0);
+ --amberA12: color(display-p3 0.294 0.208 0.145);
+ --blackA1: color(display-p3 0 0 0 / 0.05);
+ --blackA2: color(display-p3 0 0 0 / 0.1);
+ --blackA3: color(display-p3 0 0 0 / 0.15);
+ --blackA4: color(display-p3 0 0 0 / 0.2);
+ --blackA5: color(display-p3 0 0 0 / 0.3);
+ --blackA6: color(display-p3 0 0 0 / 0.4);
+ --blackA7: color(display-p3 0 0 0 / 0.5);
+ --blackA8: color(display-p3 0 0 0 / 0.6);
+ --blackA9: color(display-p3 0 0 0 / 0.7);
+ --blackA10: color(display-p3 0 0 0 / 0.8);
+ --blackA11: color(display-p3 0 0 0 / 0.9);
+ --blackA12: color(display-p3 0 0 0 / 0.95);
+ --blue1: color(display-p3 0.986 0.992 0.999);
+ --blue2: color(display-p3 0.96 0.979 0.998);
+ --blue3: color(display-p3 0.912 0.956 0.991);
+ --blue4: color(display-p3 0.853 0.932 1);
+ --blue5: color(display-p3 0.788 0.894 0.998);
+ --blue6: color(display-p3 0.709 0.843 0.976);
+ --blue7: color(display-p3 0.606 0.777 0.947);
+ --blue8: color(display-p3 0.451 0.688 0.917);
+ --blue9: color(display-p3 0.247 0.556 0.969);
+ --blue10: color(display-p3 0.234 0.523 0.912);
+ --blue11: color(display-p3 0.15 0.44 0.84);
+ --blue12: color(display-p3 0.102 0.193 0.379);
+ --blueA1: color(display-p3 0.024 0.514 1 / 0.016);
+ --blueA2: color(display-p3 0.024 0.514 0.906 / 0.04);
+ --blueA3: color(display-p3 0.012 0.506 0.914 / 0.087);
+ --blueA4: color(display-p3 0.008 0.545 1 / 0.146);
+ --blueA5: color(display-p3 0.004 0.502 0.984 / 0.212);
+ --blueA6: color(display-p3 0.004 0.463 0.922 / 0.291);
+ --blueA7: color(display-p3 0.004 0.431 0.863 / 0.393);
+ --blueA8: color(display-p3 0 0.427 0.851 / 0.55);
+ --blueA9: color(display-p3 0 0.412 0.961 / 0.753);
+ --blueA10: color(display-p3 0 0.376 0.886 / 0.765);
+ --blueA11: color(display-p3 0.15 0.44 0.84);
+ --blueA12: color(display-p3 0.102 0.193 0.379);
+ --bronze1: color(display-p3 0.991 0.988 0.988);
+ --bronze2: color(display-p3 0.989 0.97 0.961);
+ --bronze3: color(display-p3 0.958 0.932 0.919);
+ --bronze4: color(display-p3 0.929 0.894 0.877);
+ --bronze5: color(display-p3 0.898 0.853 0.832);
+ --bronze6: color(display-p3 0.861 0.805 0.778);
+ --bronze7: color(display-p3 0.812 0.739 0.706);
+ --bronze8: color(display-p3 0.741 0.647 0.606);
+ --bronze9: color(display-p3 0.611 0.507 0.455);
+ --bronze10: color(display-p3 0.563 0.461 0.414);
+ --bronze11: color(display-p3 0.471 0.373 0.336);
+ --bronze12: color(display-p3 0.251 0.191 0.172);
+ --bronzeA1: color(display-p3 0.349 0.024 0.024 / 0.012);
+ --bronzeA2: color(display-p3 0.71 0.22 0.024 / 0.04);
+ --bronzeA3: color(display-p3 0.482 0.2 0.008 / 0.083);
+ --bronzeA4: color(display-p3 0.424 0.133 0.004 / 0.122);
+ --bronzeA5: color(display-p3 0.4 0.145 0.004 / 0.169);
+ --bronzeA6: color(display-p3 0.388 0.125 0.004 / 0.224);
+ --bronzeA7: color(display-p3 0.365 0.11 0.004 / 0.295);
+ --bronzeA8: color(display-p3 0.341 0.102 0.004 / 0.393);
+ --bronzeA9: color(display-p3 0.29 0.094 0 / 0.546);
+ --bronzeA10: color(display-p3 0.255 0.082 0 / 0.585);
+ --bronzeA11: color(display-p3 0.471 0.373 0.336);
+ --bronzeA12: color(display-p3 0.251 0.191 0.172);
+ --brown1: color(display-p3 0.995 0.992 0.989);
+ --brown2: color(display-p3 0.987 0.976 0.964);
+ --brown3: color(display-p3 0.959 0.936 0.909);
+ --brown4: color(display-p3 0.934 0.897 0.855);
+ --brown5: color(display-p3 0.909 0.856 0.798);
+ --brown6: color(display-p3 0.88 0.808 0.73);
+ --brown7: color(display-p3 0.841 0.742 0.639);
+ --brown8: color(display-p3 0.782 0.647 0.514);
+ --brown9: color(display-p3 0.651 0.505 0.368);
+ --brown10: color(display-p3 0.601 0.465 0.344);
+ --brown11: color(display-p3 0.485 0.374 0.288);
+ --brown12: color(display-p3 0.236 0.202 0.183);
+ --brownA1: color(display-p3 0.675 0.349 0.024 / 0.012);
+ --brownA2: color(display-p3 0.675 0.349 0.024 / 0.036);
+ --brownA3: color(display-p3 0.573 0.314 0.012 / 0.091);
+ --brownA4: color(display-p3 0.545 0.302 0.008 / 0.146);
+ --brownA5: color(display-p3 0.561 0.29 0.004 / 0.204);
+ --brownA6: color(display-p3 0.553 0.294 0.004 / 0.271);
+ --brownA7: color(display-p3 0.557 0.286 0.004 / 0.361);
+ --brownA8: color(display-p3 0.549 0.275 0.004 / 0.487);
+ --brownA9: color(display-p3 0.447 0.22 0 / 0.632);
+ --brownA10: color(display-p3 0.388 0.188 0 / 0.655);
+ --brownA11: color(display-p3 0.485 0.374 0.288);
+ --brownA12: color(display-p3 0.236 0.202 0.183);
+ --crimson1: color(display-p3 0.998 0.989 0.992);
+ --crimson2: color(display-p3 0.991 0.969 0.976);
+ --crimson3: color(display-p3 0.987 0.917 0.941);
+ --crimson4: color(display-p3 0.975 0.866 0.904);
+ --crimson5: color(display-p3 0.953 0.813 0.864);
+ --crimson6: color(display-p3 0.921 0.755 0.817);
+ --crimson7: color(display-p3 0.88 0.683 0.761);
+ --crimson8: color(display-p3 0.834 0.592 0.694);
+ --crimson9: color(display-p3 0.843 0.298 0.507);
+ --crimson10: color(display-p3 0.807 0.266 0.468);
+ --crimson11: color(display-p3 0.731 0.195 0.388);
+ --crimson12: color(display-p3 0.352 0.111 0.221);
+ --crimsonA1: color(display-p3 0.675 0.024 0.349 / 0.012);
+ --crimsonA2: color(display-p3 0.757 0.02 0.267 / 0.032);
+ --crimsonA3: color(display-p3 0.859 0.008 0.294 / 0.083);
+ --crimsonA4: color(display-p3 0.827 0.008 0.298 / 0.134);
+ --crimsonA5: color(display-p3 0.753 0.008 0.275 / 0.189);
+ --crimsonA6: color(display-p3 0.682 0.004 0.247 / 0.244);
+ --crimsonA7: color(display-p3 0.62 0.004 0.251 / 0.318);
+ --crimsonA8: color(display-p3 0.6 0.004 0.251 / 0.408);
+ --crimsonA9: color(display-p3 0.776 0 0.298 / 0.702);
+ --crimsonA10: color(display-p3 0.737 0 0.275 / 0.734);
+ --crimsonA11: color(display-p3 0.731 0.195 0.388);
+ --crimsonA12: color(display-p3 0.352 0.111 0.221);
+ --cyan1: color(display-p3 0.982 0.992 0.996);
+ --cyan2: color(display-p3 0.955 0.981 0.984);
+ --cyan3: color(display-p3 0.888 0.965 0.975);
+ --cyan4: color(display-p3 0.821 0.941 0.959);
+ --cyan5: color(display-p3 0.751 0.907 0.935);
+ --cyan6: color(display-p3 0.671 0.862 0.9);
+ --cyan7: color(display-p3 0.564 0.8 0.854);
+ --cyan8: color(display-p3 0.388 0.715 0.798);
+ --cyan9: color(display-p3 0.282 0.627 0.765);
+ --cyan10: color(display-p3 0.264 0.583 0.71);
+ --cyan11: color(display-p3 0.08 0.48 0.63);
+ --cyan12: color(display-p3 0.108 0.232 0.277);
+ --cyanA1: color(display-p3 0.02 0.608 0.804 / 0.02);
+ --cyanA2: color(display-p3 0.02 0.557 0.647 / 0.044);
+ --cyanA3: color(display-p3 0.004 0.694 0.796 / 0.114);
+ --cyanA4: color(display-p3 0.004 0.678 0.784 / 0.181);
+ --cyanA5: color(display-p3 0.004 0.624 0.733 / 0.248);
+ --cyanA6: color(display-p3 0.004 0.584 0.706 / 0.33);
+ --cyanA7: color(display-p3 0.004 0.541 0.667 / 0.436);
+ --cyanA8: color(display-p3 0 0.533 0.667 / 0.612);
+ --cyanA9: color(display-p3 0 0.482 0.675 / 0.718);
+ --cyanA10: color(display-p3 0 0.435 0.608 / 0.738);
+ --cyanA11: color(display-p3 0.08 0.48 0.63);
+ --cyanA12: color(display-p3 0.108 0.232 0.277);
+ --gold1: color(display-p3 0.992 0.992 0.989);
+ --gold2: color(display-p3 0.98 0.976 0.953);
+ --gold3: color(display-p3 0.947 0.94 0.909);
+ --gold4: color(display-p3 0.914 0.904 0.865);
+ --gold5: color(display-p3 0.88 0.865 0.816);
+ --gold6: color(display-p3 0.84 0.818 0.756);
+ --gold7: color(display-p3 0.788 0.753 0.677);
+ --gold8: color(display-p3 0.715 0.66 0.565);
+ --gold9: color(display-p3 0.579 0.517 0.41);
+ --gold10: color(display-p3 0.538 0.479 0.38);
+ --gold11: color(display-p3 0.433 0.386 0.305);
+ --gold12: color(display-p3 0.227 0.209 0.173);
+ --goldA1: color(display-p3 0.349 0.349 0.024 / 0.012);
+ --goldA2: color(display-p3 0.592 0.514 0.024 / 0.048);
+ --goldA3: color(display-p3 0.4 0.357 0.012 / 0.091);
+ --goldA4: color(display-p3 0.357 0.298 0.008 / 0.134);
+ --goldA5: color(display-p3 0.345 0.282 0.004 / 0.185);
+ --goldA6: color(display-p3 0.341 0.263 0.004 / 0.244);
+ --goldA7: color(display-p3 0.345 0.235 0.004 / 0.322);
+ --goldA8: color(display-p3 0.345 0.22 0.004 / 0.436);
+ --goldA9: color(display-p3 0.286 0.18 0 / 0.589);
+ --goldA10: color(display-p3 0.255 0.161 0 / 0.62);
+ --goldA11: color(display-p3 0.433 0.386 0.305);
+ --goldA12: color(display-p3 0.227 0.209 0.173);
+ --grass1: color(display-p3 0.986 0.996 0.985);
+ --grass2: color(display-p3 0.966 0.983 0.964);
+ --grass3: color(display-p3 0.923 0.965 0.917);
+ --grass4: color(display-p3 0.872 0.94 0.865);
+ --grass5: color(display-p3 0.811 0.908 0.802);
+ --grass6: color(display-p3 0.733 0.864 0.724);
+ --grass7: color(display-p3 0.628 0.803 0.622);
+ --grass8: color(display-p3 0.477 0.72 0.482);
+ --grass9: color(display-p3 0.38 0.647 0.378);
+ --grass10: color(display-p3 0.344 0.598 0.342);
+ --grass11: color(display-p3 0.263 0.488 0.261);
+ --grass12: color(display-p3 0.151 0.233 0.153);
+ --grassA1: color(display-p3 0.024 0.757 0.024 / 0.016);
+ --grassA2: color(display-p3 0.024 0.565 0.024 / 0.036);
+ --grassA3: color(display-p3 0.059 0.576 0.008 / 0.083);
+ --grassA4: color(display-p3 0.035 0.565 0.008 / 0.134);
+ --grassA5: color(display-p3 0.047 0.545 0.008 / 0.197);
+ --grassA6: color(display-p3 0.031 0.502 0.004 / 0.275);
+ --grassA7: color(display-p3 0.012 0.482 0.004 / 0.377);
+ --grassA8: color(display-p3 0 0.467 0.008 / 0.522);
+ --grassA9: color(display-p3 0.008 0.435 0 / 0.624);
+ --grassA10: color(display-p3 0.008 0.388 0 / 0.659);
+ --grassA11: color(display-p3 0.263 0.488 0.261);
+ --grassA12: color(display-p3 0.151 0.233 0.153);
+ --gray1: color(display-p3 0.988 0.988 0.988);
+ --gray2: color(display-p3 0.975 0.975 0.975);
+ --gray3: color(display-p3 0.939 0.939 0.939);
+ --gray4: color(display-p3 0.908 0.908 0.908);
+ --gray5: color(display-p3 0.88 0.88 0.88);
+ --gray6: color(display-p3 0.849 0.849 0.849);
+ --gray7: color(display-p3 0.807 0.807 0.807);
+ --gray8: color(display-p3 0.732 0.732 0.732);
+ --gray9: color(display-p3 0.553 0.553 0.553);
+ --gray10: color(display-p3 0.512 0.512 0.512);
+ --gray11: color(display-p3 0.392 0.392 0.392);
+ --gray12: color(display-p3 0.125 0.125 0.125);
+ --grayA1: color(display-p3 0 0 0 / 0.012);
+ --grayA2: color(display-p3 0 0 0 / 0.024);
+ --grayA3: color(display-p3 0 0 0 / 0.063);
+ --grayA4: color(display-p3 0 0 0 / 0.09);
+ --grayA5: color(display-p3 0 0 0 / 0.122);
+ --grayA6: color(display-p3 0 0 0 / 0.153);
+ --grayA7: color(display-p3 0 0 0 / 0.192);
+ --grayA8: color(display-p3 0 0 0 / 0.267);
+ --grayA9: color(display-p3 0 0 0 / 0.447);
+ --grayA10: color(display-p3 0 0 0 / 0.486);
+ --grayA11: color(display-p3 0 0 0 / 0.608);
+ --grayA12: color(display-p3 0 0 0 / 0.875);
+ --green1: color(display-p3 0.986 0.996 0.989);
+ --green2: color(display-p3 0.963 0.983 0.967);
+ --green3: color(display-p3 0.913 0.964 0.925);
+ --green4: color(display-p3 0.859 0.94 0.879);
+ --green5: color(display-p3 0.796 0.907 0.826);
+ --green6: color(display-p3 0.718 0.863 0.761);
+ --green7: color(display-p3 0.61 0.801 0.675);
+ --green8: color(display-p3 0.451 0.715 0.559);
+ --green9: color(display-p3 0.332 0.634 0.442);
+ --green10: color(display-p3 0.308 0.595 0.417);
+ --green11: color(display-p3 0.19 0.5 0.32);
+ --green12: color(display-p3 0.132 0.228 0.18);
+ --greenA1: color(display-p3 0.024 0.757 0.267 / 0.016);
+ --greenA2: color(display-p3 0.024 0.565 0.129 / 0.036);
+ --greenA3: color(display-p3 0.012 0.596 0.145 / 0.087);
+ --greenA4: color(display-p3 0.008 0.588 0.145 / 0.142);
+ --greenA5: color(display-p3 0.004 0.541 0.157 / 0.204);
+ --greenA6: color(display-p3 0.004 0.518 0.157 / 0.283);
+ --greenA7: color(display-p3 0.004 0.486 0.165 / 0.389);
+ --greenA8: color(display-p3 0 0.478 0.2 / 0.55);
+ --greenA9: color(display-p3 0 0.455 0.165 / 0.667);
+ --greenA10: color(display-p3 0 0.416 0.153 / 0.691);
+ --greenA11: color(display-p3 0.19 0.5 0.32);
+ --greenA12: color(display-p3 0.132 0.228 0.18);
+ --indigo1: color(display-p3 0.992 0.992 0.996);
+ --indigo2: color(display-p3 0.971 0.977 0.998);
+ --indigo3: color(display-p3 0.933 0.948 0.992);
+ --indigo4: color(display-p3 0.885 0.914 1);
+ --indigo5: color(display-p3 0.831 0.87 1);
+ --indigo6: color(display-p3 0.767 0.814 0.995);
+ --indigo7: color(display-p3 0.685 0.74 0.957);
+ --indigo8: color(display-p3 0.569 0.639 0.916);
+ --indigo9: color(display-p3 0.276 0.384 0.837);
+ --indigo10: color(display-p3 0.234 0.343 0.801);
+ --indigo11: color(display-p3 0.256 0.354 0.755);
+ --indigo12: color(display-p3 0.133 0.175 0.348);
+ --indigoA1: color(display-p3 0.02 0.02 0.51 / 0.008);
+ --indigoA2: color(display-p3 0.024 0.161 0.863 / 0.028);
+ --indigoA3: color(display-p3 0.008 0.239 0.886 / 0.067);
+ --indigoA4: color(display-p3 0.004 0.247 1 / 0.114);
+ --indigoA5: color(display-p3 0.004 0.235 1 / 0.169);
+ --indigoA6: color(display-p3 0.004 0.208 0.984 / 0.232);
+ --indigoA7: color(display-p3 0.004 0.176 0.863 / 0.314);
+ --indigoA8: color(display-p3 0.004 0.165 0.812 / 0.432);
+ --indigoA9: color(display-p3 0 0.153 0.773 / 0.726);
+ --indigoA10: color(display-p3 0 0.137 0.737 / 0.765);
+ --indigoA11: color(display-p3 0.256 0.354 0.755);
+ --indigoA12: color(display-p3 0.133 0.175 0.348);
+ --iris1: color(display-p3 0.992 0.992 0.999);
+ --iris2: color(display-p3 0.972 0.973 0.998);
+ --iris3: color(display-p3 0.943 0.945 0.992);
+ --iris4: color(display-p3 0.902 0.906 1);
+ --iris5: color(display-p3 0.857 0.861 1);
+ --iris6: color(display-p3 0.799 0.805 0.987);
+ --iris7: color(display-p3 0.721 0.727 0.955);
+ --iris8: color(display-p3 0.61 0.619 0.918);
+ --iris9: color(display-p3 0.357 0.357 0.81);
+ --iris10: color(display-p3 0.318 0.318 0.774);
+ --iris11: color(display-p3 0.337 0.326 0.748);
+ --iris12: color(display-p3 0.154 0.161 0.371);
+ --irisA1: color(display-p3 0.02 0.02 1 / 0.008);
+ --irisA2: color(display-p3 0.024 0.024 0.863 / 0.028);
+ --irisA3: color(display-p3 0.004 0.071 0.871 / 0.059);
+ --irisA4: color(display-p3 0.012 0.051 1 / 0.099);
+ --irisA5: color(display-p3 0.008 0.035 1 / 0.142);
+ --irisA6: color(display-p3 0 0.02 0.941 / 0.2);
+ --irisA7: color(display-p3 0.004 0.02 0.847 / 0.279);
+ --irisA8: color(display-p3 0.004 0.024 0.788 / 0.389);
+ --irisA9: color(display-p3 0 0 0.706 / 0.644);
+ --irisA10: color(display-p3 0 0 0.667 / 0.683);
+ --irisA11: color(display-p3 0.337 0.326 0.748);
+ --irisA12: color(display-p3 0.154 0.161 0.371);
+ --jade1: color(display-p3 0.986 0.996 0.992);
+ --jade2: color(display-p3 0.962 0.983 0.969);
+ --jade3: color(display-p3 0.912 0.965 0.932);
+ --jade4: color(display-p3 0.858 0.941 0.893);
+ --jade5: color(display-p3 0.795 0.909 0.847);
+ --jade6: color(display-p3 0.715 0.864 0.791);
+ --jade7: color(display-p3 0.603 0.802 0.718);
+ --jade8: color(display-p3 0.44 0.72 0.629);
+ --jade9: color(display-p3 0.319 0.63 0.521);
+ --jade10: color(display-p3 0.299 0.592 0.488);
+ --jade11: color(display-p3 0.15 0.5 0.37);
+ --jade12: color(display-p3 0.142 0.229 0.194);
+ --jadeA1: color(display-p3 0.024 0.757 0.514 / 0.016);
+ --jadeA2: color(display-p3 0.024 0.612 0.22 / 0.04);
+ --jadeA3: color(display-p3 0.012 0.596 0.235 / 0.087);
+ --jadeA4: color(display-p3 0.008 0.588 0.255 / 0.142);
+ --jadeA5: color(display-p3 0.004 0.561 0.251 / 0.204);
+ --jadeA6: color(display-p3 0.004 0.525 0.278 / 0.287);
+ --jadeA7: color(display-p3 0.004 0.506 0.29 / 0.397);
+ --jadeA8: color(display-p3 0 0.506 0.337 / 0.561);
+ --jadeA9: color(display-p3 0 0.459 0.298 / 0.683);
+ --jadeA10: color(display-p3 0 0.42 0.271 / 0.702);
+ --jadeA11: color(display-p3 0.15 0.5 0.37);
+ --jadeA12: color(display-p3 0.142 0.229 0.194);
+ --lime1: color(display-p3 0.989 0.992 0.981);
+ --lime2: color(display-p3 0.975 0.98 0.954);
+ --lime3: color(display-p3 0.939 0.965 0.851);
+ --lime4: color(display-p3 0.896 0.94 0.76);
+ --lime5: color(display-p3 0.843 0.903 0.678);
+ --lime6: color(display-p3 0.778 0.852 0.599);
+ --lime7: color(display-p3 0.694 0.784 0.508);
+ --lime8: color(display-p3 0.585 0.707 0.378);
+ --lime9: color(display-p3 0.78 0.928 0.466);
+ --lime10: color(display-p3 0.734 0.896 0.397);
+ --lime11: color(display-p3 0.386 0.482 0.227);
+ --lime12: color(display-p3 0.222 0.25 0.128);
+ --limeA1: color(display-p3 0.412 0.608 0.02 / 0.02);
+ --limeA2: color(display-p3 0.514 0.592 0.024 / 0.048);
+ --limeA3: color(display-p3 0.584 0.765 0.008 / 0.15);
+ --limeA4: color(display-p3 0.561 0.757 0.004 / 0.24);
+ --limeA5: color(display-p3 0.514 0.698 0.004 / 0.322);
+ --limeA6: color(display-p3 0.443 0.627 0 / 0.4);
+ --limeA7: color(display-p3 0.376 0.561 0.004 / 0.491);
+ --limeA8: color(display-p3 0.333 0.529 0 / 0.624);
+ --limeA9: color(display-p3 0.588 0.867 0 / 0.534);
+ --limeA10: color(display-p3 0.561 0.827 0 / 0.604);
+ --limeA11: color(display-p3 0.386 0.482 0.227);
+ --limeA12: color(display-p3 0.222 0.25 0.128);
+ --mauve1: color(display-p3 0.991 0.988 0.992);
+ --mauve2: color(display-p3 0.98 0.976 0.984);
+ --mauve3: color(display-p3 0.946 0.938 0.952);
+ --mauve4: color(display-p3 0.915 0.906 0.925);
+ --mauve5: color(display-p3 0.886 0.876 0.901);
+ --mauve6: color(display-p3 0.856 0.846 0.875);
+ --mauve7: color(display-p3 0.814 0.804 0.84);
+ --mauve8: color(display-p3 0.735 0.728 0.777);
+ --mauve9: color(display-p3 0.555 0.549 0.596);
+ --mauve10: color(display-p3 0.514 0.508 0.552);
+ --mauve11: color(display-p3 0.395 0.388 0.424);
+ --mauve12: color(display-p3 0.128 0.122 0.147);
+ --mauveA1: color(display-p3 0.349 0.024 0.349 / 0.012);
+ --mauveA2: color(display-p3 0.184 0.024 0.349 / 0.024);
+ --mauveA3: color(display-p3 0.129 0.008 0.255 / 0.063);
+ --mauveA4: color(display-p3 0.094 0.012 0.216 / 0.095);
+ --mauveA5: color(display-p3 0.098 0.008 0.224 / 0.126);
+ --mauveA6: color(display-p3 0.055 0.004 0.18 / 0.153);
+ --mauveA7: color(display-p3 0.067 0.008 0.184 / 0.197);
+ --mauveA8: color(display-p3 0.02 0.004 0.176 / 0.271);
+ --mauveA9: color(display-p3 0.02 0.004 0.106 / 0.451);
+ --mauveA10: color(display-p3 0.012 0.004 0.09 / 0.491);
+ --mauveA11: color(display-p3 0.016 0 0.059 / 0.612);
+ --mauveA12: color(display-p3 0.008 0 0.027 / 0.879);
+ --mint1: color(display-p3 0.98 0.995 0.992);
+ --mint2: color(display-p3 0.957 0.985 0.977);
+ --mint3: color(display-p3 0.888 0.972 0.95);
+ --mint4: color(display-p3 0.819 0.951 0.916);
+ --mint5: color(display-p3 0.747 0.918 0.873);
+ --mint6: color(display-p3 0.668 0.87 0.818);
+ --mint7: color(display-p3 0.567 0.805 0.744);
+ --mint8: color(display-p3 0.42 0.724 0.649);
+ --mint9: color(display-p3 0.62 0.908 0.834);
+ --mint10: color(display-p3 0.585 0.871 0.797);
+ --mint11: color(display-p3 0.203 0.463 0.397);
+ --mint12: color(display-p3 0.136 0.259 0.236);
+ --mintA1: color(display-p3 0.02 0.804 0.608 / 0.02);
+ --mintA2: color(display-p3 0.02 0.647 0.467 / 0.044);
+ --mintA3: color(display-p3 0.004 0.761 0.553 / 0.114);
+ --mintA4: color(display-p3 0.004 0.741 0.545 / 0.181);
+ --mintA5: color(display-p3 0.004 0.678 0.51 / 0.255);
+ --mintA6: color(display-p3 0.004 0.616 0.463 / 0.334);
+ --mintA7: color(display-p3 0.004 0.549 0.412 / 0.432);
+ --mintA8: color(display-p3 0 0.529 0.392 / 0.581);
+ --mintA9: color(display-p3 0.004 0.765 0.569 / 0.381);
+ --mintA10: color(display-p3 0.004 0.69 0.51 / 0.416);
+ --mintA11: color(display-p3 0.203 0.463 0.397);
+ --mintA12: color(display-p3 0.136 0.259 0.236);
+ --olive1: color(display-p3 0.989 0.992 0.989);
+ --olive2: color(display-p3 0.974 0.98 0.973);
+ --olive3: color(display-p3 0.939 0.945 0.937);
+ --olive4: color(display-p3 0.907 0.914 0.905);
+ --olive5: color(display-p3 0.878 0.885 0.875);
+ --olive6: color(display-p3 0.846 0.855 0.843);
+ --olive7: color(display-p3 0.803 0.812 0.8);
+ --olive8: color(display-p3 0.727 0.738 0.723);
+ --olive9: color(display-p3 0.541 0.556 0.532);
+ --olive10: color(display-p3 0.5 0.515 0.491);
+ --olive11: color(display-p3 0.38 0.395 0.374);
+ --olive12: color(display-p3 0.117 0.129 0.111);
+ --oliveA1: color(display-p3 0.024 0.349 0.024 / 0.012);
+ --oliveA2: color(display-p3 0.024 0.302 0.024 / 0.028);
+ --oliveA3: color(display-p3 0.008 0.129 0.008 / 0.063);
+ --oliveA4: color(display-p3 0.012 0.094 0.012 / 0.095);
+ --oliveA5: color(display-p3 0.035 0.098 0.008 / 0.126);
+ --oliveA6: color(display-p3 0.027 0.078 0.004 / 0.157);
+ --oliveA7: color(display-p3 0.02 0.059 0 / 0.2);
+ --oliveA8: color(display-p3 0.02 0.059 0.004 / 0.279);
+ --oliveA9: color(display-p3 0.02 0.051 0.004 / 0.467);
+ --oliveA10: color(display-p3 0.024 0.047 0 / 0.51);
+ --oliveA11: color(display-p3 0.012 0.039 0 / 0.628);
+ --oliveA12: color(display-p3 0.008 0.024 0 / 0.891);
+ --orange1: color(display-p3 0.995 0.988 0.985);
+ --orange2: color(display-p3 0.994 0.968 0.934);
+ --orange3: color(display-p3 0.989 0.938 0.85);
+ --orange4: color(display-p3 1 0.874 0.687);
+ --orange5: color(display-p3 1 0.821 0.583);
+ --orange6: color(display-p3 0.975 0.767 0.545);
+ --orange7: color(display-p3 0.919 0.693 0.486);
+ --orange8: color(display-p3 0.877 0.597 0.379);
+ --orange9: color(display-p3 0.9 0.45 0.2);
+ --orange10: color(display-p3 0.87 0.409 0.164);
+ --orange11: color(display-p3 0.76 0.34 0);
+ --orange12: color(display-p3 0.323 0.185 0.127);
+ --orangeA1: color(display-p3 0.757 0.267 0.024 / 0.016);
+ --orangeA2: color(display-p3 0.886 0.533 0.008 / 0.067);
+ --orangeA3: color(display-p3 0.922 0.584 0.008 / 0.15);
+ --orangeA4: color(display-p3 1 0.604 0.004 / 0.314);
+ --orangeA5: color(display-p3 1 0.569 0.004 / 0.416);
+ --orangeA6: color(display-p3 0.949 0.494 0.004 / 0.455);
+ --orangeA7: color(display-p3 0.839 0.408 0 / 0.514);
+ --orangeA8: color(display-p3 0.804 0.349 0 / 0.62);
+ --orangeA9: color(display-p3 0.878 0.314 0 / 0.8);
+ --orangeA10: color(display-p3 0.843 0.29 0 / 0.836);
+ --orangeA11: color(display-p3 0.76 0.34 0);
+ --orangeA12: color(display-p3 0.323 0.185 0.127);
+ --pink1: color(display-p3 0.998 0.989 0.996);
+ --pink2: color(display-p3 0.992 0.97 0.985);
+ --pink3: color(display-p3 0.981 0.917 0.96);
+ --pink4: color(display-p3 0.963 0.867 0.932);
+ --pink5: color(display-p3 0.939 0.815 0.899);
+ --pink6: color(display-p3 0.907 0.756 0.859);
+ --pink7: color(display-p3 0.869 0.683 0.81);
+ --pink8: color(display-p3 0.825 0.59 0.751);
+ --pink9: color(display-p3 0.775 0.297 0.61);
+ --pink10: color(display-p3 0.748 0.27 0.581);
+ --pink11: color(display-p3 0.698 0.219 0.528);
+ --pink12: color(display-p3 0.363 0.101 0.279);
+ --pinkA1: color(display-p3 0.675 0.024 0.675 / 0.012);
+ --pinkA2: color(display-p3 0.757 0.02 0.51 / 0.032);
+ --pinkA3: color(display-p3 0.765 0.008 0.529 / 0.083);
+ --pinkA4: color(display-p3 0.737 0.008 0.506 / 0.134);
+ --pinkA5: color(display-p3 0.663 0.004 0.451 / 0.185);
+ --pinkA6: color(display-p3 0.616 0.004 0.424 / 0.244);
+ --pinkA7: color(display-p3 0.596 0.004 0.412 / 0.318);
+ --pinkA8: color(display-p3 0.573 0.004 0.404 / 0.412);
+ --pinkA9: color(display-p3 0.682 0 0.447 / 0.702);
+ --pinkA10: color(display-p3 0.655 0 0.424 / 0.73);
+ --pinkA11: color(display-p3 0.698 0.219 0.528);
+ --pinkA12: color(display-p3 0.363 0.101 0.279);
+ --plum1: color(display-p3 0.995 0.988 0.999);
+ --plum2: color(display-p3 0.988 0.971 0.99);
+ --plum3: color(display-p3 0.973 0.923 0.98);
+ --plum4: color(display-p3 0.953 0.875 0.966);
+ --plum5: color(display-p3 0.926 0.825 0.945);
+ --plum6: color(display-p3 0.89 0.765 0.916);
+ --plum7: color(display-p3 0.84 0.686 0.877);
+ --plum8: color(display-p3 0.775 0.58 0.832);
+ --plum9: color(display-p3 0.624 0.313 0.708);
+ --plum10: color(display-p3 0.587 0.29 0.667);
+ --plum11: color(display-p3 0.543 0.263 0.619);
+ --plum12: color(display-p3 0.299 0.114 0.352);
+ --plumA1: color(display-p3 0.675 0.024 1 / 0.012);
+ --plumA2: color(display-p3 0.58 0.024 0.58 / 0.028);
+ --plumA3: color(display-p3 0.655 0.008 0.753 / 0.079);
+ --plumA4: color(display-p3 0.627 0.008 0.722 / 0.126);
+ --plumA5: color(display-p3 0.58 0.004 0.69 / 0.177);
+ --plumA6: color(display-p3 0.537 0.004 0.655 / 0.236);
+ --plumA7: color(display-p3 0.49 0.004 0.616 / 0.314);
+ --plumA8: color(display-p3 0.471 0.004 0.6 / 0.42);
+ --plumA9: color(display-p3 0.451 0 0.576 / 0.687);
+ --plumA10: color(display-p3 0.42 0 0.529 / 0.71);
+ --plumA11: color(display-p3 0.543 0.263 0.619);
+ --plumA12: color(display-p3 0.299 0.114 0.352);
+ --purple1: color(display-p3 0.995 0.988 0.996);
+ --purple2: color(display-p3 0.983 0.971 0.993);
+ --purple3: color(display-p3 0.963 0.931 0.989);
+ --purple4: color(display-p3 0.937 0.888 0.981);
+ --purple5: color(display-p3 0.904 0.837 0.966);
+ --purple6: color(display-p3 0.86 0.774 0.942);
+ --purple7: color(display-p3 0.799 0.69 0.91);
+ --purple8: color(display-p3 0.719 0.583 0.874);
+ --purple9: color(display-p3 0.523 0.318 0.751);
+ --purple10: color(display-p3 0.483 0.289 0.7);
+ --purple11: color(display-p3 0.473 0.281 0.687);
+ --purple12: color(display-p3 0.234 0.132 0.363);
+ --purpleA1: color(display-p3 0.675 0.024 0.675 / 0.012);
+ --purpleA2: color(display-p3 0.443 0.024 0.722 / 0.028);
+ --purpleA3: color(display-p3 0.506 0.008 0.835 / 0.071);
+ --purpleA4: color(display-p3 0.451 0.004 0.831 / 0.114);
+ --purpleA5: color(display-p3 0.431 0.004 0.788 / 0.165);
+ --purpleA6: color(display-p3 0.384 0.004 0.745 / 0.228);
+ --purpleA7: color(display-p3 0.357 0.004 0.71 / 0.31);
+ --purpleA8: color(display-p3 0.322 0.004 0.702 / 0.416);
+ --purpleA9: color(display-p3 0.298 0 0.639 / 0.683);
+ --purpleA10: color(display-p3 0.271 0 0.58 / 0.71);
+ --purpleA11: color(display-p3 0.473 0.281 0.687);
+ --purpleA12: color(display-p3 0.234 0.132 0.363);
+ --red1: color(display-p3 0.998 0.989 0.988);
+ --red2: color(display-p3 0.995 0.971 0.971);
+ --red3: color(display-p3 0.985 0.925 0.925);
+ --red4: color(display-p3 0.999 0.866 0.866);
+ --red5: color(display-p3 0.984 0.812 0.811);
+ --red6: color(display-p3 0.955 0.751 0.749);
+ --red7: color(display-p3 0.915 0.675 0.672);
+ --red8: color(display-p3 0.872 0.575 0.572);
+ --red9: color(display-p3 0.83 0.329 0.324);
+ --red10: color(display-p3 0.798 0.294 0.285);
+ --red11: color(display-p3 0.744 0.234 0.222);
+ --red12: color(display-p3 0.36 0.115 0.143);
+ --redA1: color(display-p3 0.675 0.024 0.024 / 0.012);
+ --redA2: color(display-p3 0.863 0.024 0.024 / 0.028);
+ --redA3: color(display-p3 0.792 0.008 0.008 / 0.075);
+ --redA4: color(display-p3 1 0.008 0.008 / 0.134);
+ --redA5: color(display-p3 0.918 0.008 0.008 / 0.189);
+ --redA6: color(display-p3 0.831 0.02 0.004 / 0.251);
+ --redA7: color(display-p3 0.741 0.016 0.004 / 0.33);
+ --redA8: color(display-p3 0.698 0.012 0.004 / 0.428);
+ --redA9: color(display-p3 0.749 0.008 0 / 0.675);
+ --redA10: color(display-p3 0.714 0.012 0 / 0.714);
+ --redA11: color(display-p3 0.744 0.234 0.222);
+ --redA12: color(display-p3 0.36 0.115 0.143);
+ --ruby1: color(display-p3 0.998 0.989 0.992);
+ --ruby2: color(display-p3 0.995 0.971 0.974);
+ --ruby3: color(display-p3 0.983 0.92 0.928);
+ --ruby4: color(display-p3 0.987 0.869 0.885);
+ --ruby5: color(display-p3 0.968 0.817 0.839);
+ --ruby6: color(display-p3 0.937 0.758 0.786);
+ --ruby7: color(display-p3 0.897 0.685 0.721);
+ --ruby8: color(display-p3 0.851 0.588 0.639);
+ --ruby9: color(display-p3 0.83 0.323 0.408);
+ --ruby10: color(display-p3 0.795 0.286 0.375);
+ --ruby11: color(display-p3 0.728 0.211 0.311);
+ --ruby12: color(display-p3 0.36 0.115 0.171);
+ --rubyA1: color(display-p3 0.675 0.024 0.349 / 0.012);
+ --rubyA2: color(display-p3 0.863 0.024 0.024 / 0.028);
+ --rubyA3: color(display-p3 0.804 0.008 0.11 / 0.079);
+ --rubyA4: color(display-p3 0.91 0.008 0.125 / 0.13);
+ --rubyA5: color(display-p3 0.831 0.004 0.133 / 0.185);
+ --rubyA6: color(display-p3 0.745 0.004 0.118 / 0.244);
+ --rubyA7: color(display-p3 0.678 0.004 0.114 / 0.314);
+ --rubyA8: color(display-p3 0.639 0.004 0.125 / 0.412);
+ --rubyA9: color(display-p3 0.753 0 0.129 / 0.679);
+ --rubyA10: color(display-p3 0.714 0 0.125 / 0.714);
+ --rubyA11: color(display-p3 0.728 0.211 0.311);
+ --rubyA12: color(display-p3 0.36 0.115 0.171);
+ --sage1: color(display-p3 0.986 0.992 0.988);
+ --sage2: color(display-p3 0.97 0.977 0.974);
+ --sage3: color(display-p3 0.935 0.944 0.94);
+ --sage4: color(display-p3 0.904 0.913 0.909);
+ --sage5: color(display-p3 0.875 0.885 0.88);
+ --sage6: color(display-p3 0.844 0.854 0.849);
+ --sage7: color(display-p3 0.8 0.811 0.806);
+ --sage8: color(display-p3 0.725 0.738 0.732);
+ --sage9: color(display-p3 0.531 0.556 0.546);
+ --sage10: color(display-p3 0.492 0.515 0.506);
+ --sage11: color(display-p3 0.377 0.395 0.389);
+ --sage12: color(display-p3 0.107 0.129 0.118);
+ --sageA1: color(display-p3 0.024 0.514 0.267 / 0.016);
+ --sageA2: color(display-p3 0.02 0.267 0.145 / 0.032);
+ --sageA3: color(display-p3 0.008 0.184 0.125 / 0.067);
+ --sageA4: color(display-p3 0.012 0.094 0.051 / 0.095);
+ --sageA5: color(display-p3 0.008 0.098 0.035 / 0.126);
+ --sageA6: color(display-p3 0.004 0.078 0.027 / 0.157);
+ --sageA7: color(display-p3 0 0.059 0.039 / 0.2);
+ --sageA8: color(display-p3 0.004 0.047 0.031 / 0.275);
+ --sageA9: color(display-p3 0.004 0.059 0.035 / 0.471);
+ --sageA10: color(display-p3 0 0.047 0.031 / 0.51);
+ --sageA11: color(display-p3 0 0.031 0.02 / 0.624);
+ --sageA12: color(display-p3 0 0.027 0.012 / 0.895);
+ --sand1: color(display-p3 0.992 0.992 0.989);
+ --sand2: color(display-p3 0.977 0.977 0.973);
+ --sand3: color(display-p3 0.943 0.942 0.936);
+ --sand4: color(display-p3 0.913 0.912 0.903);
+ --sand5: color(display-p3 0.885 0.883 0.873);
+ --sand6: color(display-p3 0.854 0.852 0.839);
+ --sand7: color(display-p3 0.813 0.81 0.794);
+ --sand8: color(display-p3 0.738 0.734 0.713);
+ --sand9: color(display-p3 0.553 0.553 0.528);
+ --sand10: color(display-p3 0.511 0.511 0.488);
+ --sand11: color(display-p3 0.388 0.388 0.37);
+ --sand12: color(display-p3 0.129 0.126 0.111);
+ --sandA1: color(display-p3 0.349 0.349 0.024 / 0.012);
+ --sandA2: color(display-p3 0.161 0.161 0.024 / 0.028);
+ --sandA3: color(display-p3 0.067 0.067 0.008 / 0.063);
+ --sandA4: color(display-p3 0.129 0.129 0.012 / 0.099);
+ --sandA5: color(display-p3 0.098 0.067 0.008 / 0.126);
+ --sandA6: color(display-p3 0.102 0.075 0.004 / 0.161);
+ --sandA7: color(display-p3 0.098 0.098 0.004 / 0.208);
+ --sandA8: color(display-p3 0.086 0.075 0.004 / 0.287);
+ --sandA9: color(display-p3 0.051 0.051 0.004 / 0.471);
+ --sandA10: color(display-p3 0.047 0.047 0 / 0.514);
+ --sandA11: color(display-p3 0.031 0.031 0 / 0.632);
+ --sandA12: color(display-p3 0.024 0.02 0 / 0.891);
+ --sky1: color(display-p3 0.98 0.995 0.999);
+ --sky2: color(display-p3 0.953 0.98 0.99);
+ --sky3: color(display-p3 0.899 0.963 0.989);
+ --sky4: color(display-p3 0.842 0.937 0.977);
+ --sky5: color(display-p3 0.777 0.9 0.954);
+ --sky6: color(display-p3 0.701 0.851 0.921);
+ --sky7: color(display-p3 0.604 0.785 0.879);
+ --sky8: color(display-p3 0.457 0.696 0.829);
+ --sky9: color(display-p3 0.585 0.877 0.983);
+ --sky10: color(display-p3 0.555 0.845 0.959);
+ --sky11: color(display-p3 0.193 0.448 0.605);
+ --sky12: color(display-p3 0.145 0.241 0.329);
+ --skyA1: color(display-p3 0.02 0.804 1 / 0.02);
+ --skyA2: color(display-p3 0.024 0.592 0.757 / 0.048);
+ --skyA3: color(display-p3 0.004 0.655 0.886 / 0.102);
+ --skyA4: color(display-p3 0.004 0.604 0.851 / 0.157);
+ --skyA5: color(display-p3 0.004 0.565 0.792 / 0.224);
+ --skyA6: color(display-p3 0.004 0.502 0.737 / 0.299);
+ --skyA7: color(display-p3 0.004 0.459 0.694 / 0.397);
+ --skyA8: color(display-p3 0 0.435 0.682 / 0.542);
+ --skyA9: color(display-p3 0.004 0.71 0.965 / 0.416);
+ --skyA10: color(display-p3 0.004 0.647 0.914 / 0.444);
+ --skyA11: color(display-p3 0.193 0.448 0.605);
+ --skyA12: color(display-p3 0.145 0.241 0.329);
+ --slate1: color(display-p3 0.988 0.988 0.992);
+ --slate2: color(display-p3 0.976 0.976 0.984);
+ --slate3: color(display-p3 0.94 0.941 0.953);
+ --slate4: color(display-p3 0.908 0.909 0.925);
+ --slate5: color(display-p3 0.88 0.881 0.901);
+ --slate6: color(display-p3 0.85 0.852 0.876);
+ --slate7: color(display-p3 0.805 0.808 0.838);
+ --slate8: color(display-p3 0.727 0.733 0.773);
+ --slate9: color(display-p3 0.547 0.553 0.592);
+ --slate10: color(display-p3 0.503 0.512 0.549);
+ --slate11: color(display-p3 0.379 0.392 0.421);
+ --slate12: color(display-p3 0.113 0.125 0.14);
+ --slateA1: color(display-p3 0.024 0.024 0.349 / 0.012);
+ --slateA2: color(display-p3 0.024 0.024 0.349 / 0.024);
+ --slateA3: color(display-p3 0.004 0.004 0.204 / 0.059);
+ --slateA4: color(display-p3 0.012 0.012 0.184 / 0.091);
+ --slateA5: color(display-p3 0.004 0.039 0.2 / 0.122);
+ --slateA6: color(display-p3 0.008 0.008 0.165 / 0.15);
+ --slateA7: color(display-p3 0.008 0.027 0.184 / 0.197);
+ --slateA8: color(display-p3 0.004 0.031 0.176 / 0.275);
+ --slateA9: color(display-p3 0.004 0.02 0.106 / 0.455);
+ --slateA10: color(display-p3 0.004 0.027 0.098 / 0.499);
+ --slateA11: color(display-p3 0 0.02 0.063 / 0.62);
+ --slateA12: color(display-p3 0 0.012 0.031 / 0.887);
+ --teal1: color(display-p3 0.983 0.996 0.992);
+ --teal2: color(display-p3 0.958 0.983 0.976);
+ --teal3: color(display-p3 0.895 0.971 0.952);
+ --teal4: color(display-p3 0.831 0.949 0.92);
+ --teal5: color(display-p3 0.761 0.914 0.878);
+ --teal6: color(display-p3 0.682 0.864 0.825);
+ --teal7: color(display-p3 0.581 0.798 0.756);
+ --teal8: color(display-p3 0.433 0.716 0.671);
+ --teal9: color(display-p3 0.297 0.637 0.581);
+ --teal10: color(display-p3 0.275 0.599 0.542);
+ --teal11: color(display-p3 0.08 0.5 0.43);
+ --teal12: color(display-p3 0.11 0.235 0.219);
+ --tealA1: color(display-p3 0.024 0.757 0.514 / 0.016);
+ --tealA2: color(display-p3 0.02 0.647 0.467 / 0.044);
+ --tealA3: color(display-p3 0.004 0.741 0.557 / 0.106);
+ --tealA4: color(display-p3 0.004 0.702 0.537 / 0.169);
+ --tealA5: color(display-p3 0.004 0.643 0.494 / 0.24);
+ --tealA6: color(display-p3 0.004 0.569 0.447 / 0.318);
+ --tealA7: color(display-p3 0.004 0.518 0.424 / 0.42);
+ --tealA8: color(display-p3 0 0.506 0.424 / 0.569);
+ --tealA9: color(display-p3 0 0.482 0.404 / 0.702);
+ --tealA10: color(display-p3 0 0.451 0.369 / 0.726);
+ --tealA11: color(display-p3 0.08 0.5 0.43);
+ --tealA12: color(display-p3 0.11 0.235 0.219);
+ --tomato1: color(display-p3 0.998 0.989 0.988);
+ --tomato2: color(display-p3 0.994 0.974 0.969);
+ --tomato3: color(display-p3 0.985 0.924 0.909);
+ --tomato4: color(display-p3 0.996 0.868 0.835);
+ --tomato5: color(display-p3 0.98 0.812 0.77);
+ --tomato6: color(display-p3 0.953 0.75 0.698);
+ --tomato7: color(display-p3 0.917 0.673 0.611);
+ --tomato8: color(display-p3 0.875 0.575 0.502);
+ --tomato9: color(display-p3 0.831 0.345 0.231);
+ --tomato10: color(display-p3 0.802 0.313 0.2);
+ --tomato11: color(display-p3 0.755 0.259 0.152);
+ --tomato12: color(display-p3 0.335 0.165 0.132);
+ --tomatoA1: color(display-p3 0.675 0.024 0.024 / 0.012);
+ --tomatoA2: color(display-p3 0.757 0.145 0.02 / 0.032);
+ --tomatoA3: color(display-p3 0.831 0.184 0.012 / 0.091);
+ --tomatoA4: color(display-p3 0.976 0.192 0.004 / 0.165);
+ --tomatoA5: color(display-p3 0.918 0.192 0.004 / 0.232);
+ --tomatoA6: color(display-p3 0.847 0.173 0.004 / 0.302);
+ --tomatoA7: color(display-p3 0.788 0.165 0.004 / 0.389);
+ --tomatoA8: color(display-p3 0.749 0.153 0.004 / 0.499);
+ --tomatoA9: color(display-p3 0.78 0.149 0 / 0.769);
+ --tomatoA10: color(display-p3 0.757 0.141 0 / 0.8);
+ --tomatoA11: color(display-p3 0.755 0.259 0.152);
+ --tomatoA12: color(display-p3 0.335 0.165 0.132);
+ --violet1: color(display-p3 0.991 0.988 0.995);
+ --violet2: color(display-p3 0.978 0.974 0.998);
+ --violet3: color(display-p3 0.953 0.943 0.993);
+ --violet4: color(display-p3 0.916 0.897 1);
+ --violet5: color(display-p3 0.876 0.851 1);
+ --violet6: color(display-p3 0.825 0.793 0.981);
+ --violet7: color(display-p3 0.752 0.712 0.943);
+ --violet8: color(display-p3 0.654 0.602 0.902);
+ --violet9: color(display-p3 0.417 0.341 0.784);
+ --violet10: color(display-p3 0.381 0.306 0.741);
+ --violet11: color(display-p3 0.383 0.317 0.702);
+ --violet12: color(display-p3 0.179 0.15 0.359);
+ --violetA1: color(display-p3 0.349 0.024 0.675 / 0.012);
+ --violetA2: color(display-p3 0.161 0.024 0.863 / 0.028);
+ --violetA3: color(display-p3 0.204 0.004 0.871 / 0.059);
+ --violetA4: color(display-p3 0.196 0.004 1 / 0.102);
+ --violetA5: color(display-p3 0.165 0.008 1 / 0.15);
+ --violetA6: color(display-p3 0.153 0.004 0.906 / 0.208);
+ --violetA7: color(display-p3 0.141 0.004 0.796 / 0.287);
+ --violetA8: color(display-p3 0.133 0.004 0.753 / 0.397);
+ --violetA9: color(display-p3 0.114 0 0.675 / 0.659);
+ --violetA10: color(display-p3 0.11 0 0.627 / 0.695);
+ --violetA11: color(display-p3 0.383 0.317 0.702);
+ --violetA12: color(display-p3 0.179 0.15 0.359);
+ --whiteA1: color(display-p3 1 1 1 / 0.05);
+ --whiteA2: color(display-p3 1 1 1 / 0.1);
+ --whiteA3: color(display-p3 1 1 1 / 0.15);
+ --whiteA4: color(display-p3 1 1 1 / 0.2);
+ --whiteA5: color(display-p3 1 1 1 / 0.3);
+ --whiteA6: color(display-p3 1 1 1 / 0.4);
+ --whiteA7: color(display-p3 1 1 1 / 0.5);
+ --whiteA8: color(display-p3 1 1 1 / 0.6);
+ --whiteA9: color(display-p3 1 1 1 / 0.7);
+ --whiteA10: color(display-p3 1 1 1 / 0.8);
+ --whiteA11: color(display-p3 1 1 1 / 0.9);
+ --whiteA12: color(display-p3 1 1 1 / 0.95);
+ --yellow1: color(display-p3 0.992 0.992 0.978);
+ --yellow2: color(display-p3 0.995 0.99 0.922);
+ --yellow3: color(display-p3 0.997 0.982 0.749);
+ --yellow4: color(display-p3 0.992 0.953 0.627);
+ --yellow5: color(display-p3 0.984 0.91 0.51);
+ --yellow6: color(display-p3 0.934 0.847 0.474);
+ --yellow7: color(display-p3 0.876 0.785 0.46);
+ --yellow8: color(display-p3 0.811 0.689 0.313);
+ --yellow9: color(display-p3 1 0.92 0.22);
+ --yellow10: color(display-p3 0.977 0.868 0.291);
+ --yellow11: color(display-p3 0.6 0.44 0);
+ --yellow12: color(display-p3 0.271 0.233 0.137);
+ --yellowA1: color(display-p3 0.675 0.675 0.024 / 0.024);
+ --yellowA2: color(display-p3 0.953 0.855 0.008 / 0.079);
+ --yellowA3: color(display-p3 0.988 0.925 0.004 / 0.251);
+ --yellowA4: color(display-p3 0.98 0.875 0.004 / 0.373);
+ --yellowA5: color(display-p3 0.969 0.816 0.004 / 0.491);
+ --yellowA6: color(display-p3 0.875 0.71 0 / 0.526);
+ --yellowA7: color(display-p3 0.769 0.604 0 / 0.542);
+ --yellowA8: color(display-p3 0.725 0.549 0 / 0.687);
+ --yellowA9: color(display-p3 1 0.898 0 / 0.781);
+ --yellowA10: color(display-p3 0.969 0.812 0 / 0.71);
+ --yellowA11: color(display-p3 0.6 0.44 0);
+ --yellowA12: color(display-p3 0.271 0.233 0.137);
+ }
+
+ .dark {
+ --amber1: color(display-p3 0.082 0.07 0.05);
+ --amber2: color(display-p3 0.111 0.094 0.064);
+ --amber3: color(display-p3 0.178 0.128 0.049);
+ --amber4: color(display-p3 0.239 0.156 0);
+ --amber5: color(display-p3 0.29 0.193 0);
+ --amber6: color(display-p3 0.344 0.245 0.076);
+ --amber7: color(display-p3 0.422 0.314 0.141);
+ --amber8: color(display-p3 0.535 0.399 0.189);
+ --amber9: color(display-p3 1 0.77 0.26);
+ --amber10: color(display-p3 1 0.87 0.15);
+ --amber11: color(display-p3 1 0.8 0.29);
+ --amber12: color(display-p3 0.984 0.909 0.726);
+ --amberA1: color(display-p3 0.992 0.298 0 / 0.017);
+ --amberA2: color(display-p3 0.988 0.651 0 / 0.047);
+ --amberA3: color(display-p3 1 0.6 0 / 0.118);
+ --amberA4: color(display-p3 1 0.557 0 / 0.185);
+ --amberA5: color(display-p3 1 0.592 0 / 0.24);
+ --amberA6: color(display-p3 1 0.659 0.094 / 0.299);
+ --amberA7: color(display-p3 1 0.714 0.263 / 0.383);
+ --amberA8: color(display-p3 0.996 0.729 0.306 / 0.5);
+ --amberA9: color(display-p3 1 0.769 0.259);
+ --amberA10: color(display-p3 1 0.871 0.149);
+ --amberA11: color(display-p3 1 0.8 0.29);
+ --amberA12: color(display-p3 0.984 0.909 0.726);
+ --blue1: color(display-p3 0.057 0.081 0.122);
+ --blue2: color(display-p3 0.072 0.098 0.147);
+ --blue3: color(display-p3 0.078 0.154 0.27);
+ --blue4: color(display-p3 0.033 0.197 0.37);
+ --blue5: color(display-p3 0.08 0.245 0.441);
+ --blue6: color(display-p3 0.14 0.298 0.511);
+ --blue7: color(display-p3 0.195 0.361 0.6);
+ --blue8: color(display-p3 0.239 0.434 0.72);
+ --blue9: color(display-p3 0.247 0.556 0.969);
+ --blue10: color(display-p3 0.344 0.612 0.973);
+ --blue11: color(display-p3 0.49 0.72 1);
+ --blue12: color(display-p3 0.788 0.898 0.99);
+ --blueA1: color(display-p3 0 0.333 1 / 0.059);
+ --blueA2: color(display-p3 0.114 0.435 0.988 / 0.085);
+ --blueA3: color(display-p3 0.122 0.463 1 / 0.219);
+ --blueA4: color(display-p3 0 0.467 1 / 0.324);
+ --blueA5: color(display-p3 0.098 0.51 1 / 0.4);
+ --blueA6: color(display-p3 0.224 0.557 1 / 0.475);
+ --blueA7: color(display-p3 0.294 0.584 1 / 0.572);
+ --blueA8: color(display-p3 0.314 0.592 1 / 0.702);
+ --blueA9: color(display-p3 0.251 0.573 0.996 / 0.967);
+ --blueA10: color(display-p3 0.357 0.631 1 / 0.971);
+ --blueA11: color(display-p3 0.49 0.72 1);
+ --blueA12: color(display-p3 0.788 0.898 0.99);
+ --bronze1: color(display-p3 0.076 0.067 0.063);
+ --bronze2: color(display-p3 0.106 0.097 0.093);
+ --bronze3: color(display-p3 0.147 0.132 0.125);
+ --bronze4: color(display-p3 0.185 0.166 0.156);
+ --bronze5: color(display-p3 0.227 0.202 0.19);
+ --bronze6: color(display-p3 0.278 0.246 0.23);
+ --bronze7: color(display-p3 0.343 0.302 0.281);
+ --bronze8: color(display-p3 0.426 0.374 0.347);
+ --bronze9: color(display-p3 0.611 0.507 0.455);
+ --bronze10: color(display-p3 0.66 0.556 0.504);
+ --bronze11: color(display-p3 0.81 0.707 0.655);
+ --bronze12: color(display-p3 0.921 0.88 0.854);
+ --bronzeA1: color(display-p3 0.941 0.067 0 / 0.009);
+ --bronzeA2: color(display-p3 0.98 0.8 0.706 / 0.043);
+ --bronzeA3: color(display-p3 0.988 0.851 0.761 / 0.085);
+ --bronzeA4: color(display-p3 0.996 0.839 0.78 / 0.127);
+ --bronzeA5: color(display-p3 0.996 0.863 0.773 / 0.173);
+ --bronzeA6: color(display-p3 1 0.863 0.796 / 0.227);
+ --bronzeA7: color(display-p3 1 0.867 0.8 / 0.295);
+ --bronzeA8: color(display-p3 1 0.859 0.788 / 0.387);
+ --bronzeA9: color(display-p3 1 0.82 0.733 / 0.585);
+ --bronzeA10: color(display-p3 1 0.839 0.761 / 0.635);
+ --bronzeA11: color(display-p3 0.81 0.707 0.655);
+ --bronzeA12: color(display-p3 0.921 0.88 0.854);
+ --brown1: color(display-p3 0.071 0.067 0.059);
+ --brown2: color(display-p3 0.107 0.095 0.087);
+ --brown3: color(display-p3 0.151 0.13 0.115);
+ --brown4: color(display-p3 0.191 0.161 0.138);
+ --brown5: color(display-p3 0.235 0.194 0.162);
+ --brown6: color(display-p3 0.291 0.237 0.192);
+ --brown7: color(display-p3 0.365 0.295 0.232);
+ --brown8: color(display-p3 0.469 0.377 0.287);
+ --brown9: color(display-p3 0.651 0.505 0.368);
+ --brown10: color(display-p3 0.697 0.557 0.423);
+ --brown11: color(display-p3 0.835 0.715 0.597);
+ --brown12: color(display-p3 0.938 0.885 0.802);
+ --brownA1: color(display-p3 0.855 0.071 0 / 0.005);
+ --brownA2: color(display-p3 0.98 0.706 0.525 / 0.043);
+ --brownA3: color(display-p3 0.996 0.745 0.576 / 0.093);
+ --brownA4: color(display-p3 1 0.765 0.592 / 0.135);
+ --brownA5: color(display-p3 1 0.761 0.588 / 0.181);
+ --brownA6: color(display-p3 1 0.773 0.592 / 0.24);
+ --brownA7: color(display-p3 0.996 0.776 0.58 / 0.32);
+ --brownA8: color(display-p3 1 0.78 0.573 / 0.433);
+ --brownA9: color(display-p3 1 0.769 0.549 / 0.627);
+ --brownA10: color(display-p3 1 0.792 0.596 / 0.677);
+ --brownA11: color(display-p3 0.835 0.715 0.597);
+ --brownA12: color(display-p3 0.938 0.885 0.802);
+ --crimson1: color(display-p3 0.093 0.068 0.078);
+ --crimson2: color(display-p3 0.117 0.078 0.095);
+ --crimson3: color(display-p3 0.203 0.091 0.143);
+ --crimson4: color(display-p3 0.277 0.087 0.182);
+ --crimson5: color(display-p3 0.332 0.115 0.22);
+ --crimson6: color(display-p3 0.394 0.162 0.268);
+ --crimson7: color(display-p3 0.489 0.222 0.336);
+ --crimson8: color(display-p3 0.638 0.289 0.429);
+ --crimson9: color(display-p3 0.843 0.298 0.507);
+ --crimson10: color(display-p3 0.864 0.364 0.539);
+ --crimson11: color(display-p3 1 0.56 0.66);
+ --crimson12: color(display-p3 0.966 0.834 0.906);
+ --crimsonA1: color(display-p3 0.984 0.071 0.463 / 0.03);
+ --crimsonA2: color(display-p3 0.996 0.282 0.569 / 0.055);
+ --crimsonA3: color(display-p3 0.996 0.227 0.573 / 0.148);
+ --crimsonA4: color(display-p3 1 0.157 0.569 / 0.227);
+ --crimsonA5: color(display-p3 1 0.231 0.604 / 0.286);
+ --crimsonA6: color(display-p3 1 0.337 0.643 / 0.349);
+ --crimsonA7: color(display-p3 1 0.416 0.663 / 0.454);
+ --crimsonA8: color(display-p3 0.996 0.427 0.651 / 0.614);
+ --crimsonA9: color(display-p3 1 0.345 0.596 / 0.832);
+ --crimsonA10: color(display-p3 1 0.42 0.62 / 0.853);
+ --crimsonA11: color(display-p3 1 0.56 0.66);
+ --crimsonA12: color(display-p3 0.966 0.834 0.906);
+ --cyan1: color(display-p3 0.053 0.085 0.098);
+ --cyan2: color(display-p3 0.072 0.105 0.122);
+ --cyan3: color(display-p3 0.073 0.168 0.209);
+ --cyan4: color(display-p3 0.063 0.216 0.277);
+ --cyan5: color(display-p3 0.091 0.267 0.336);
+ --cyan6: color(display-p3 0.137 0.324 0.4);
+ --cyan7: color(display-p3 0.186 0.398 0.484);
+ --cyan8: color(display-p3 0.23 0.496 0.6);
+ --cyan9: color(display-p3 0.282 0.627 0.765);
+ --cyan10: color(display-p3 0.331 0.675 0.801);
+ --cyan11: color(display-p3 0.446 0.79 0.887);
+ --cyan12: color(display-p3 0.757 0.919 0.962);
+ --cyanA1: color(display-p3 0 0.647 0.992 / 0.034);
+ --cyanA2: color(display-p3 0.133 0.733 1 / 0.059);
+ --cyanA3: color(display-p3 0.122 0.741 0.996 / 0.152);
+ --cyanA4: color(display-p3 0.051 0.725 1 / 0.227);
+ --cyanA5: color(display-p3 0.149 0.757 1 / 0.29);
+ --cyanA6: color(display-p3 0.267 0.792 1 / 0.358);
+ --cyanA7: color(display-p3 0.333 0.808 1 / 0.446);
+ --cyanA8: color(display-p3 0.357 0.816 1 / 0.572);
+ --cyanA9: color(display-p3 0.357 0.82 1 / 0.748);
+ --cyanA10: color(display-p3 0.4 0.839 1 / 0.786);
+ --cyanA11: color(display-p3 0.446 0.79 0.887);
+ --cyanA12: color(display-p3 0.757 0.919 0.962);
+ --gold1: color(display-p3 0.071 0.071 0.067);
+ --gold2: color(display-p3 0.104 0.101 0.09);
+ --gold3: color(display-p3 0.141 0.136 0.122);
+ --gold4: color(display-p3 0.177 0.17 0.152);
+ --gold5: color(display-p3 0.217 0.207 0.185);
+ --gold6: color(display-p3 0.265 0.252 0.225);
+ --gold7: color(display-p3 0.327 0.31 0.277);
+ --gold8: color(display-p3 0.407 0.384 0.342);
+ --gold9: color(display-p3 0.579 0.517 0.41);
+ --gold10: color(display-p3 0.628 0.566 0.463);
+ --gold11: color(display-p3 0.784 0.728 0.635);
+ --gold12: color(display-p3 0.906 0.887 0.855);
+ --goldA1: color(display-p3 0.855 0.855 0.071 / 0.005);
+ --goldA2: color(display-p3 0.98 0.89 0.616 / 0.043);
+ --goldA3: color(display-p3 1 0.949 0.753 / 0.08);
+ --goldA4: color(display-p3 1 0.933 0.8 / 0.118);
+ --goldA5: color(display-p3 1 0.949 0.804 / 0.16);
+ --goldA6: color(display-p3 1 0.925 0.8 / 0.215);
+ --goldA7: color(display-p3 1 0.945 0.831 / 0.278);
+ --goldA8: color(display-p3 1 0.937 0.82 / 0.366);
+ --goldA9: color(display-p3 0.996 0.882 0.69 / 0.551);
+ --goldA10: color(display-p3 1 0.894 0.725 / 0.601);
+ --goldA11: color(display-p3 0.784 0.728 0.635);
+ --goldA12: color(display-p3 0.906 0.887 0.855);
+ --grass1: color(display-p3 0.062 0.083 0.067);
+ --grass2: color(display-p3 0.083 0.103 0.085);
+ --grass3: color(display-p3 0.118 0.163 0.122);
+ --grass4: color(display-p3 0.142 0.225 0.15);
+ --grass5: color(display-p3 0.178 0.279 0.186);
+ --grass6: color(display-p3 0.217 0.337 0.224);
+ --grass7: color(display-p3 0.258 0.4 0.264);
+ --grass8: color(display-p3 0.302 0.47 0.305);
+ --grass9: color(display-p3 0.38 0.647 0.378);
+ --grass10: color(display-p3 0.426 0.694 0.426);
+ --grass11: color(display-p3 0.535 0.807 0.542);
+ --grass12: color(display-p3 0.797 0.936 0.776);
+ --grassA1: color(display-p3 0 0.992 0.071 / 0.017);
+ --grassA2: color(display-p3 0.482 0.996 0.584 / 0.038);
+ --grassA3: color(display-p3 0.549 0.992 0.588 / 0.106);
+ --grassA4: color(display-p3 0.51 0.996 0.557 / 0.169);
+ --grassA5: color(display-p3 0.553 1 0.588 / 0.227);
+ --grassA6: color(display-p3 0.584 1 0.608 / 0.29);
+ --grassA7: color(display-p3 0.604 1 0.616 / 0.358);
+ --grassA8: color(display-p3 0.608 1 0.62 / 0.433);
+ --grassA9: color(display-p3 0.573 1 0.569 / 0.622);
+ --grassA10: color(display-p3 0.6 0.996 0.6 / 0.673);
+ --grassA11: color(display-p3 0.535 0.807 0.542);
+ --grassA12: color(display-p3 0.797 0.936 0.776);
+ --gray1: color(display-p3 0.067 0.067 0.067);
+ --gray2: color(display-p3 0.098 0.098 0.098);
+ --gray3: color(display-p3 0.135 0.135 0.135);
+ --gray4: color(display-p3 0.163 0.163 0.163);
+ --gray5: color(display-p3 0.192 0.192 0.192);
+ --gray6: color(display-p3 0.228 0.228 0.228);
+ --gray7: color(display-p3 0.283 0.283 0.283);
+ --gray8: color(display-p3 0.375 0.375 0.375);
+ --gray9: color(display-p3 0.431 0.431 0.431);
+ --gray10: color(display-p3 0.484 0.484 0.484);
+ --gray11: color(display-p3 0.706 0.706 0.706);
+ --gray12: color(display-p3 0.933 0.933 0.933);
+ --grayA1: color(display-p3 0 0 0 / 0);
+ --grayA2: color(display-p3 1 1 1 / 0.034);
+ --grayA3: color(display-p3 1 1 1 / 0.071);
+ --grayA4: color(display-p3 1 1 1 / 0.105);
+ --grayA5: color(display-p3 1 1 1 / 0.134);
+ --grayA6: color(display-p3 1 1 1 / 0.172);
+ --grayA7: color(display-p3 1 1 1 / 0.231);
+ --grayA8: color(display-p3 1 1 1 / 0.332);
+ --grayA9: color(display-p3 1 1 1 / 0.391);
+ --grayA10: color(display-p3 1 1 1 / 0.445);
+ --grayA11: color(display-p3 1 1 1 / 0.685);
+ --grayA12: color(display-p3 1 1 1 / 0.929);
+ --green1: color(display-p3 0.062 0.083 0.071);
+ --green2: color(display-p3 0.079 0.106 0.09);
+ --green3: color(display-p3 0.1 0.173 0.133);
+ --green4: color(display-p3 0.115 0.229 0.166);
+ --green5: color(display-p3 0.147 0.282 0.206);
+ --green6: color(display-p3 0.185 0.338 0.25);
+ --green7: color(display-p3 0.227 0.403 0.298);
+ --green8: color(display-p3 0.27 0.479 0.351);
+ --green9: color(display-p3 0.332 0.634 0.442);
+ --green10: color(display-p3 0.357 0.682 0.474);
+ --green11: color(display-p3 0.434 0.828 0.573);
+ --green12: color(display-p3 0.747 0.938 0.807);
+ --greenA1: color(display-p3 0 0.992 0.298 / 0.017);
+ --greenA2: color(display-p3 0.341 0.98 0.616 / 0.043);
+ --greenA3: color(display-p3 0.376 0.996 0.655 / 0.114);
+ --greenA4: color(display-p3 0.341 0.996 0.635 / 0.173);
+ --greenA5: color(display-p3 0.408 1 0.678 / 0.232);
+ --greenA6: color(display-p3 0.475 1 0.706 / 0.29);
+ --greenA7: color(display-p3 0.514 1 0.706 / 0.362);
+ --greenA8: color(display-p3 0.529 1 0.718 / 0.442);
+ --greenA9: color(display-p3 0.502 0.996 0.682 / 0.61);
+ --greenA10: color(display-p3 0.506 1 0.682 / 0.66);
+ --greenA11: color(display-p3 0.434 0.828 0.573);
+ --greenA12: color(display-p3 0.747 0.938 0.807);
+ --indigo1: color(display-p3 0.068 0.074 0.118);
+ --indigo2: color(display-p3 0.081 0.089 0.144);
+ --indigo3: color(display-p3 0.105 0.141 0.275);
+ --indigo4: color(display-p3 0.129 0.18 0.369);
+ --indigo5: color(display-p3 0.163 0.22 0.439);
+ --indigo6: color(display-p3 0.203 0.262 0.5);
+ --indigo7: color(display-p3 0.245 0.309 0.575);
+ --indigo8: color(display-p3 0.285 0.362 0.674);
+ --indigo9: color(display-p3 0.276 0.384 0.837);
+ --indigo10: color(display-p3 0.354 0.445 0.866);
+ --indigo11: color(display-p3 0.63 0.69 1);
+ --indigo12: color(display-p3 0.848 0.881 0.99);
+ --indigoA1: color(display-p3 0.071 0.212 0.996 / 0.055);
+ --indigoA2: color(display-p3 0.251 0.345 0.988 / 0.085);
+ --indigoA3: color(display-p3 0.243 0.404 1 / 0.223);
+ --indigoA4: color(display-p3 0.263 0.42 1 / 0.324);
+ --indigoA5: color(display-p3 0.314 0.451 1 / 0.4);
+ --indigoA6: color(display-p3 0.361 0.49 1 / 0.467);
+ --indigoA7: color(display-p3 0.388 0.51 1 / 0.547);
+ --indigoA8: color(display-p3 0.404 0.518 1 / 0.652);
+ --indigoA9: color(display-p3 0.318 0.451 1 / 0.824);
+ --indigoA10: color(display-p3 0.404 0.506 1 / 0.858);
+ --indigoA11: color(display-p3 0.63 0.69 1);
+ --indigoA12: color(display-p3 0.848 0.881 0.99);
+ --iris1: color(display-p3 0.075 0.075 0.114);
+ --iris2: color(display-p3 0.089 0.086 0.14);
+ --iris3: color(display-p3 0.128 0.134 0.272);
+ --iris4: color(display-p3 0.153 0.165 0.382);
+ --iris5: color(display-p3 0.192 0.201 0.44);
+ --iris6: color(display-p3 0.239 0.241 0.491);
+ --iris7: color(display-p3 0.291 0.289 0.565);
+ --iris8: color(display-p3 0.35 0.345 0.673);
+ --iris9: color(display-p3 0.357 0.357 0.81);
+ --iris10: color(display-p3 0.428 0.416 0.843);
+ --iris11: color(display-p3 0.685 0.662 1);
+ --iris12: color(display-p3 0.878 0.875 0.986);
+ --irisA1: color(display-p3 0.224 0.224 0.992 / 0.051);
+ --irisA2: color(display-p3 0.361 0.314 1 / 0.08);
+ --irisA3: color(display-p3 0.357 0.373 1 / 0.219);
+ --irisA4: color(display-p3 0.325 0.361 1 / 0.337);
+ --irisA5: color(display-p3 0.38 0.4 1 / 0.4);
+ --irisA6: color(display-p3 0.447 0.447 1 / 0.454);
+ --irisA7: color(display-p3 0.486 0.486 1 / 0.534);
+ --irisA8: color(display-p3 0.502 0.494 1 / 0.652);
+ --irisA9: color(display-p3 0.431 0.431 1 / 0.799);
+ --irisA10: color(display-p3 0.502 0.486 1 / 0.832);
+ --irisA11: color(display-p3 0.685 0.662 1);
+ --irisA12: color(display-p3 0.878 0.875 0.986);
+ --jade1: color(display-p3 0.059 0.083 0.071);
+ --jade2: color(display-p3 0.078 0.11 0.094);
+ --jade3: color(display-p3 0.091 0.176 0.138);
+ --jade4: color(display-p3 0.102 0.228 0.177);
+ --jade5: color(display-p3 0.133 0.279 0.221);
+ --jade6: color(display-p3 0.174 0.334 0.273);
+ --jade7: color(display-p3 0.219 0.402 0.335);
+ --jade8: color(display-p3 0.263 0.488 0.411);
+ --jade9: color(display-p3 0.319 0.63 0.521);
+ --jade10: color(display-p3 0.338 0.68 0.555);
+ --jade11: color(display-p3 0.4 0.835 0.656);
+ --jade12: color(display-p3 0.734 0.934 0.838);
+ --jadeA1: color(display-p3 0 0.992 0.298 / 0.017);
+ --jadeA2: color(display-p3 0.318 0.988 0.651 / 0.047);
+ --jadeA3: color(display-p3 0.267 1 0.667 / 0.118);
+ --jadeA4: color(display-p3 0.275 0.996 0.702 / 0.173);
+ --jadeA5: color(display-p3 0.361 1 0.741 / 0.227);
+ --jadeA6: color(display-p3 0.439 1 0.796 / 0.286);
+ --jadeA7: color(display-p3 0.49 1 0.804 / 0.362);
+ --jadeA8: color(display-p3 0.506 1 0.835 / 0.45);
+ --jadeA9: color(display-p3 0.478 0.996 0.816 / 0.606);
+ --jadeA10: color(display-p3 0.478 1 0.816 / 0.656);
+ --jadeA11: color(display-p3 0.4 0.835 0.656);
+ --jadeA12: color(display-p3 0.734 0.934 0.838);
+ --lime1: color(display-p3 0.067 0.073 0.048);
+ --lime2: color(display-p3 0.086 0.1 0.067);
+ --lime3: color(display-p3 0.13 0.16 0.099);
+ --lime4: color(display-p3 0.172 0.214 0.126);
+ --lime5: color(display-p3 0.213 0.266 0.153);
+ --lime6: color(display-p3 0.257 0.321 0.182);
+ --lime7: color(display-p3 0.307 0.383 0.215);
+ --lime8: color(display-p3 0.365 0.456 0.25);
+ --lime9: color(display-p3 0.78 0.928 0.466);
+ --lime10: color(display-p3 0.865 0.995 0.519);
+ --lime11: color(display-p3 0.771 0.893 0.485);
+ --lime12: color(display-p3 0.905 0.966 0.753);
+ --limeA1: color(display-p3 0.067 0.941 0 / 0.009);
+ --limeA2: color(display-p3 0.584 0.996 0.071 / 0.038);
+ --limeA3: color(display-p3 0.69 1 0.38 / 0.101);
+ --limeA4: color(display-p3 0.729 1 0.435 / 0.16);
+ --limeA5: color(display-p3 0.745 1 0.471 / 0.215);
+ --limeA6: color(display-p3 0.769 1 0.482 / 0.274);
+ --limeA7: color(display-p3 0.769 1 0.506 / 0.341);
+ --limeA8: color(display-p3 0.784 1 0.51 / 0.416);
+ --limeA9: color(display-p3 0.839 1 0.502 / 0.925);
+ --limeA10: color(display-p3 0.871 1 0.522 / 0.996);
+ --limeA11: color(display-p3 0.771 0.893 0.485);
+ --limeA12: color(display-p3 0.905 0.966 0.753);
+ --mauve1: color(display-p3 0.07 0.067 0.074);
+ --mauve2: color(display-p3 0.101 0.098 0.105);
+ --mauve3: color(display-p3 0.138 0.134 0.144);
+ --mauve4: color(display-p3 0.167 0.161 0.175);
+ --mauve5: color(display-p3 0.196 0.189 0.206);
+ --mauve6: color(display-p3 0.232 0.225 0.245);
+ --mauve7: color(display-p3 0.286 0.277 0.302);
+ --mauve8: color(display-p3 0.383 0.373 0.408);
+ --mauve9: color(display-p3 0.434 0.428 0.467);
+ --mauve10: color(display-p3 0.487 0.48 0.519);
+ --mauve11: color(display-p3 0.707 0.7 0.735);
+ --mauve12: color(display-p3 0.933 0.933 0.94);
+ --mauveA1: color(display-p3 0 0 0 / 0);
+ --mauveA2: color(display-p3 0.996 0.992 1 / 0.034);
+ --mauveA3: color(display-p3 0.937 0.933 0.992 / 0.077);
+ --mauveA4: color(display-p3 0.957 0.918 0.996 / 0.111);
+ --mauveA5: color(display-p3 0.937 0.906 0.996 / 0.145);
+ --mauveA6: color(display-p3 0.953 0.925 0.996 / 0.183);
+ --mauveA7: color(display-p3 0.945 0.929 1 / 0.246);
+ --mauveA8: color(display-p3 0.937 0.918 1 / 0.361);
+ --mauveA9: color(display-p3 0.933 0.918 1 / 0.424);
+ --mauveA10: color(display-p3 0.941 0.925 1 / 0.479);
+ --mauveA11: color(display-p3 0.965 0.961 1 / 0.712);
+ --mauveA12: color(display-p3 0.992 0.992 1 / 0.937);
+ --mint1: color(display-p3 0.059 0.082 0.081);
+ --mint2: color(display-p3 0.068 0.104 0.105);
+ --mint3: color(display-p3 0.077 0.17 0.168);
+ --mint4: color(display-p3 0.068 0.224 0.22);
+ --mint5: color(display-p3 0.104 0.275 0.264);
+ --mint6: color(display-p3 0.154 0.332 0.313);
+ --mint7: color(display-p3 0.207 0.403 0.373);
+ --mint8: color(display-p3 0.258 0.49 0.441);
+ --mint9: color(display-p3 0.62 0.908 0.834);
+ --mint10: color(display-p3 0.725 0.954 0.898);
+ --mint11: color(display-p3 0.482 0.825 0.733);
+ --mint12: color(display-p3 0.807 0.955 0.887);
+ --mintA1: color(display-p3 0 0.992 0.992 / 0.017);
+ --mintA2: color(display-p3 0.071 0.98 0.98 / 0.043);
+ --mintA3: color(display-p3 0.176 0.996 0.996 / 0.11);
+ --mintA4: color(display-p3 0.071 0.996 0.973 / 0.169);
+ --mintA5: color(display-p3 0.243 1 0.949 / 0.223);
+ --mintA6: color(display-p3 0.369 1 0.933 / 0.286);
+ --mintA7: color(display-p3 0.459 1 0.914 / 0.362);
+ --mintA8: color(display-p3 0.49 1 0.89 / 0.454);
+ --mintA9: color(display-p3 0.678 0.996 0.914 / 0.904);
+ --mintA10: color(display-p3 0.761 1 0.941 / 0.95);
+ --mintA11: color(display-p3 0.482 0.825 0.733);
+ --mintA12: color(display-p3 0.807 0.955 0.887);
+ --olive1: color(display-p3 0.067 0.07 0.063);
+ --olive2: color(display-p3 0.095 0.098 0.091);
+ --olive3: color(display-p3 0.131 0.135 0.126);
+ --olive4: color(display-p3 0.158 0.163 0.153);
+ --olive5: color(display-p3 0.186 0.192 0.18);
+ --olive6: color(display-p3 0.221 0.229 0.215);
+ --olive7: color(display-p3 0.273 0.284 0.266);
+ --olive8: color(display-p3 0.365 0.382 0.359);
+ --olive9: color(display-p3 0.414 0.438 0.404);
+ --olive10: color(display-p3 0.467 0.49 0.458);
+ --olive11: color(display-p3 0.69 0.709 0.682);
+ --olive12: color(display-p3 0.927 0.933 0.926);
+ --oliveA1: color(display-p3 0 0 0 / 0);
+ --oliveA2: color(display-p3 0.984 0.988 0.976 / 0.03);
+ --oliveA3: color(display-p3 0.992 0.996 0.988 / 0.068);
+ --oliveA4: color(display-p3 0.953 0.996 0.949 / 0.102);
+ --oliveA5: color(display-p3 0.969 1 0.965 / 0.131);
+ --oliveA6: color(display-p3 0.973 1 0.969 / 0.169);
+ --oliveA7: color(display-p3 0.98 1 0.961 / 0.228);
+ --oliveA8: color(display-p3 0.961 1 0.957 / 0.334);
+ --oliveA9: color(display-p3 0.949 1 0.922 / 0.397);
+ --oliveA10: color(display-p3 0.953 1 0.941 / 0.452);
+ --oliveA11: color(display-p3 0.976 1 0.965 / 0.688);
+ --oliveA12: color(display-p3 0.992 1 0.992 / 0.929);
+ --orange1: color(display-p3 0.088 0.07 0.057);
+ --orange2: color(display-p3 0.113 0.089 0.061);
+ --orange3: color(display-p3 0.189 0.12 0.056);
+ --orange4: color(display-p3 0.262 0.132 0);
+ --orange5: color(display-p3 0.315 0.168 0.016);
+ --orange6: color(display-p3 0.376 0.219 0.088);
+ --orange7: color(display-p3 0.465 0.283 0.147);
+ --orange8: color(display-p3 0.601 0.359 0.201);
+ --orange9: color(display-p3 0.9 0.45 0.2);
+ --orange10: color(display-p3 0.98 0.51 0.23);
+ --orange11: color(display-p3 1 0.63 0.38);
+ --orange12: color(display-p3 0.98 0.883 0.775);
+ --orangeA1: color(display-p3 0.961 0.247 0 / 0.022);
+ --orangeA2: color(display-p3 0.992 0.529 0 / 0.051);
+ --orangeA3: color(display-p3 0.996 0.486 0 / 0.131);
+ --orangeA4: color(display-p3 0.996 0.384 0 / 0.211);
+ --orangeA5: color(display-p3 1 0.455 0 / 0.265);
+ --orangeA6: color(display-p3 1 0.529 0.129 / 0.332);
+ --orangeA7: color(display-p3 1 0.569 0.251 / 0.429);
+ --orangeA8: color(display-p3 1 0.584 0.302 / 0.572);
+ --orangeA9: color(display-p3 1 0.494 0.216 / 0.895);
+ --orangeA10: color(display-p3 1 0.522 0.235 / 0.979);
+ --orangeA11: color(display-p3 1 0.63 0.38);
+ --orangeA12: color(display-p3 0.98 0.883 0.775);
+ --pink1: color(display-p3 0.093 0.068 0.089);
+ --pink2: color(display-p3 0.121 0.073 0.11);
+ --pink3: color(display-p3 0.198 0.098 0.179);
+ --pink4: color(display-p3 0.271 0.095 0.231);
+ --pink5: color(display-p3 0.32 0.127 0.273);
+ --pink6: color(display-p3 0.382 0.177 0.326);
+ --pink7: color(display-p3 0.477 0.238 0.405);
+ --pink8: color(display-p3 0.612 0.304 0.51);
+ --pink9: color(display-p3 0.775 0.297 0.61);
+ --pink10: color(display-p3 0.808 0.356 0.645);
+ --pink11: color(display-p3 1 0.535 0.78);
+ --pink12: color(display-p3 0.964 0.826 0.912);
+ --pinkA1: color(display-p3 0.984 0.071 0.855 / 0.03);
+ --pinkA2: color(display-p3 1 0.2 0.8 / 0.059);
+ --pinkA3: color(display-p3 1 0.294 0.886 / 0.139);
+ --pinkA4: color(display-p3 1 0.192 0.82 / 0.219);
+ --pinkA5: color(display-p3 1 0.282 0.827 / 0.274);
+ --pinkA6: color(display-p3 1 0.396 0.835 / 0.337);
+ --pinkA7: color(display-p3 1 0.459 0.831 / 0.442);
+ --pinkA8: color(display-p3 1 0.478 0.827 / 0.585);
+ --pinkA9: color(display-p3 1 0.373 0.784 / 0.761);
+ --pinkA10: color(display-p3 1 0.435 0.792 / 0.795);
+ --pinkA11: color(display-p3 1 0.535 0.78);
+ --pinkA12: color(display-p3 0.964 0.826 0.912);
+ --plum1: color(display-p3 0.09 0.068 0.092);
+ --plum2: color(display-p3 0.118 0.077 0.121);
+ --plum3: color(display-p3 0.192 0.105 0.202);
+ --plum4: color(display-p3 0.25 0.121 0.271);
+ --plum5: color(display-p3 0.293 0.152 0.319);
+ --plum6: color(display-p3 0.343 0.198 0.372);
+ --plum7: color(display-p3 0.424 0.262 0.461);
+ --plum8: color(display-p3 0.54 0.341 0.595);
+ --plum9: color(display-p3 0.624 0.313 0.708);
+ --plum10: color(display-p3 0.666 0.365 0.748);
+ --plum11: color(display-p3 0.86 0.602 0.933);
+ --plum12: color(display-p3 0.936 0.836 0.949);
+ --plumA1: color(display-p3 0.973 0.071 0.973 / 0.026);
+ --plumA2: color(display-p3 0.933 0.267 1 / 0.059);
+ --plumA3: color(display-p3 0.918 0.333 0.996 / 0.148);
+ --plumA4: color(display-p3 0.91 0.318 1 / 0.219);
+ --plumA5: color(display-p3 0.914 0.388 1 / 0.269);
+ --plumA6: color(display-p3 0.906 0.463 1 / 0.328);
+ --plumA7: color(display-p3 0.906 0.529 1 / 0.425);
+ --plumA8: color(display-p3 0.906 0.553 1 / 0.568);
+ --plumA9: color(display-p3 0.875 0.427 1 / 0.69);
+ --plumA10: color(display-p3 0.886 0.471 0.996 / 0.732);
+ --plumA11: color(display-p3 0.86 0.602 0.933);
+ --plumA12: color(display-p3 0.936 0.836 0.949);
+ --purple1: color(display-p3 0.09 0.068 0.103);
+ --purple2: color(display-p3 0.113 0.082 0.134);
+ --purple3: color(display-p3 0.175 0.112 0.224);
+ --purple4: color(display-p3 0.224 0.137 0.297);
+ --purple5: color(display-p3 0.264 0.167 0.349);
+ --purple6: color(display-p3 0.311 0.208 0.406);
+ --purple7: color(display-p3 0.381 0.266 0.496);
+ --purple8: color(display-p3 0.49 0.349 0.649);
+ --purple9: color(display-p3 0.523 0.318 0.751);
+ --purple10: color(display-p3 0.57 0.373 0.791);
+ --purple11: color(display-p3 0.8 0.62 1);
+ --purple12: color(display-p3 0.913 0.854 0.971);
+ --purpleA1: color(display-p3 0.686 0.071 0.996 / 0.038);
+ --purpleA2: color(display-p3 0.722 0.286 0.996 / 0.072);
+ --purpleA3: color(display-p3 0.718 0.349 0.996 / 0.169);
+ --purpleA4: color(display-p3 0.702 0.353 1 / 0.248);
+ --purpleA5: color(display-p3 0.718 0.404 1 / 0.303);
+ --purpleA6: color(display-p3 0.733 0.455 1 / 0.366);
+ --purpleA7: color(display-p3 0.753 0.506 1 / 0.458);
+ --purpleA8: color(display-p3 0.749 0.522 1 / 0.622);
+ --purpleA9: color(display-p3 0.686 0.408 1 / 0.736);
+ --purpleA10: color(display-p3 0.71 0.459 1 / 0.778);
+ --purpleA11: color(display-p3 0.8 0.62 1);
+ --purpleA12: color(display-p3 0.913 0.854 0.971);
+ --red1: color(display-p3 0.093 0.068 0.067);
+ --red2: color(display-p3 0.118 0.077 0.079);
+ --red3: color(display-p3 0.211 0.081 0.099);
+ --red4: color(display-p3 0.287 0.079 0.113);
+ --red5: color(display-p3 0.348 0.11 0.142);
+ --red6: color(display-p3 0.414 0.16 0.183);
+ --red7: color(display-p3 0.508 0.224 0.236);
+ --red8: color(display-p3 0.659 0.298 0.297);
+ --red9: color(display-p3 0.83 0.329 0.324);
+ --red10: color(display-p3 0.861 0.403 0.387);
+ --red11: color(display-p3 1 0.57 0.55);
+ --red12: color(display-p3 0.971 0.826 0.852);
+ --redA1: color(display-p3 0.984 0.071 0.071 / 0.03);
+ --redA2: color(display-p3 0.996 0.282 0.282 / 0.055);
+ --redA3: color(display-p3 1 0.169 0.271 / 0.156);
+ --redA4: color(display-p3 1 0.118 0.267 / 0.236);
+ --redA5: color(display-p3 1 0.212 0.314 / 0.303);
+ --redA6: color(display-p3 1 0.318 0.38 / 0.374);
+ --redA7: color(display-p3 1 0.4 0.424 / 0.475);
+ --redA8: color(display-p3 1 0.431 0.431 / 0.635);
+ --redA9: color(display-p3 1 0.388 0.384 / 0.82);
+ --redA10: color(display-p3 1 0.463 0.447 / 0.853);
+ --redA11: color(display-p3 1 0.57 0.55);
+ --redA12: color(display-p3 0.971 0.826 0.852);
+ --ruby1: color(display-p3 0.093 0.068 0.074);
+ --ruby2: color(display-p3 0.113 0.083 0.089);
+ --ruby3: color(display-p3 0.208 0.088 0.117);
+ --ruby4: color(display-p3 0.279 0.092 0.147);
+ --ruby5: color(display-p3 0.337 0.12 0.18);
+ --ruby6: color(display-p3 0.401 0.166 0.223);
+ --ruby7: color(display-p3 0.495 0.224 0.281);
+ --ruby8: color(display-p3 0.652 0.295 0.359);
+ --ruby9: color(display-p3 0.83 0.323 0.408);
+ --ruby10: color(display-p3 0.857 0.392 0.455);
+ --ruby11: color(display-p3 1 0.57 0.59);
+ --ruby12: color(display-p3 0.968 0.83 0.88);
+ --rubyA1: color(display-p3 0.984 0.071 0.329 / 0.03);
+ --rubyA2: color(display-p3 0.992 0.376 0.529 / 0.051);
+ --rubyA3: color(display-p3 0.996 0.196 0.404 / 0.152);
+ --rubyA4: color(display-p3 1 0.173 0.416 / 0.227);
+ --rubyA5: color(display-p3 1 0.259 0.459 / 0.29);
+ --rubyA6: color(display-p3 1 0.341 0.506 / 0.358);
+ --rubyA7: color(display-p3 1 0.412 0.541 / 0.458);
+ --rubyA8: color(display-p3 1 0.431 0.537 / 0.627);
+ --rubyA9: color(display-p3 1 0.376 0.482 / 0.82);
+ --rubyA10: color(display-p3 1 0.447 0.522 / 0.849);
+ --rubyA11: color(display-p3 1 0.57 0.59);
+ --rubyA12: color(display-p3 0.968 0.83 0.88);
+ --sage1: color(display-p3 0.064 0.07 0.067);
+ --sage2: color(display-p3 0.092 0.098 0.094);
+ --sage3: color(display-p3 0.128 0.135 0.131);
+ --sage4: color(display-p3 0.155 0.164 0.159);
+ --sage5: color(display-p3 0.183 0.193 0.188);
+ --sage6: color(display-p3 0.218 0.23 0.224);
+ --sage7: color(display-p3 0.269 0.285 0.277);
+ --sage8: color(display-p3 0.362 0.382 0.373);
+ --sage9: color(display-p3 0.398 0.438 0.421);
+ --sage10: color(display-p3 0.453 0.49 0.474);
+ --sage11: color(display-p3 0.685 0.709 0.697);
+ --sage12: color(display-p3 0.927 0.933 0.93);
+ --sageA1: color(display-p3 0 0 0 / 0);
+ --sageA2: color(display-p3 0.976 0.988 0.984 / 0.03);
+ --sageA3: color(display-p3 0.992 0.945 0.941 / 0.072);
+ --sageA4: color(display-p3 0.988 0.996 0.992 / 0.102);
+ --sageA5: color(display-p3 0.992 1 0.996 / 0.131);
+ --sageA6: color(display-p3 0.973 1 0.976 / 0.173);
+ --sageA7: color(display-p3 0.957 1 0.976 / 0.233);
+ --sageA8: color(display-p3 0.957 1 0.984 / 0.334);
+ --sageA9: color(display-p3 0.902 1 0.957 / 0.397);
+ --sageA10: color(display-p3 0.929 1 0.973 / 0.452);
+ --sageA11: color(display-p3 0.969 1 0.988 / 0.688);
+ --sageA12: color(display-p3 0.992 1 0.996 / 0.929);
+ --sand1: color(display-p3 0.067 0.067 0.063);
+ --sand2: color(display-p3 0.098 0.098 0.094);
+ --sand3: color(display-p3 0.135 0.135 0.129);
+ --sand4: color(display-p3 0.164 0.163 0.156);
+ --sand5: color(display-p3 0.193 0.192 0.183);
+ --sand6: color(display-p3 0.23 0.229 0.217);
+ --sand7: color(display-p3 0.285 0.282 0.267);
+ --sand8: color(display-p3 0.384 0.378 0.357);
+ --sand9: color(display-p3 0.434 0.428 0.403);
+ --sand10: color(display-p3 0.487 0.481 0.456);
+ --sand11: color(display-p3 0.707 0.703 0.68);
+ --sand12: color(display-p3 0.933 0.933 0.926);
+ --sandA1: color(display-p3 0 0 0 / 0);
+ --sandA2: color(display-p3 0.992 0.992 0.988 / 0.034);
+ --sandA3: color(display-p3 0.996 0.996 0.992 / 0.072);
+ --sandA4: color(display-p3 0.992 0.992 0.953 / 0.106);
+ --sandA5: color(display-p3 1 1 0.965 / 0.135);
+ --sandA6: color(display-p3 1 0.976 0.929 / 0.177);
+ --sandA7: color(display-p3 1 0.984 0.929 / 0.236);
+ --sandA8: color(display-p3 1 0.976 0.925 / 0.341);
+ --sandA9: color(display-p3 1 0.98 0.925 / 0.395);
+ --sandA10: color(display-p3 1 0.992 0.933 / 0.45);
+ --sandA11: color(display-p3 1 0.996 0.961 / 0.685);
+ --sandA12: color(display-p3 1 1 0.992 / 0.929);
+ --sky1: color(display-p3 0.056 0.078 0.116);
+ --sky2: color(display-p3 0.075 0.101 0.149);
+ --sky3: color(display-p3 0.089 0.154 0.244);
+ --sky4: color(display-p3 0.106 0.207 0.323);
+ --sky5: color(display-p3 0.135 0.261 0.394);
+ --sky6: color(display-p3 0.17 0.322 0.469);
+ --sky7: color(display-p3 0.205 0.394 0.557);
+ --sky8: color(display-p3 0.232 0.48 0.665);
+ --sky9: color(display-p3 0.585 0.877 0.983);
+ --sky10: color(display-p3 0.718 0.925 0.991);
+ --sky11: color(display-p3 0.536 0.772 0.924);
+ --sky12: color(display-p3 0.799 0.947 0.993);
+ --skyA1: color(display-p3 0 0.282 0.996 / 0.055);
+ --skyA2: color(display-p3 0.157 0.467 0.992 / 0.089);
+ --skyA3: color(display-p3 0.192 0.522 0.996 / 0.19);
+ --skyA4: color(display-p3 0.212 0.584 1 / 0.274);
+ --skyA5: color(display-p3 0.259 0.631 1 / 0.349);
+ --skyA6: color(display-p3 0.302 0.655 1 / 0.433);
+ --skyA7: color(display-p3 0.329 0.686 1 / 0.526);
+ --skyA8: color(display-p3 0.325 0.71 1 / 0.643);
+ --skyA9: color(display-p3 0.592 0.894 1 / 0.984);
+ --skyA10: color(display-p3 0.722 0.933 1 / 0.992);
+ --skyA11: color(display-p3 0.536 0.772 0.924);
+ --skyA12: color(display-p3 0.799 0.947 0.993);
+ --slate1: color(display-p3 0.067 0.067 0.074);
+ --slate2: color(display-p3 0.095 0.098 0.105);
+ --slate3: color(display-p3 0.13 0.135 0.145);
+ --slate4: color(display-p3 0.156 0.163 0.176);
+ --slate5: color(display-p3 0.183 0.191 0.206);
+ --slate6: color(display-p3 0.215 0.226 0.244);
+ --slate7: color(display-p3 0.265 0.28 0.302);
+ --slate8: color(display-p3 0.357 0.381 0.409);
+ --slate9: color(display-p3 0.415 0.431 0.463);
+ --slate10: color(display-p3 0.469 0.483 0.514);
+ --slate11: color(display-p3 0.692 0.704 0.728);
+ --slate12: color(display-p3 0.93 0.933 0.94);
+ --slateA1: color(display-p3 0 0 0 / 0);
+ --slateA2: color(display-p3 0.875 0.992 1 / 0.034);
+ --slateA3: color(display-p3 0.882 0.933 0.992 / 0.077);
+ --slateA4: color(display-p3 0.882 0.953 0.996 / 0.111);
+ --slateA5: color(display-p3 0.878 0.929 0.996 / 0.145);
+ --slateA6: color(display-p3 0.882 0.949 0.996 / 0.183);
+ --slateA7: color(display-p3 0.882 0.929 1 / 0.246);
+ --slateA8: color(display-p3 0.871 0.937 1 / 0.361);
+ --slateA9: color(display-p3 0.898 0.937 1 / 0.42);
+ --slateA10: color(display-p3 0.918 0.945 1 / 0.475);
+ --slateA11: color(display-p3 0.949 0.969 0.996 / 0.708);
+ --slateA12: color(display-p3 0.988 0.992 1 / 0.937);
+ --teal1: color(display-p3 0.059 0.083 0.079);
+ --teal2: color(display-p3 0.075 0.11 0.107);
+ --teal3: color(display-p3 0.087 0.175 0.165);
+ --teal4: color(display-p3 0.087 0.227 0.214);
+ --teal5: color(display-p3 0.12 0.277 0.261);
+ --teal6: color(display-p3 0.162 0.335 0.314);
+ --teal7: color(display-p3 0.205 0.406 0.379);
+ --teal8: color(display-p3 0.245 0.489 0.453);
+ --teal9: color(display-p3 0.297 0.637 0.581);
+ --teal10: color(display-p3 0.319 0.69 0.62);
+ --teal11: color(display-p3 0.388 0.835 0.719);
+ --teal12: color(display-p3 0.734 0.934 0.87);
+ --tealA1: color(display-p3 0 0.992 0.761 / 0.017);
+ --tealA2: color(display-p3 0.235 0.988 0.902 / 0.047);
+ --tealA3: color(display-p3 0.235 1 0.898 / 0.118);
+ --tealA4: color(display-p3 0.18 0.996 0.929 / 0.173);
+ --tealA5: color(display-p3 0.31 1 0.933 / 0.227);
+ --tealA6: color(display-p3 0.396 1 0.933 / 0.286);
+ --tealA7: color(display-p3 0.443 1 0.925 / 0.366);
+ --tealA8: color(display-p3 0.459 1 0.925 / 0.454);
+ --tealA9: color(display-p3 0.443 0.996 0.906 / 0.61);
+ --tealA10: color(display-p3 0.439 0.996 0.89 / 0.669);
+ --tealA11: color(display-p3 0.388 0.835 0.719);
+ --tealA12: color(display-p3 0.734 0.934 0.87);
+ --tomato1: color(display-p3 0.09 0.068 0.067);
+ --tomato2: color(display-p3 0.115 0.084 0.076);
+ --tomato3: color(display-p3 0.205 0.097 0.083);
+ --tomato4: color(display-p3 0.282 0.099 0.077);
+ --tomato5: color(display-p3 0.339 0.129 0.101);
+ --tomato6: color(display-p3 0.398 0.179 0.141);
+ --tomato7: color(display-p3 0.487 0.245 0.194);
+ --tomato8: color(display-p3 0.629 0.322 0.248);
+ --tomato9: color(display-p3 0.831 0.345 0.231);
+ --tomato10: color(display-p3 0.862 0.415 0.298);
+ --tomato11: color(display-p3 1 0.585 0.455);
+ --tomato12: color(display-p3 0.959 0.833 0.802);
+ --tomatoA1: color(display-p3 0.973 0.071 0.071 / 0.026);
+ --tomatoA2: color(display-p3 0.992 0.376 0.224 / 0.051);
+ --tomatoA3: color(display-p3 0.996 0.282 0.176 / 0.148);
+ --tomatoA4: color(display-p3 1 0.204 0.118 / 0.232);
+ --tomatoA5: color(display-p3 1 0.286 0.192 / 0.29);
+ --tomatoA6: color(display-p3 1 0.392 0.278 / 0.353);
+ --tomatoA7: color(display-p3 1 0.459 0.349 / 0.45);
+ --tomatoA8: color(display-p3 1 0.49 0.369 / 0.601);
+ --tomatoA9: color(display-p3 1 0.408 0.267 / 0.82);
+ --tomatoA10: color(display-p3 1 0.478 0.341 / 0.853);
+ --tomatoA11: color(display-p3 1 0.585 0.455);
+ --tomatoA12: color(display-p3 0.959 0.833 0.802);
+ --violet1: color(display-p3 0.077 0.071 0.118);
+ --violet2: color(display-p3 0.101 0.084 0.141);
+ --violet3: color(display-p3 0.154 0.123 0.256);
+ --violet4: color(display-p3 0.191 0.148 0.345);
+ --violet5: color(display-p3 0.226 0.182 0.396);
+ --violet6: color(display-p3 0.269 0.223 0.449);
+ --violet7: color(display-p3 0.326 0.277 0.53);
+ --violet8: color(display-p3 0.399 0.346 0.656);
+ --violet9: color(display-p3 0.417 0.341 0.784);
+ --violet10: color(display-p3 0.477 0.402 0.823);
+ --violet11: color(display-p3 0.72 0.65 1);
+ --violet12: color(display-p3 0.883 0.867 0.986);
+ --violetA1: color(display-p3 0.282 0.141 0.996 / 0.055);
+ --violetA2: color(display-p3 0.51 0.263 1 / 0.08);
+ --violetA3: color(display-p3 0.494 0.337 0.996 / 0.202);
+ --violetA4: color(display-p3 0.49 0.345 1 / 0.299);
+ --violetA5: color(display-p3 0.525 0.392 1 / 0.353);
+ --violetA6: color(display-p3 0.569 0.455 1 / 0.408);
+ --violetA7: color(display-p3 0.588 0.494 1 / 0.496);
+ --violetA8: color(display-p3 0.596 0.51 1 / 0.631);
+ --violetA9: color(display-p3 0.522 0.424 1 / 0.769);
+ --violetA10: color(display-p3 0.576 0.482 1 / 0.811);
+ --violetA11: color(display-p3 0.72 0.65 1);
+ --violetA12: color(display-p3 0.883 0.867 0.986);
+ --yellow1: color(display-p3 0.078 0.069 0.047);
+ --yellow2: color(display-p3 0.103 0.094 0.063);
+ --yellow3: color(display-p3 0.168 0.137 0.039);
+ --yellow4: color(display-p3 0.209 0.169 0);
+ --yellow5: color(display-p3 0.255 0.209 0);
+ --yellow6: color(display-p3 0.31 0.261 0.07);
+ --yellow7: color(display-p3 0.389 0.331 0.135);
+ --yellow8: color(display-p3 0.497 0.42 0.182);
+ --yellow9: color(display-p3 1 0.92 0.22);
+ --yellow10: color(display-p3 1 1 0.456);
+ --yellow11: color(display-p3 0.948 0.885 0.392);
+ --yellow12: color(display-p3 0.959 0.934 0.731);
+ --yellowA1: color(display-p3 0.973 0.369 0 / 0.013);
+ --yellowA2: color(display-p3 0.996 0.792 0 / 0.038);
+ --yellowA3: color(display-p3 0.996 0.71 0 / 0.11);
+ --yellowA4: color(display-p3 0.996 0.741 0 / 0.152);
+ --yellowA5: color(display-p3 0.996 0.765 0 / 0.202);
+ --yellowA6: color(display-p3 0.996 0.816 0.082 / 0.261);
+ --yellowA7: color(display-p3 1 0.831 0.263 / 0.345);
+ --yellowA8: color(display-p3 1 0.831 0.314 / 0.463);
+ --yellowA9: color(display-p3 1 0.922 0.22);
+ --yellowA10: color(display-p3 1 1 0.455);
+ --yellowA11: color(display-p3 0.948 0.885 0.392);
+ --yellowA12: color(display-p3 0.959 0.934 0.731);
+ }
+ }
+}
+
+:root {
+ --chart-1: 12 76% 61%;
+ --chart-2: 173 58% 39%;
+ --chart-3: 197 37% 24%;
+ --chart-4: 43 74% 66%;
+ --chart-5: 27 87% 67%;
+ --border: var(--gray4);
+}
+
+.dark {
+ --chart-1: 220 70% 50%;
+ --chart-2: 160 60% 45%;
+ --chart-3: 30 80% 55%;
+ --chart-4: 280 65% 60%;
+ --chart-5: 340 75% 55%;
+}
+
+* {
+ border-color: var(--gray4);
+}
+
+html,
+body {
+ background-color: var(--gray1);
+ font-family: var(--font-labil-grotesk);
+ color: var(--gray12);
+}
+
+.container {
+ width: 100%;
+}
+
+@media (min-width: 640px) {
+ .container {
+ max-width: 640px;
+ }
+}
+
+@media (min-width: 768px) {
+ .container {
+ max-width: 768px;
+ }
+}
+
+@media (min-width: 1024px) {
+ .container {
+ max-width: 1024px;
+ }
+}
+
+@media (min-width: 1280px) {
+ .container {
+ max-width: 1280px;
+ }
+}
+
+@media (min-width: 1536px) {
+ .container {
+ max-width: 1536px;
+ }
+}
+
+.prose {
+ color: var(--tw-prose-body);
+ max-width: 65ch;
+}
+
+.prose :where(p):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 1.25em;
+ margin-bottom: 1.25em;
+}
+
+.prose
+ :where([class~='lead']):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ color: var(--tw-prose-lead);
+ font-size: 1.25em;
+ line-height: 1.6;
+ margin-top: 1.2em;
+ margin-bottom: 1.2em;
+}
+
+.prose :where(a):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-links);
+ text-decoration: underline;
+ font-weight: 500;
+}
+
+.prose
+ :where(strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-bold);
+ font-weight: 600;
+}
+
+.prose
+ :where(a strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: inherit;
+}
+
+.prose
+ :where(blockquote strong):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ color: inherit;
+}
+
+.prose
+ :where(thead th strong):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ color: inherit;
+}
+
+.prose :where(ol):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ list-style-type: decimal;
+ margin-top: 1.25em;
+ margin-bottom: 1.25em;
+ padding-inline-start: 1.625em;
+}
+
+.prose
+ :where(ol[type='A']):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ list-style-type: upper-alpha;
+}
+
+.prose
+ :where(ol[type='a']):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ list-style-type: lower-alpha;
+}
+
+.prose
+ :where(ol[type='A' s]):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ list-style-type: upper-alpha;
+}
+
+.prose
+ :where(ol[type='a' s]):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ list-style-type: lower-alpha;
+}
+
+.prose
+ :where(ol[type='I']):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ list-style-type: upper-roman;
+}
+
+.prose
+ :where(ol[type='i']):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ list-style-type: lower-roman;
+}
+
+.prose
+ :where(ol[type='I' s]):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ list-style-type: upper-roman;
+}
+
+.prose
+ :where(ol[type='i' s]):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ list-style-type: lower-roman;
+}
+
+.prose
+ :where(ol[type='1']):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ list-style-type: decimal;
+}
+
+.prose :where(ul):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ list-style-type: disc;
+ margin-top: 1.25em;
+ margin-bottom: 1.25em;
+ padding-inline-start: 1.625em;
+}
+
+.prose
+ :where(ol > li):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ )::marker {
+ font-weight: 400;
+ color: var(--tw-prose-counters);
+}
+
+.prose
+ :where(ul > li):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ )::marker {
+ color: var(--tw-prose-bullets);
+}
+
+.prose :where(dt):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-headings);
+ font-weight: 600;
+ margin-top: 1.25em;
+}
+
+.prose :where(hr):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ border-color: var(--tw-prose-hr);
+ border-top-width: 1px;
+ margin-top: 3em;
+ margin-bottom: 3em;
+}
+
+.prose
+ :where(blockquote):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ font-weight: 500;
+ font-style: italic;
+ color: var(--tw-prose-quotes);
+ border-inline-start-width: 0.25rem;
+ border-inline-start-color: var(--tw-prose-quote-borders);
+ quotes: '\201C' '\201D' '\2018' '\2019';
+ margin-top: 1.6em;
+ margin-bottom: 1.6em;
+ padding-inline-start: 1em;
+}
+
+.prose
+ :where(blockquote p:first-of-type):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ )::before {
+ content: open-quote;
+}
+
+.prose
+ :where(blockquote p:last-of-type):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ )::after {
+ content: close-quote;
+}
+
+.prose :where(h1):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-headings);
+ font-weight: 800;
+ font-size: 2.25em;
+ margin-top: 0;
+ margin-bottom: 0.8888889em;
+ line-height: 1.1111111;
+}
+
+.prose
+ :where(h1 strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ font-weight: 900;
+ color: inherit;
+}
+
+.prose :where(h2):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-headings);
+ font-weight: 700;
+ font-size: 1.5em;
+ margin-top: 2em;
+ margin-bottom: 1em;
+ line-height: 1.3333333;
+}
+
+.prose
+ :where(h2 strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ font-weight: 800;
+ color: inherit;
+}
+
+.prose :where(h3):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-headings);
+ font-weight: 600;
+ font-size: 1.25em;
+ margin-top: 1.6em;
+ margin-bottom: 0.6em;
+ line-height: 1.6;
+}
+
+.prose
+ :where(h3 strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ font-weight: 700;
+ color: inherit;
+}
+
+.prose :where(h4):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-headings);
+ font-weight: 600;
+ margin-top: 1.5em;
+ margin-bottom: 0.5em;
+ line-height: 1.5;
+}
+
+.prose
+ :where(h4 strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ font-weight: 700;
+ color: inherit;
+}
+
+.prose :where(img):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 2em;
+ margin-bottom: 2em;
+}
+
+.prose
+ :where(picture):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ display: block;
+ margin-top: 2em;
+ margin-bottom: 2em;
+}
+
+.prose :where(video):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 2em;
+ margin-bottom: 2em;
+}
+
+.prose :where(kbd):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ font-weight: 500;
+ font-family: inherit;
+ color: var(--tw-prose-kbd);
+ box-shadow:
+ 0 0 0 1px rgb(var(--tw-prose-kbd-shadows) / 10%),
+ 0 3px 0 rgb(var(--tw-prose-kbd-shadows) / 10%);
+ font-size: 0.875em;
+ border-radius: 0.3125rem;
+ padding-top: 0.1875em;
+ padding-inline-end: 0.375em;
+ padding-bottom: 0.1875em;
+ padding-inline-start: 0.375em;
+}
+
+.prose :where(code):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-code);
+ font-weight: 600;
+ font-size: 0.875em;
+}
+
+.prose
+ :where(code):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ )::before {
+ content: '`';
+}
+
+.prose
+ :where(code):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ )::after {
+ content: '`';
+}
+
+.prose
+ :where(a code):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: inherit;
+}
+
+.prose
+ :where(h1 code):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: inherit;
+}
+
+.prose
+ :where(h2 code):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: inherit;
+ font-size: 0.875em;
+}
+
+.prose
+ :where(h3 code):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: inherit;
+ font-size: 0.9em;
+}
+
+.prose
+ :where(h4 code):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: inherit;
+}
+
+.prose
+ :where(blockquote code):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ color: inherit;
+}
+
+.prose
+ :where(thead th code):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ color: inherit;
+}
+
+.prose :where(pre):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-pre-code);
+ background-color: var(--tw-prose-pre-bg);
+ overflow-x: auto;
+ font-weight: 400;
+ font-size: 0.875em;
+ line-height: 1.7142857;
+ margin-top: 1.7142857em;
+ margin-bottom: 1.7142857em;
+ border-radius: 0.375rem;
+ padding-top: 0.8571429em;
+ padding-inline-end: 1.1428571em;
+ padding-bottom: 0.8571429em;
+ padding-inline-start: 1.1428571em;
+}
+
+.prose
+ :where(pre code):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ background-color: transparent;
+ border-width: 0;
+ border-radius: 0;
+ padding: 0;
+ font-weight: inherit;
+ color: inherit;
+ font-size: inherit;
+ font-family: inherit;
+ line-height: inherit;
+}
+
+.prose
+ :where(pre code):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ )::before {
+ content: none;
+}
+
+.prose
+ :where(pre code):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ )::after {
+ content: none;
+}
+
+.prose :where(table):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ width: 100%;
+ table-layout: auto;
+ margin-top: 2em;
+ margin-bottom: 2em;
+ font-size: 0.875em;
+ line-height: 1.7142857;
+}
+
+.prose :where(thead):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ border-bottom-width: 1px;
+ border-bottom-color: var(--tw-prose-th-borders);
+}
+
+.prose
+ :where(thead th):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-headings);
+ font-weight: 600;
+ vertical-align: bottom;
+ padding-inline-end: 0.5714286em;
+ padding-bottom: 0.5714286em;
+ padding-inline-start: 0.5714286em;
+}
+
+.prose
+ :where(tbody tr):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ border-bottom-width: 1px;
+ border-bottom-color: var(--tw-prose-td-borders);
+}
+
+.prose
+ :where(tbody tr:last-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ border-bottom-width: 0;
+}
+
+.prose
+ :where(tbody td):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ vertical-align: baseline;
+}
+
+.prose :where(tfoot):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ border-top-width: 1px;
+ border-top-color: var(--tw-prose-th-borders);
+}
+
+.prose
+ :where(tfoot td):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ vertical-align: top;
+}
+
+.prose
+ :where(th, td):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ text-align: start;
+}
+
+.prose
+ :where(figure > *):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.prose
+ :where(figcaption):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ color: var(--tw-prose-captions);
+ font-size: 0.875em;
+ line-height: 1.4285714;
+ margin-top: 0.8571429em;
+}
+
+.prose {
+ --tw-prose-body: #374151;
+ --tw-prose-headings: #111827;
+ --tw-prose-lead: #4b5563;
+ --tw-prose-links: #111827;
+ --tw-prose-bold: #111827;
+ --tw-prose-counters: #6b7280;
+ --tw-prose-bullets: #d1d5db;
+ --tw-prose-hr: #e5e7eb;
+ --tw-prose-quotes: #111827;
+ --tw-prose-quote-borders: #e5e7eb;
+ --tw-prose-captions: #6b7280;
+ --tw-prose-kbd: #111827;
+ --tw-prose-kbd-shadows: 17 24 39;
+ --tw-prose-code: #111827;
+ --tw-prose-pre-code: #e5e7eb;
+ --tw-prose-pre-bg: #1f2937;
+ --tw-prose-th-borders: #d1d5db;
+ --tw-prose-td-borders: #e5e7eb;
+ --tw-prose-invert-body: #d1d5db;
+ --tw-prose-invert-headings: #fff;
+ --tw-prose-invert-lead: #9ca3af;
+ --tw-prose-invert-links: #fff;
+ --tw-prose-invert-bold: #fff;
+ --tw-prose-invert-counters: #9ca3af;
+ --tw-prose-invert-bullets: #4b5563;
+ --tw-prose-invert-hr: #374151;
+ --tw-prose-invert-quotes: #f3f4f6;
+ --tw-prose-invert-quote-borders: #374151;
+ --tw-prose-invert-captions: #9ca3af;
+ --tw-prose-invert-kbd: #fff;
+ --tw-prose-invert-kbd-shadows: 255 255 255;
+ --tw-prose-invert-code: #fff;
+ --tw-prose-invert-pre-code: #d1d5db;
+ --tw-prose-invert-pre-bg: rgb(0 0 0 / 50%);
+ --tw-prose-invert-th-borders: #4b5563;
+ --tw-prose-invert-td-borders: #374151;
+ font-size: 1rem;
+ line-height: 1.75;
+}
+
+.prose
+ :where(picture > img):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.prose :where(li):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+.prose
+ :where(ol > li):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ padding-inline-start: 0.375em;
+}
+
+.prose
+ :where(ul > li):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ padding-inline-start: 0.375em;
+}
+
+.prose
+ :where(.prose > ul > li p):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ margin-top: 0.75em;
+ margin-bottom: 0.75em;
+}
+
+.prose
+ :where(.prose > ul > li > p:first-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ margin-top: 1.25em;
+}
+
+.prose
+ :where(.prose > ul > li > p:last-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ margin-bottom: 1.25em;
+}
+
+.prose
+ :where(.prose > ol > li > p:first-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ margin-top: 1.25em;
+}
+
+.prose
+ :where(.prose > ol > li > p:last-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ margin-bottom: 1.25em;
+}
+
+.prose
+ :where(ul ul, ul ol, ol ul, ol ol):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ margin-top: 0.75em;
+ margin-bottom: 0.75em;
+}
+
+.prose :where(dl):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 1.25em;
+ margin-bottom: 1.25em;
+}
+
+.prose :where(dd):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 0.5em;
+ padding-inline-start: 1.625em;
+}
+
+.prose
+ :where(hr + *):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 0;
+}
+
+.prose
+ :where(h2 + *):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 0;
+}
+
+.prose
+ :where(h3 + *):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 0;
+}
+
+.prose
+ :where(h4 + *):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 0;
+}
+
+.prose
+ :where(thead th:first-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ padding-inline-start: 0;
+}
+
+.prose
+ :where(thead th:last-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ padding-inline-end: 0;
+}
+
+.prose
+ :where(tbody td, tfoot td):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ padding-top: 0.5714286em;
+ padding-inline-end: 0.5714286em;
+ padding-bottom: 0.5714286em;
+ padding-inline-start: 0.5714286em;
+}
+
+.prose
+ :where(tbody td:first-child, tfoot td:first-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ padding-inline-start: 0;
+}
+
+.prose
+ :where(tbody td:last-child, tfoot td:last-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ padding-inline-end: 0;
+}
+
+.prose
+ :where(figure):not(:where([class~='not-prose'], [class~='not-prose'] *)) {
+ margin-top: 2em;
+ margin-bottom: 2em;
+}
+
+.prose
+ :where(.prose > :first-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ margin-top: 0;
+}
+
+.prose
+ :where(.prose > :last-child):not(
+ :where([class~='not-prose'], [class~='not-prose'] *)
+ ) {
+ margin-bottom: 0;
+}
+
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border-width: 0;
+}
+
+.pointer-events-none {
+ pointer-events: none;
+}
+
+.pointer-events-auto {
+ pointer-events: auto;
+}
+
+.visible {
+ visibility: visible;
+}
+
+.invisible {
+ visibility: hidden;
+}
+
+.collapse {
+ visibility: collapse;
+}
+
+.static {
+ position: static;
+}
+
+.fixed {
+ position: fixed;
+}
+
+.absolute {
+ position: absolute;
+}
+
+.relative {
+ position: relative;
+}
+
+.sticky {
+ position: sticky;
+}
+
+.inset-0 {
+ inset: 0px;
+}
+
+.inset-auto {
+ inset: auto;
+}
+
+.inset-x-0 {
+ left: 0px;
+ right: 0px;
+}
+
+.inset-x-1\/2 {
+ left: 50%;
+ right: 50%;
+}
+
+.inset-x-auto {
+ left: auto;
+ right: auto;
+}
+
+.inset-y-0 {
+ top: 0px;
+ bottom: 0px;
+}
+
+.inset-y-auto {
+ top: auto;
+ bottom: auto;
+}
+
+.-bottom-0 {
+ bottom: -0px;
+}
+
+.-bottom-1 {
+ bottom: -0.25rem;
+}
+
+.-bottom-10 {
+ bottom: -2.5rem;
+}
+
+.-bottom-12 {
+ bottom: -3rem;
+}
+
+.-bottom-14 {
+ bottom: -3.5rem;
+}
+
+.-bottom-7 {
+ bottom: -1.75rem;
+}
+
+.-left-0 {
+ left: -0px;
+}
+
+.-left-1 {
+ left: -0.25rem;
+}
+
+.-left-10 {
+ left: -2.5rem;
+}
+
+.-left-12 {
+ left: -3rem;
+}
+
+.-left-7 {
+ left: -1.75rem;
+}
+
+.-right-0 {
+ right: -0px;
+}
+
+.-right-1 {
+ right: -0.25rem;
+}
+
+.-right-1\/3 {
+ right: -33.333333%;
+}
+
+.-right-1\/4 {
+ right: -25%;
+}
+
+.-right-10 {
+ right: -2.5rem;
+}
+
+.-right-12 {
+ right: -3rem;
+}
+
+.-right-7 {
+ right: -1.75rem;
+}
+
+.-top-0 {
+ top: -0px;
+}
+
+.-top-1 {
+ top: -0.25rem;
+}
+
+.-top-1\/2 {
+ top: -50%;
+}
+
+.-top-10 {
+ top: -2.5rem;
+}
+
+.-top-12 {
+ top: -3rem;
+}
+
+.-top-7 {
+ top: -1.75rem;
+}
+
+.-top-8 {
+ top: -2rem;
+}
+
+.-top-px {
+ top: -1px;
+}
+
+.bottom-0 {
+ bottom: 0px;
+}
+
+.bottom-8 {
+ bottom: 2rem;
+}
+
+.bottom-auto {
+ bottom: auto;
+}
+
+.left-0 {
+ left: 0px;
+}
+
+.left-1 {
+ left: 0.25rem;
+}
+
+.left-1\/2 {
+ left: 50%;
+}
+
+.left-1\/3 {
+ left: 33.333333%;
+}
+
+.left-1\/4 {
+ left: 25%;
+}
+
+.left-16 {
+ left: 4rem;
+}
+
+.left-2 {
+ left: 0.5rem;
+}
+
+.left-20 {
+ left: 5rem;
+}
+
+.left-3 {
+ left: 0.75rem;
+}
+
+.left-\[32px\] {
+ left: 32px;
+}
+
+.left-auto {
+ left: auto;
+}
+
+.right-0 {
+ right: 0px;
+}
+
+.right-1 {
+ right: 0.25rem;
+}
+
+.right-1\/3 {
+ right: 33.333333%;
+}
+
+.right-1\/4 {
+ right: 25%;
+}
+
+.right-10 {
+ right: 2.5rem;
+}
+
+.right-2 {
+ right: 0.5rem;
+}
+
+.right-3 {
+ right: 0.75rem;
+}
+
+.right-4 {
+ right: 1rem;
+}
+
+.right-auto {
+ right: auto;
+}
+
+.top-0 {
+ top: 0px;
+}
+
+.top-1 {
+ top: 0.25rem;
+}
+
+.top-1\/2 {
+ top: 50%;
+}
+
+.top-12 {
+ top: 3rem;
+}
+
+.top-20 {
+ top: 5rem;
+}
+
+.top-28 {
+ top: 7rem;
+}
+
+.top-3 {
+ top: 0.75rem;
+}
+
+.top-4 {
+ top: 1rem;
+}
+
+.top-9 {
+ top: 2.25rem;
+}
+
+.top-\[60\%\] {
+ top: 60%;
+}
+
+.top-\[80px\] {
+ top: 80px;
+}
+
+.top-\[96px\] {
+ top: 96px;
+}
+
+.top-auto {
+ top: auto;
+}
+
+.top-full {
+ top: 100%;
+}
+
+.top-px {
+ top: 1px;
+}
+
+.isolate {
+ isolation: isolate;
+}
+
+.z-0 {
+ z-index: 0;
+}
+
+.z-10 {
+ z-index: 10;
+}
+
+.z-20 {
+ z-index: 20;
+}
+
+.z-50 {
+ z-index: 50;
+}
+
+.z-\[-1\] {
+ z-index: -1;
+}
+
+.z-\[0\] {
+ z-index: 0;
+}
+
+.z-\[100\] {
+ z-index: 100;
+}
+
+.z-\[11\] {
+ z-index: 11;
+}
+
+.z-\[14\] {
+ z-index: 14;
+}
+
+.z-\[19\] {
+ z-index: 19;
+}
+
+.z-\[1\] {
+ z-index: 1;
+}
+
+.z-\[2\] {
+ z-index: 2;
+}
+
+.z-\[3\] {
+ z-index: 3;
+}
+
+.z-\[4\] {
+ z-index: 4;
+}
+
+.z-\[5\] {
+ z-index: 5;
+}
+
+.z-\[6\] {
+ z-index: 6;
+}
+
+.col-span-1 {
+ grid-column: span 1 / span 1;
+}
+
+.col-span-2 {
+ grid-column: span 2 / span 2;
+}
+
+.\!m-0 {
+ margin: 0px !important;
+}
+
+.m-0 {
+ margin: 0px;
+}
+
+.m-auto {
+ margin: auto;
+}
+
+.-mx-1 {
+ margin-left: -0.25rem;
+ margin-right: -0.25rem;
+}
+
+.-mx-4 {
+ margin-left: -1rem;
+ margin-right: -1rem;
+}
+
+.-my-20 {
+ margin-top: -5rem;
+ margin-bottom: -5rem;
+}
+
+.mx-0 {
+ margin-left: 0px;
+ margin-right: 0px;
+}
+
+.mx-2 {
+ margin-left: 0.5rem;
+ margin-right: 0.5rem;
+}
+
+.mx-auto {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.my-0 {
+ margin-top: 0px;
+ margin-bottom: 0px;
+}
+
+.my-0\.5 {
+ margin-top: 0.125rem;
+ margin-bottom: 0.125rem;
+}
+
+.my-1 {
+ margin-top: 0.25rem;
+ margin-bottom: 0.25rem;
+}
+
+.my-4 {
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+}
+
+.my-6 {
+ margin-top: 1.5rem;
+ margin-bottom: 1.5rem;
+}
+
+.my-auto {
+ margin-top: auto;
+ margin-bottom: auto;
+}
+
+.-mb-2 {
+ margin-bottom: -0.5rem;
+}
+
+.-ml-2 {
+ margin-left: -0.5rem;
+}
+
+.-ml-4 {
+ margin-left: -1rem;
+}
+
+.-mt-4 {
+ margin-top: -1rem;
+}
+
+.mb-0 {
+ margin-bottom: 0px;
+}
+
+.mb-1 {
+ margin-bottom: 0.25rem;
+}
+
+.mb-12 {
+ margin-bottom: 3rem;
+}
+
+.mb-16 {
+ margin-bottom: 4rem;
+}
+
+.mb-2 {
+ margin-bottom: 0.5rem;
+}
+
+.mb-4 {
+ margin-bottom: 1rem;
+}
+
+.mb-6 {
+ margin-bottom: 1.5rem;
+}
+
+.mb-8 {
+ margin-bottom: 2rem;
+}
+
+.mb-auto {
+ margin-bottom: auto;
+}
+
+.ml-0 {
+ margin-left: 0px;
+}
+
+.ml-0\.5 {
+ margin-left: 0.125rem;
+}
+
+.ml-1 {
+ margin-left: 0.25rem;
+}
+
+.ml-6 {
+ margin-left: 1.5rem;
+}
+
+.ml-auto {
+ margin-left: auto;
+}
+
+.mr-0 {
+ margin-right: 0px;
+}
+
+.mr-2 {
+ margin-right: 0.5rem;
+}
+
+.mr-3 {
+ margin-right: 0.75rem;
+}
+
+.mr-auto {
+ margin-right: auto;
+}
+
+.mt-0 {
+ margin-top: 0px;
+}
+
+.mt-1\.5 {
+ margin-top: 0.375rem;
+}
+
+.mt-2 {
+ margin-top: 0.5rem;
+}
+
+.mt-20 {
+ margin-top: 5rem;
+}
+
+.mt-24 {
+ margin-top: 6rem;
+}
+
+.mt-4 {
+ margin-top: 1rem;
+}
+
+.mt-6 {
+ margin-top: 1.5rem;
+}
+
+.mt-8 {
+ margin-top: 2rem;
+}
+
+.mt-auto {
+ margin-top: auto;
+}
+
+.line-clamp-1 {
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 1;
+}
+
+.line-clamp-2 {
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 2;
+}
+
+.line-clamp-3 {
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 3;
+}
+
+.block {
+ display: block;
+}
+
+.inline-block {
+ display: inline-block;
+}
+
+.flex {
+ display: flex;
+}
+
+.inline-flex {
+ display: inline-flex;
+}
+
+.table {
+ display: table;
+}
+
+.grid {
+ display: grid;
+}
+
+.hidden {
+ display: none;
+}
+
+.aspect-\[1_\/_1\] {
+ aspect-ratio: 1 / 1;
+}
+
+.size-1 {
+ width: 0.25rem;
+ height: 0.25rem;
+}
+
+.size-10 {
+ width: 2.5rem;
+ height: 2.5rem;
+}
+
+.size-12 {
+ width: 3rem;
+ height: 3rem;
+}
+
+.size-2 {
+ width: 0.5rem;
+ height: 0.5rem;
+}
+
+.size-2\.5 {
+ width: 0.625rem;
+ height: 0.625rem;
+}
+
+.size-3 {
+ width: 0.75rem;
+ height: 0.75rem;
+}
+
+.size-3\.5 {
+ width: 0.875rem;
+ height: 0.875rem;
+}
+
+.size-36 {
+ width: 9rem;
+ height: 9rem;
+}
+
+.size-4 {
+ width: 1rem;
+ height: 1rem;
+}
+
+.size-5 {
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
+.size-6 {
+ width: 1.5rem;
+ height: 1.5rem;
+}
+
+.size-7 {
+ width: 1.75rem;
+ height: 1.75rem;
+}
+
+.size-8 {
+ width: 2rem;
+ height: 2rem;
+}
+
+.size-9 {
+ width: 2.25rem;
+ height: 2.25rem;
+}
+
+.size-\[13\.85rem\] {
+ width: 13.85rem;
+ height: 13.85rem;
+}
+
+.size-\[19\.5rem\] {
+ width: 19.5rem;
+ height: 19.5rem;
+}
+
+.size-\[4\.5rem\] {
+ width: 4.5rem;
+ height: 4.5rem;
+}
+
+.size-\[43\.25rem\] {
+ width: 43.25rem;
+ height: 43.25rem;
+}
+
+.size-\[62\.5rem\] {
+ width: 62.5rem;
+ height: 62.5rem;
+}
+
+.size-\[8\.75rem\] {
+ width: 8.75rem;
+ height: 8.75rem;
+}
+
+.size-full {
+ width: 100%;
+ height: 100%;
+}
+
+.\!h-32 {
+ height: 8rem !important;
+}
+
+.h-1\.5 {
+ height: 0.375rem;
+}
+
+.h-1\/2 {
+ height: 50%;
+}
+
+.h-10 {
+ height: 2.5rem;
+}
+
+.h-12 {
+ height: 3rem;
+}
+
+.h-14 {
+ height: 3.5rem;
+}
+
+.h-2 {
+ height: 0.5rem;
+}
+
+.h-2\.5 {
+ height: 0.625rem;
+}
+
+.h-20 {
+ height: 5rem;
+}
+
+.h-24 {
+ height: 6rem;
+}
+
+.h-4 {
+ height: 1rem;
+}
+
+.h-40 {
+ height: 10rem;
+}
+
+.h-5 {
+ height: 1.25rem;
+}
+
+.h-6 {
+ height: 1.5rem;
+}
+
+.h-64 {
+ height: 16rem;
+}
+
+.h-8 {
+ height: 2rem;
+}
+
+.h-80 {
+ height: 20rem;
+}
+
+.h-9 {
+ height: 2.25rem;
+}
+
+.h-\[200\%\] {
+ height: 200%;
+}
+
+.h-\[600px\] {
+ height: 600px;
+}
+
+.h-\[75dvh\] {
+ height: 75dvh;
+}
+
+.h-\[calc\(100\%_-_128px\)\] {
+ height: calc(100% - 128px);
+}
+
+.h-\[calc\(100dvh_-_32px\)\] {
+ height: calc(100dvh - 32px);
+}
+
+.h-\[var\(--radix-navigation-menu-viewport-height\)\] {
+ height: var(--radix-navigation-menu-viewport-height);
+}
+
+.h-\[var\(--radix-select-trigger-height\)\] {
+ height: var(--radix-select-trigger-height);
+}
+
+.h-auto {
+ height: auto;
+}
+
+.h-fit {
+ height: -moz-fit-content;
+ height: fit-content;
+}
+
+.h-full {
+ height: 100%;
+}
+
+.h-px {
+ height: 1px;
+}
+
+.h-screen {
+ height: 100vh;
+}
+
+.max-h-2 {
+ max-height: 0.5rem;
+}
+
+.max-h-32 {
+ max-height: 8rem;
+}
+
+.max-h-8 {
+ max-height: 2rem;
+}
+
+.max-h-96 {
+ max-height: 24rem;
+}
+
+.max-h-\[100dvh\] {
+ max-height: 100dvh;
+}
+
+.max-h-\[280px\] {
+ max-height: 280px;
+}
+
+.max-h-\[300px\] {
+ max-height: 300px;
+}
+
+.max-h-\[500px\] {
+ max-height: 500px;
+}
+
+.max-h-\[calc\(100dvh_-_192px\)\] {
+ max-height: calc(100dvh - 192px);
+}
+
+.max-h-\[calc\(100dvh_-_200px\)\] {
+ max-height: calc(100dvh - 200px);
+}
+
+.max-h-full {
+ max-height: 100%;
+}
+
+.max-h-px {
+ max-height: 1px;
+}
+
+.max-h-screen {
+ max-height: 100vh;
+}
+
+.\!min-h-32 {
+ min-height: 8rem !important;
+}
+
+.min-h-16 {
+ min-height: 4rem;
+}
+
+.min-h-56 {
+ min-height: 14rem;
+}
+
+.min-h-72 {
+ min-height: 18rem;
+}
+
+.min-h-8 {
+ min-height: 2rem;
+}
+
+.min-h-80 {
+ min-height: 20rem;
+}
+
+.min-h-\[100dvh\] {
+ min-height: 100dvh;
+}
+
+.min-h-\[600px\] {
+ min-height: 600px;
+}
+
+.min-h-\[60px\] {
+ min-height: 60px;
+}
+
+.min-h-\[calc\(100\%_-_0px\)\] {
+ min-height: calc(100% - 0px);
+}
+
+.min-h-full {
+ min-height: 100%;
+}
+
+.min-h-screen {
+ min-height: 100vh;
+}
+
+.\!w-32 {
+ width: 8rem !important;
+}
+
+.w-0 {
+ width: 0px;
+}
+
+.w-1 {
+ width: 0.25rem;
+}
+
+.w-1\/2 {
+ width: 50%;
+}
+
+.w-1\/4 {
+ width: 25%;
+}
+
+.w-1\/6 {
+ width: 16.666667%;
+}
+
+.w-11 {
+ width: 2.75rem;
+}
+
+.w-14 {
+ width: 3.5rem;
+}
+
+.w-2\.5 {
+ width: 0.625rem;
+}
+
+.w-20 {
+ width: 5rem;
+}
+
+.w-3 {
+ width: 0.75rem;
+}
+
+.w-3\/4 {
+ width: 75%;
+}
+
+.w-32 {
+ width: 8rem;
+}
+
+.w-4 {
+ width: 1rem;
+}
+
+.w-56 {
+ width: 14rem;
+}
+
+.w-64 {
+ width: 16rem;
+}
+
+.w-72 {
+ width: 18rem;
+}
+
+.w-8 {
+ width: 2rem;
+}
+
+.w-80 {
+ width: 20rem;
+}
+
+.w-\[100dvw\] {
+ width: 100dvw;
+}
+
+.w-\[100px\] {
+ width: 100px;
+}
+
+.w-\[200px\] {
+ width: 200px;
+}
+
+.w-\[206px\] {
+ width: 206px;
+}
+
+.w-\[327px\] {
+ width: 327px;
+}
+
+.w-\[4px\] {
+ width: 4px;
+}
+
+.w-\[60\%\] {
+ width: 60%;
+}
+
+.w-\[743px\] {
+ width: 743px;
+}
+
+.w-\[calc\(100\%_-_4rem\)\] {
+ width: calc(100% - 4rem);
+}
+
+.w-\[calc\(75\%_-_80px\)\] {
+ width: calc(75% - 80px);
+}
+
+.w-auto {
+ width: auto;
+}
+
+.w-fit {
+ width: -moz-fit-content;
+ width: fit-content;
+}
+
+.w-full {
+ width: 100%;
+}
+
+.w-max {
+ width: -moz-max-content;
+ width: max-content;
+}
+
+.w-px {
+ width: 1px;
+}
+
+.w-screen {
+ width: 100vw;
+}
+
+.\!min-w-32 {
+ min-width: 8rem !important;
+}
+
+.min-w-0 {
+ min-width: 0px;
+}
+
+.min-w-16 {
+ min-width: 4rem;
+}
+
+.min-w-32 {
+ min-width: 8rem;
+}
+
+.min-w-48 {
+ min-width: 12rem;
+}
+
+.min-w-8 {
+ min-width: 2rem;
+}
+
+.min-w-96 {
+ min-width: 24rem;
+}
+
+.min-w-\[150dvw\] {
+ min-width: 150dvw;
+}
+
+.min-w-\[1920px\] {
+ min-width: 1920px;
+}
+
+.min-w-\[var\(--radix-select-trigger-width\)\] {
+ min-width: var(--radix-select-trigger-width);
+}
+
+.min-w-full {
+ min-width: 100%;
+}
+
+.min-w-px {
+ min-width: 1px;
+}
+
+.max-w-10 {
+ max-width: 2.5rem;
+}
+
+.max-w-14 {
+ max-width: 3.5rem;
+}
+
+.max-w-32 {
+ max-width: 8rem;
+}
+
+.max-w-\[100dvw\] {
+ max-width: 100dvw;
+}
+
+.max-w-\[60dvw\] {
+ max-width: 60dvw;
+}
+
+.max-w-\[75dvw\] {
+ max-width: 75dvw;
+}
+
+.max-w-\[800px\] {
+ max-width: 800px;
+}
+
+.max-w-\[calc\(100\%_-_32px\)\] {
+ max-width: calc(100% - 32px);
+}
+
+.max-w-\[calc\(100\%_-_4rem\)\] {
+ max-width: calc(100% - 4rem);
+}
+
+.max-w-fit {
+ max-width: -moz-fit-content;
+ max-width: fit-content;
+}
+
+.max-w-full {
+ max-width: 100%;
+}
+
+.max-w-lg {
+ max-width: 32rem;
+}
+
+.max-w-max {
+ max-width: -moz-max-content;
+ max-width: max-content;
+}
+
+.max-w-md {
+ max-width: 28rem;
+}
+
+.max-w-px {
+ max-width: 1px;
+}
+
+.max-w-screen-lg {
+ max-width: 1024px;
+}
+
+.max-w-screen-md {
+ max-width: 768px;
+}
+
+.max-w-sm {
+ max-width: 24rem;
+}
+
+.flex-1 {
+ flex: 1 1 0%;
+}
+
+.shrink {
+ flex-shrink: 1;
+}
+
+.shrink-0 {
+ flex-shrink: 0;
+}
+
+.grow {
+ flex-grow: 1;
+}
+
+.grow-0 {
+ flex-grow: 0;
+}
+
+.basis-1\/2 {
+ flex-basis: 50%;
+}
+
+.basis-1\/3 {
+ flex-basis: 33.333333%;
+}
+
+.basis-2\/3 {
+ flex-basis: 66.666667%;
+}
+
+.basis-full {
+ flex-basis: 100%;
+}
+
+.caption-bottom {
+ caption-side: bottom;
+}
+
+.border-collapse {
+ border-collapse: collapse;
+}
+
+.origin-\[top_center\] {
+ transform-origin: top center;
+}
+
+.origin-center {
+ transform-origin: center;
+}
+
+.origin-right {
+ transform-origin: right;
+}
+
+.-translate-x-1\/2 {
+ --tw-translate-x: -50%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.-translate-x-full {
+ --tw-translate-x: -100%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.-translate-x-px {
+ --tw-translate-x: -1px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.-translate-y-1\/2 {
+ --tw-translate-y: -50%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.-translate-y-2\.5 {
+ --tw-translate-y: -0.625rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.-translate-y-3 {
+ --tw-translate-y: -0.75rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.-translate-y-5 {
+ --tw-translate-y: -1.25rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.-translate-y-\[calc\(50\%_\+_40px\)\] {
+ --tw-translate-y: calc(calc(50% + 40px) * -1);
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-x-1\/2 {
+ --tw-translate-x: 50%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-x-12 {
+ --tw-translate-x: 3rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-x-2\.5 {
+ --tw-translate-x: 0.625rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-x-5 {
+ --tw-translate-x: 1.25rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-x-\[-25rem\] {
+ --tw-translate-x: -25rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-x-\[2px\] {
+ --tw-translate-x: 2px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-x-full {
+ --tw-translate-x: 100%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-x-px {
+ --tw-translate-x: 1px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-y-0 {
+ --tw-translate-y: 0px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-y-1\/4 {
+ --tw-translate-y: 25%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-y-2 {
+ --tw-translate-y: 0.5rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-y-3 {
+ --tw-translate-y: 0.75rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-y-4 {
+ --tw-translate-y: 1rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-y-40 {
+ --tw-translate-y: 10rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-y-\[10\.5rem\] {
+ --tw-translate-y: 10.5rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-y-\[6\.125rem\] {
+ --tw-translate-y: 6.125rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.rotate-0 {
+ --tw-rotate: 0deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.rotate-180 {
+ --tw-rotate: 180deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.rotate-2 {
+ --tw-rotate: 2deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.rotate-45 {
+ --tw-rotate: 45deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.rotate-90 {
+ --tw-rotate: 90deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.scale-0 {
+ --tw-scale-x: 0;
+ --tw-scale-y: 0;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.scale-100 {
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.scale-125 {
+ --tw-scale-x: 1.25;
+ --tw-scale-y: 1.25;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.scale-75 {
+ --tw-scale-x: 0.75;
+ --tw-scale-y: 0.75;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.scale-90 {
+ --tw-scale-x: 0.9;
+ --tw-scale-y: 0.9;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.-scale-x-100 {
+ --tw-scale-x: -1;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.scale-y-\[-0\.7\] {
+ --tw-scale-y: -0.7;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.transform {
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+@keyframes caret-blink {
+ 0%,
+ 70%,
+ 100% {
+ opacity: 1;
+ }
+
+ 20%,
+ 50% {
+ opacity: 0;
+ }
+}
+
+.animate-caret-blink {
+ animation: caret-blink 1.25s ease-out infinite;
+}
+
+@keyframes pulse {
+ 50% {
+ opacity: 0.5;
+ }
+}
+
+.animate-pulse {
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
+}
+
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.animate-spinSlow1x {
+ animation: spin 20.25s linear infinite;
+}
+
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.animate-spinSlow2x {
+ animation: spin 22.25s linear infinite;
+}
+
+.cursor-default {
+ cursor: default;
+}
+
+.cursor-grab {
+ cursor: grab;
+}
+
+.cursor-pointer {
+ cursor: pointer;
+}
+
+.touch-none {
+ touch-action: none;
+}
+
+.select-none {
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+
+.snap-center {
+ scroll-snap-align: center;
+}
+
+.scroll-m-0 {
+ scroll-margin: 0px;
+}
+
+.scroll-m-20 {
+ scroll-margin: 5rem;
+}
+
+.scroll-p-0 {
+ scroll-padding: 0px;
+}
+
+.list-decimal {
+ list-style-type: decimal;
+}
+
+.list-disc {
+ list-style-type: disc;
+}
+
+.list-none {
+ list-style-type: none;
+}
+
+.grid-cols-1 {
+ grid-template-columns: repeat(1, minmax(0, 1fr));
+}
+
+.grid-cols-2 {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+}
+
+.grid-cols-3 {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+.grid-cols-4 {
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+}
+
+.grid-rows-2 {
+ grid-template-rows: repeat(2, minmax(0, 1fr));
+}
+
+.flex-row {
+ flex-direction: row;
+}
+
+.flex-col {
+ flex-direction: column;
+}
+
+.flex-col-reverse {
+ flex-direction: column-reverse;
+}
+
+.flex-wrap {
+ flex-wrap: wrap;
+}
+
+.flex-nowrap {
+ flex-wrap: nowrap;
+}
+
+.place-content-center {
+ place-content: center;
+}
+
+.place-content-stretch {
+ place-content: stretch;
+}
+
+.place-items-center {
+ place-items: center;
+}
+
+.place-items-stretch {
+ place-items: stretch;
+}
+
+.content-center {
+ align-content: center;
+}
+
+.content-start {
+ align-content: flex-start;
+}
+
+.content-stretch {
+ align-content: stretch;
+}
+
+.items-start {
+ align-items: flex-start;
+}
+
+.items-end {
+ align-items: flex-end;
+}
+
+.items-center {
+ align-items: center;
+}
+
+.items-stretch {
+ align-items: stretch;
+}
+
+.justify-start {
+ justify-content: flex-start;
+}
+
+.justify-end {
+ justify-content: flex-end;
+}
+
+.justify-center {
+ justify-content: center;
+}
+
+.justify-between {
+ justify-content: space-between;
+}
+
+.justify-around {
+ justify-content: space-around;
+}
+
+.justify-stretch {
+ justify-content: stretch;
+}
+
+.justify-items-center {
+ justify-items: center;
+}
+
+.gap-0 {
+ gap: 0px;
+}
+
+.gap-0\.5 {
+ gap: 0.125rem;
+}
+
+.gap-1 {
+ gap: 0.25rem;
+}
+
+.gap-1\.5 {
+ gap: 0.375rem;
+}
+
+.gap-12 {
+ gap: 3rem;
+}
+
+.gap-2 {
+ gap: 0.5rem;
+}
+
+.gap-20 {
+ gap: 5rem;
+}
+
+.gap-3 {
+ gap: 0.75rem;
+}
+
+.gap-32 {
+ gap: 8rem;
+}
+
+.gap-4 {
+ gap: 1rem;
+}
+
+.gap-5 {
+ gap: 1.25rem;
+}
+
+.gap-6 {
+ gap: 1.5rem;
+}
+
+.gap-8 {
+ gap: 2rem;
+}
+
+.gap-\[3\.129rem\] {
+ gap: 3.129rem;
+}
+
+.gap-\[3\.25rem\] {
+ gap: 3.25rem;
+}
+
+.gap-px {
+ gap: 1px;
+}
+
+.gap-x-0 {
+ -moz-column-gap: 0px;
+ column-gap: 0px;
+}
+
+.gap-x-6 {
+ -moz-column-gap: 1.5rem;
+ column-gap: 1.5rem;
+}
+
+.gap-x-px {
+ -moz-column-gap: 1px;
+ column-gap: 1px;
+}
+
+.-space-x-0 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(-0px * var(--tw-space-x-reverse));
+ margin-left: calc(-0px * calc(1 - var(--tw-space-x-reverse)));
+}
+
+.-space-x-px > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(-1px * var(--tw-space-x-reverse));
+ margin-left: calc(-1px * calc(1 - var(--tw-space-x-reverse)));
+}
+
+.space-x-0 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(0px * var(--tw-space-x-reverse));
+ margin-left: calc(0px * calc(1 - var(--tw-space-x-reverse)));
+}
+
+.space-x-1 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(0.25rem * var(--tw-space-x-reverse));
+ margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));
+}
+
+.space-x-2 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(0.5rem * var(--tw-space-x-reverse));
+ margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
+}
+
+.space-x-4 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(1rem * var(--tw-space-x-reverse));
+ margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
+}
+
+.space-y-0 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(0px * var(--tw-space-y-reverse));
+}
+
+.space-y-1 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
+}
+
+.space-y-1\.5 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));
+}
+
+.space-y-2 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
+}
+
+.space-y-24 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(6rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(6rem * var(--tw-space-y-reverse));
+}
+
+.space-y-4 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(1rem * var(--tw-space-y-reverse));
+}
+
+.self-center {
+ align-self: center;
+}
+
+.overflow-auto {
+ overflow: auto;
+}
+
+.overflow-hidden {
+ overflow: hidden;
+}
+
+.overflow-visible {
+ overflow: visible;
+}
+
+.overflow-y-auto {
+ overflow-y: auto;
+}
+
+.overflow-x-hidden {
+ overflow-x: hidden;
+}
+
+.overflow-y-hidden {
+ overflow-y: hidden;
+}
+
+.overflow-x-clip {
+ overflow-x: clip;
+}
+
+.text-ellipsis {
+ text-overflow: ellipsis;
+}
+
+.whitespace-nowrap {
+ white-space: nowrap;
+}
+
+.whitespace-pre-wrap {
+ white-space: pre-wrap;
+}
+
+.\!text-nowrap {
+ text-wrap: nowrap !important;
+}
+
+.text-nowrap {
+ text-wrap: nowrap;
+}
+
+.text-balance {
+ text-wrap: balance;
+}
+
+.text-pretty {
+ text-wrap: pretty;
+}
+
+.break-words {
+ overflow-wrap: break-word;
+}
+
+.\!rounded-2xl {
+ border-radius: 1rem !important;
+}
+
+.rounded {
+ border-radius: 0.25rem;
+}
+
+.rounded-2xl {
+ border-radius: 1rem;
+}
+
+.rounded-3xl {
+ border-radius: 1.5rem;
+}
+
+.rounded-\[1\.4rem\] {
+ border-radius: 1.4rem;
+}
+
+.rounded-\[2px\] {
+ border-radius: 2px;
+}
+
+.rounded-\[2rem\] {
+ border-radius: 2rem;
+}
+
+.rounded-\[5\.5rem\] {
+ border-radius: 5.5rem;
+}
+
+.rounded-\[calc\(\.75rem_-_\.15rem\)\] {
+ border-radius: calc(0.75rem - 0.15rem);
+}
+
+.rounded-\[calc\(1rem_-_2px\)\] {
+ border-radius: calc(1rem - 2px);
+}
+
+.rounded-\[inherit\] {
+ border-radius: inherit;
+}
+
+.rounded-full {
+ border-radius: 9999px;
+}
+
+.rounded-lg {
+ border-radius: 0.5rem;
+}
+
+.rounded-md {
+ border-radius: 0.375rem;
+}
+
+.rounded-none {
+ border-radius: 0px;
+}
+
+.rounded-sm {
+ border-radius: 0.125rem;
+}
+
+.rounded-xl {
+ border-radius: 0.75rem;
+}
+
+.rounded-b-lg {
+ border-bottom-right-radius: 0.5rem;
+ border-bottom-left-radius: 0.5rem;
+}
+
+.rounded-l-full {
+ border-top-left-radius: 9999px;
+ border-bottom-left-radius: 9999px;
+}
+
+.rounded-l-lg {
+ border-top-left-radius: 0.5rem;
+ border-bottom-left-radius: 0.5rem;
+}
+
+.rounded-l-none {
+ border-top-left-radius: 0px;
+ border-bottom-left-radius: 0px;
+}
+
+.rounded-r-2xl {
+ border-top-right-radius: 1rem;
+ border-bottom-right-radius: 1rem;
+}
+
+.rounded-t-\[10px\] {
+ border-top-left-radius: 10px;
+ border-top-right-radius: 10px;
+}
+
+.rounded-tl-sm {
+ border-top-left-radius: 0.125rem;
+}
+
+.border {
+ border-width: 1px;
+}
+
+.border-0 {
+ border-width: 0px;
+}
+
+.border-2 {
+ border-width: 2px;
+}
+
+.border-\[1\.5px\] {
+ border-width: 1.5px;
+}
+
+.border-y {
+ border-top-width: 1px;
+ border-bottom-width: 1px;
+}
+
+.border-b {
+ border-bottom-width: 1px;
+}
+
+.border-b-0 {
+ border-bottom-width: 0px;
+}
+
+.border-l {
+ border-left-width: 1px;
+}
+
+.border-l-0 {
+ border-left-width: 0px;
+}
+
+.border-l-2 {
+ border-left-width: 2px;
+}
+
+.border-r {
+ border-right-width: 1px;
+}
+
+.border-t {
+ border-top-width: 1px;
+}
+
+.border-dashed {
+ border-style: dashed;
+}
+
+.border-none {
+ border-style: none;
+}
+
+.border-\[--color-border\] {
+ border-color: var(--color-border);
+}
+
+.border-\[--grayA2\] {
+ border-color: var(--grayA2);
+}
+
+.border-\[var\(--accentA5\)\] {
+ border-color: var(--accentA5);
+}
+
+.border-\[var\(--colorCardBorder\)\] {
+ border-color: var(--colorCardBorder);
+}
+
+.border-\[var\(--ghost-a2\)\] {
+ border-color: var(--ghost-a2);
+}
+
+.border-\[var\(--gray12\)\] {
+ border-color: var(--gray12);
+}
+
+.border-\[var\(--gray4\)\] {
+ border-color: var(--gray4);
+}
+
+.border-\[var\(--grayA1\)\] {
+ border-color: var(--grayA1);
+}
+
+.border-\[var\(--grayA2\)\] {
+ border-color: var(--grayA2);
+}
+
+.border-\[var\(--grayA3\)\] {
+ border-color: var(--grayA3);
+}
+
+.border-\[var\(--grayA4\)\] {
+ border-color: var(--grayA4);
+}
+
+.border-\[var\(--grayA5\)\] {
+ border-color: var(--grayA5);
+}
+
+.border-\[var\(--grayA6\)\] {
+ border-color: var(--grayA6);
+}
+
+.border-\[var\(--grayA7\)\] {
+ border-color: var(--grayA7);
+}
+
+.border-\[var\(--grayA8\)\] {
+ border-color: var(--grayA8);
+}
+
+.border-\[var\(--mintA9\)\] {
+ border-color: var(--mintA9);
+}
+
+.border-destructive {
+ border-color: var(--red9);
+}
+
+.border-ghost-a3 {
+ border-color: var(--ghost-a3);
+}
+
+.border-ghost-a4 {
+ border-color: var(--ghost-a4);
+}
+
+.border-ghost-a7 {
+ border-color: var(--ghost-a7);
+}
+
+.border-input {
+ border-color: var(--gray4);
+}
+
+.border-primary {
+ border-color: var(--violet9);
+}
+
+.border-primary-6 {
+ border-color: var(--violet6);
+}
+
+.border-red-6 {
+ border-color: var(--red6);
+}
+
+.border-transparent {
+ border-color: transparent;
+}
+
+.border-b-transparent {
+ border-bottom-color: transparent;
+}
+
+.border-l-transparent {
+ border-left-color: transparent;
+}
+
+.border-t-transparent {
+ border-top-color: transparent;
+}
+
+.\!bg-\[white\] {
+ --tw-bg-opacity: 1 !important;
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity)) !important;
+}
+
+.bg-\[--color-bg\] {
+ background-color: var(--color-bg);
+}
+
+.bg-\[var\(--accent1\)\] {
+ background-color: var(--accent1);
+}
+
+.bg-\[var\(--accentA5\)\] {
+ background-color: var(--accentA5);
+}
+
+.bg-\[var\(--colorCardBorder\)\] {
+ background-color: var(--colorCardBorder);
+}
+
+.bg-\[var\(--colorCardTagBg\)\] {
+ background-color: var(--colorCardTagBg);
+}
+
+.bg-\[var\(--ghost-12\)\] {
+ background-color: var(--ghost-12);
+}
+
+.bg-\[var\(--ghost-a2\)\] {
+ background-color: var(--ghost-a2);
+}
+
+.bg-\[var\(--ghost-aa1\)\] {
+ background-color: var(--ghost-aa1);
+}
+
+.bg-\[var\(--gray1\)\] {
+ background-color: var(--gray1);
+}
+
+.bg-\[var\(--gray12\)\] {
+ background-color: var(--gray12);
+}
+
+.bg-\[var\(--gray2\)\] {
+ background-color: var(--gray2);
+}
+
+.bg-\[var\(--gray3\)\] {
+ background-color: var(--gray3);
+}
+
+.bg-\[var\(--gray4\)\] {
+ background-color: var(--gray4);
+}
+
+.bg-\[var\(--gray6\)\] {
+ background-color: var(--gray6);
+}
+
+.bg-\[var\(--grayA1\)\] {
+ background-color: var(--grayA1);
+}
+
+.bg-\[var\(--grayA11\)\] {
+ background-color: var(--grayA11);
+}
+
+.bg-\[var\(--grayA12\)\] {
+ background-color: var(--grayA12);
+}
+
+.bg-\[var\(--grayA2\)\] {
+ background-color: var(--grayA2);
+}
+
+.bg-\[var\(--grayA4\)\] {
+ background-color: var(--grayA4);
+}
+
+.bg-\[var\(--grayA5\)\] {
+ background-color: var(--grayA5);
+}
+
+.bg-\[var\(--grayA7\)\] {
+ background-color: var(--grayA7);
+}
+
+.bg-\[var\(--grayA9\)\] {
+ background-color: var(--grayA9);
+}
+
+.bg-\[var\(--lime9\)\] {
+ background-color: var(--lime9);
+}
+
+.bg-\[var\(--orange9\)\] {
+ background-color: var(--orange9);
+}
+
+.bg-\[var\(--sky11\)\] {
+ background-color: var(--sky11);
+}
+
+.bg-accent {
+ background-color: var(--accent11);
+}
+
+.bg-accent-1 {
+ background-color: var(--accent1);
+}
+
+.bg-background {
+ background-color: var(--gray1);
+}
+
+.bg-black {
+ --tw-bg-opacity: 1;
+ background-color: rgb(0 0 0 / var(--tw-bg-opacity));
+}
+
+.bg-black\/80 {
+ background-color: rgb(0 0 0 / 0.8);
+}
+
+.bg-border {
+ background-color: var(--gray4);
+}
+
+.bg-card {
+ background-color: hsl(var(--gray2));
+}
+
+.bg-destructive {
+ background-color: var(--red9);
+}
+
+.bg-foreground {
+ background-color: var(--gray12);
+}
+
+.bg-ghost {
+ background-color: var(--ghost-a2);
+}
+
+.bg-ghost-a1 {
+ background-color: var(--ghost-a1);
+}
+
+.bg-ghost-a11 {
+ background-color: var(--ghost-a11);
+}
+
+.bg-ghost-aa7 {
+ background-color: var(--ghost-aa7);
+}
+
+.bg-gray-2 {
+ background-color: var(--gray2);
+}
+
+.bg-gray-3 {
+ background-color: var(--gray3);
+}
+
+.bg-muted {
+ background-color: var(--gray4);
+}
+
+.bg-popover {
+ background-color: var(--gray3);
+}
+
+.bg-primary {
+ background-color: var(--violet9);
+}
+
+.bg-primary-3 {
+ background-color: var(--violet3);
+}
+
+.bg-red-2 {
+ background-color: var(--red2);
+}
+
+.bg-secondary {
+ background-color: var(--blue10);
+}
+
+.bg-transparent {
+ background-color: transparent;
+}
+
+.bg-gradient-to-b {
+ background-image: linear-gradient(to bottom, var(--tw-gradient-stops));
+}
+
+.bg-gradient-to-br {
+ background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
+}
+
+.bg-gradient-to-r {
+ background-image: linear-gradient(to right, var(--tw-gradient-stops));
+}
+
+.bg-gradient-to-t {
+ background-image: linear-gradient(to top, var(--tw-gradient-stops));
+}
+
+.bg-radial-gradient-1 {
+ background-image: radial-gradient(
+ 87.07% 87.07% at 52.38% 100%,
+ var(--grayA1) 0%,
+ var(--grayA6) 100%
+ );
+}
+
+.bg-radial-gradient-2 {
+ background-image: radial-gradient(
+ 100.44% 141.42% at 0% 0%,
+ var(--grayA1) 0%,
+ var(--grayA6) 100%
+ );
+}
+
+.from-\[var\(--ghost-a1\)\] {
+ --tw-gradient-from: var(--ghost-a1) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--ghost-a7\)\] {
+ --tw-gradient-from: var(--ghost-a7) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--ghost-aa10\)\] {
+ --tw-gradient-from: var(--ghost-aa10) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--ghost-aa4\)\] {
+ --tw-gradient-from: var(--ghost-aa4) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--ghost-aa6\)\] {
+ --tw-gradient-from: var(--ghost-aa6) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--gray11\)\] {
+ --tw-gradient-from: var(--gray11) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--gray12\)\] {
+ --tw-gradient-from: var(--gray12) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--gray2\)\] {
+ --tw-gradient-from: var(--gray2) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--gray4\)\] {
+ --tw-gradient-from: var(--gray4) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--gray5\)\] {
+ --tw-gradient-from: var(--gray5) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--grayA1\)\] {
+ --tw-gradient-from: var(--grayA1) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--grayA10\)\] {
+ --tw-gradient-from: var(--grayA10) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--grayA2\)\] {
+ --tw-gradient-from: var(--grayA2) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--grayA4\)\] {
+ --tw-gradient-from: var(--grayA4) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--grayA5\)\] {
+ --tw-gradient-from: var(--grayA5) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--grayA6\)\] {
+ --tw-gradient-from: var(--grayA6) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--grayA8\)\] {
+ --tw-gradient-from: var(--grayA8) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-\[var\(--grayA9\)\] {
+ --tw-gradient-from: var(--grayA9) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-ghost {
+ --tw-gradient-from: var(--ghost-a2) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.from-ghost-a11 {
+ --tw-gradient-from: var(--ghost-a11) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.via-\[var\(--ghost-a12\)\] {
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from),
+ var(--ghost-a12) var(--tw-gradient-via-position), var(--tw-gradient-to);
+}
+
+.via-\[var\(--gray10\)\] {
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from),
+ var(--gray10) var(--tw-gradient-via-position), var(--tw-gradient-to);
+}
+
+.via-\[var\(--grayA3\)\] {
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from),
+ var(--grayA3) var(--tw-gradient-via-position), var(--tw-gradient-to);
+}
+
+.via-transparent {
+ --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from),
+ transparent var(--tw-gradient-via-position), var(--tw-gradient-to);
+}
+
+.to-\[var\(--ghost-2\)\] {
+ --tw-gradient-to: var(--ghost-2) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--ghost-a10\)\] {
+ --tw-gradient-to: var(--ghost-a10) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--ghost-a12\)\] {
+ --tw-gradient-to: var(--ghost-a12) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--ghost-a6\)\] {
+ --tw-gradient-to: var(--ghost-a6) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--gray1\)\] {
+ --tw-gradient-to: var(--gray1) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--gray12\)\] {
+ --tw-gradient-to: var(--gray12) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--gray3\)\] {
+ --tw-gradient-to: var(--gray3) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--gray9\)\] {
+ --tw-gradient-to: var(--gray9) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--grayA1\)\] {
+ --tw-gradient-to: var(--grayA1) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--grayA12\)\] {
+ --tw-gradient-to: var(--grayA12) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--grayA2\)\] {
+ --tw-gradient-to: var(--grayA2) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--grayA4\)\] {
+ --tw-gradient-to: var(--grayA4) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--grayA6\)\] {
+ --tw-gradient-to: var(--grayA6) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--grayA8\)\] {
+ --tw-gradient-to: var(--grayA8) var(--tw-gradient-to-position);
+}
+
+.to-\[var\(--grayA9\)\] {
+ --tw-gradient-to: var(--grayA9) var(--tw-gradient-to-position);
+}
+
+.to-ghost-a9 {
+ --tw-gradient-to: var(--ghost-a9) var(--tw-gradient-to-position);
+}
+
+.to-transparent {
+ --tw-gradient-to: transparent var(--tw-gradient-to-position);
+}
+
+.bg-clip-content {
+ background-clip: content-box;
+}
+
+.bg-clip-text {
+ -webkit-background-clip: text;
+ background-clip: text;
+}
+
+.fill-\[var\(--gray2\)\] {
+ fill: var(--gray2);
+}
+
+.fill-\[var\(--gray7\)\] {
+ fill: var(--gray7);
+}
+
+.fill-\[var\(--grayA2\)\] {
+ fill: var(--grayA2);
+}
+
+.fill-\[var\(--grayA5\)\] {
+ fill: var(--grayA5);
+}
+
+.fill-\[var\(--grayA8\)\] {
+ fill: var(--grayA8);
+}
+
+.fill-background {
+ fill: var(--gray1);
+}
+
+.fill-current {
+ fill: currentColor;
+}
+
+.fill-muted-foreground {
+ fill: var(--gray11);
+}
+
+.fill-primary {
+ fill: var(--violet9);
+}
+
+.stroke-\[var\(--grayA2\)\] {
+ stroke: var(--grayA2);
+}
+
+.stroke-\[var\(--grayA6\)\] {
+ stroke: var(--grayA6);
+}
+
+.stroke-none {
+ stroke: none;
+}
+
+.object-contain {
+ -o-object-fit: contain;
+ object-fit: contain;
+}
+
+.object-cover {
+ -o-object-fit: cover;
+ object-fit: cover;
+}
+
+.object-center {
+ -o-object-position: center;
+ object-position: center;
+}
+
+.object-top {
+ -o-object-position: top;
+ object-position: top;
+}
+
+.\!p-0 {
+ padding: 0px !important;
+}
+
+.p-0 {
+ padding: 0px;
+}
+
+.p-0\.5 {
+ padding: 0.125rem;
+}
+
+.p-1 {
+ padding: 0.25rem;
+}
+
+.p-10 {
+ padding: 2.5rem;
+}
+
+.p-12 {
+ padding: 3rem;
+}
+
+.p-2 {
+ padding: 0.5rem;
+}
+
+.p-20 {
+ padding: 5rem;
+}
+
+.p-3 {
+ padding: 0.75rem;
+}
+
+.p-4 {
+ padding: 1rem;
+}
+
+.p-6 {
+ padding: 1.5rem;
+}
+
+.p-8 {
+ padding: 2rem;
+}
+
+.p-\[0\.581rem\] {
+ padding: 0.581rem;
+}
+
+.p-\[0\.58rem\] {
+ padding: 0.58rem;
+}
+
+.p-px {
+ padding: 1px;
+}
+
+.px-0 {
+ padding-left: 0px;
+ padding-right: 0px;
+}
+
+.px-0\.5 {
+ padding-left: 0.125rem;
+ padding-right: 0.125rem;
+}
+
+.px-1 {
+ padding-left: 0.25rem;
+ padding-right: 0.25rem;
+}
+
+.px-1\.5 {
+ padding-left: 0.375rem;
+ padding-right: 0.375rem;
+}
+
+.px-10 {
+ padding-left: 2.5rem;
+ padding-right: 2.5rem;
+}
+
+.px-12 {
+ padding-left: 3rem;
+ padding-right: 3rem;
+}
+
+.px-2 {
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+}
+
+.px-2\.5 {
+ padding-left: 0.625rem;
+ padding-right: 0.625rem;
+}
+
+.px-3 {
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+}
+
+.px-3\.5 {
+ padding-left: 0.875rem;
+ padding-right: 0.875rem;
+}
+
+.px-4 {
+ padding-left: 1rem;
+ padding-right: 1rem;
+}
+
+.px-5 {
+ padding-left: 1.25rem;
+ padding-right: 1.25rem;
+}
+
+.px-6 {
+ padding-left: 1.5rem;
+ padding-right: 1.5rem;
+}
+
+.px-7 {
+ padding-left: 1.75rem;
+ padding-right: 1.75rem;
+}
+
+.px-8 {
+ padding-left: 2rem;
+ padding-right: 2rem;
+}
+
+.px-\[0\.3rem\] {
+ padding-left: 0.3rem;
+ padding-right: 0.3rem;
+}
+
+.py-0 {
+ padding-top: 0px;
+ padding-bottom: 0px;
+}
+
+.py-0\.5 {
+ padding-top: 0.125rem;
+ padding-bottom: 0.125rem;
+}
+
+.py-1 {
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+}
+
+.py-1\.5 {
+ padding-top: 0.375rem;
+ padding-bottom: 0.375rem;
+}
+
+.py-10 {
+ padding-top: 2.5rem;
+ padding-bottom: 2.5rem;
+}
+
+.py-12 {
+ padding-top: 3rem;
+ padding-bottom: 3rem;
+}
+
+.py-2 {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+
+.py-20 {
+ padding-top: 5rem;
+ padding-bottom: 5rem;
+}
+
+.py-3 {
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem;
+}
+
+.py-3\.5 {
+ padding-top: 0.875rem;
+ padding-bottom: 0.875rem;
+}
+
+.py-4 {
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+}
+
+.py-6 {
+ padding-top: 1.5rem;
+ padding-bottom: 1.5rem;
+}
+
+.py-8 {
+ padding-top: 2rem;
+ padding-bottom: 2rem;
+}
+
+.py-\[0\.2rem\] {
+ padding-top: 0.2rem;
+ padding-bottom: 0.2rem;
+}
+
+.py-px {
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+
+.pb-0 {
+ padding-bottom: 0px;
+}
+
+.pb-10 {
+ padding-bottom: 2.5rem;
+}
+
+.pb-12 {
+ padding-bottom: 3rem;
+}
+
+.pb-2 {
+ padding-bottom: 0.5rem;
+}
+
+.pb-20 {
+ padding-bottom: 5rem;
+}
+
+.pb-3 {
+ padding-bottom: 0.75rem;
+}
+
+.pb-3\.5 {
+ padding-bottom: 0.875rem;
+}
+
+.pb-32 {
+ padding-bottom: 8rem;
+}
+
+.pb-40 {
+ padding-bottom: 10rem;
+}
+
+.pb-5 {
+ padding-bottom: 1.25rem;
+}
+
+.pb-6 {
+ padding-bottom: 1.5rem;
+}
+
+.pl-0 {
+ padding-left: 0px;
+}
+
+.pl-12 {
+ padding-left: 3rem;
+}
+
+.pl-2 {
+ padding-left: 0.5rem;
+}
+
+.pl-2\.5 {
+ padding-left: 0.625rem;
+}
+
+.pl-4 {
+ padding-left: 1rem;
+}
+
+.pl-6 {
+ padding-left: 1.5rem;
+}
+
+.pl-8 {
+ padding-left: 2rem;
+}
+
+.pl-\[21\.5rem\] {
+ padding-left: 21.5rem;
+}
+
+.pr-0 {
+ padding-right: 0px;
+}
+
+.pr-1 {
+ padding-right: 0.25rem;
+}
+
+.pr-2 {
+ padding-right: 0.5rem;
+}
+
+.pr-2\.5 {
+ padding-right: 0.625rem;
+}
+
+.pr-3 {
+ padding-right: 0.75rem;
+}
+
+.pr-6 {
+ padding-right: 1.5rem;
+}
+
+.pr-8 {
+ padding-right: 2rem;
+}
+
+.pt-0 {
+ padding-top: 0px;
+}
+
+.pt-1 {
+ padding-top: 0.25rem;
+}
+
+.pt-10 {
+ padding-top: 2.5rem;
+}
+
+.pt-11 {
+ padding-top: 2.75rem;
+}
+
+.pt-16 {
+ padding-top: 4rem;
+}
+
+.pt-2 {
+ padding-top: 0.5rem;
+}
+
+.pt-20 {
+ padding-top: 5rem;
+}
+
+.pt-3 {
+ padding-top: 0.75rem;
+}
+
+.pt-4 {
+ padding-top: 1rem;
+}
+
+.pt-6 {
+ padding-top: 1.5rem;
+}
+
+.text-left {
+ text-align: left;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.align-middle {
+ vertical-align: middle;
+}
+
+.font-mono {
+ font-family: var(--font-ibm-plex-mono);
+}
+
+.text-2xl {
+ font-size: 1.5rem;
+ line-height: 2rem;
+}
+
+.text-3xl {
+ font-size: 1.875rem;
+ line-height: 2.25rem;
+}
+
+.text-4xl {
+ font-size: 2.25rem;
+ line-height: 2.5rem;
+}
+
+.text-6xl {
+ font-size: 3.75rem;
+ line-height: 1;
+}
+
+.text-7xl {
+ font-size: 4.5rem;
+ line-height: 1;
+}
+
+.text-8xl {
+ font-size: 6rem;
+ line-height: 1;
+}
+
+.text-\[\.65rem\] {
+ font-size: 0.65rem;
+}
+
+.text-\[0\.5rem\] {
+ font-size: 0.5rem;
+}
+
+.text-\[0\.625rem\] {
+ font-size: 0.625rem;
+}
+
+.text-\[0\.7rem\] {
+ font-size: 0.7rem;
+}
+
+.text-\[0\.8125rem\] {
+ font-size: 0.8125rem;
+}
+
+.text-\[0\.8rem\] {
+ font-size: 0.8rem;
+}
+
+.text-\[5\.925rem\] {
+ font-size: 5.925rem;
+}
+
+.text-\[8\.925rem\] {
+ font-size: 8.925rem;
+}
+
+.text-lg {
+ font-size: 1.125rem;
+ line-height: 1.75rem;
+}
+
+.text-sm {
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+}
+
+.text-xl {
+ font-size: 1.25rem;
+ line-height: 1.75rem;
+}
+
+.text-xs {
+ font-size: 0.75rem;
+ line-height: 1rem;
+}
+
+.font-bold {
+ font-weight: 700;
+}
+
+.font-extrabold {
+ font-weight: 800;
+}
+
+.font-medium {
+ font-weight: 500;
+}
+
+.font-normal {
+ font-weight: 400;
+}
+
+.font-semibold {
+ font-weight: 600;
+}
+
+.uppercase {
+ text-transform: uppercase;
+}
+
+.italic {
+ font-style: italic;
+}
+
+.tabular-nums {
+ --tw-numeric-spacing: tabular-nums;
+ font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero)
+ var(--tw-numeric-figure) var(--tw-numeric-spacing)
+ var(--tw-numeric-fraction);
+}
+
+.leading-7 {
+ line-height: 1.75rem;
+}
+
+.leading-\[100\%\] {
+ line-height: 100%;
+}
+
+.leading-\[64\%\] {
+ line-height: 64%;
+}
+
+.leading-\[75\%\] {
+ line-height: 75%;
+}
+
+.leading-\[80\%\] {
+ line-height: 80%;
+}
+
+.leading-none {
+ line-height: 1;
+}
+
+.leading-normal {
+ line-height: 1.5;
+}
+
+.leading-tight {
+ line-height: 1.25;
+}
+
+.tracking-\[-0\.325rem\] {
+ letter-spacing: -0.325rem;
+}
+
+.tracking-\[0\.25rem\] {
+ letter-spacing: 0.25rem;
+}
+
+.tracking-normal {
+ letter-spacing: 0em;
+}
+
+.tracking-tight {
+ letter-spacing: -0.025em;
+}
+
+.tracking-tighter {
+ letter-spacing: -0.05em;
+}
+
+.tracking-widest {
+ letter-spacing: 0.1em;
+}
+
+.text-\[var\(--accent11\)\] {
+ color: var(--accent11);
+}
+
+.text-\[var\(--ghost-1\)\] {
+ color: var(--ghost-1);
+}
+
+.text-\[var\(--ghost-a4\)\] {
+ color: var(--ghost-a4);
+}
+
+.text-\[var\(--ghost-a6\)\] {
+ color: var(--ghost-a6);
+}
+
+.text-\[var\(--gray1\)\] {
+ color: var(--gray1);
+}
+
+.text-\[var\(--gray10\)\] {
+ color: var(--gray10);
+}
+
+.text-\[var\(--gray11\)\] {
+ color: var(--gray11);
+}
+
+.text-\[var\(--gray7\)\] {
+ color: var(--gray7);
+}
+
+.text-\[var\(--gray8\)\] {
+ color: var(--gray8);
+}
+
+.text-\[var\(--gray9\)\] {
+ color: var(--gray9);
+}
+
+.text-\[var\(--grayA10\)\] {
+ color: var(--grayA10);
+}
+
+.text-\[var\(--grayA5\)\] {
+ color: var(--grayA5);
+}
+
+.text-\[var\(--grayA7\)\] {
+ color: var(--grayA7);
+}
+
+.text-\[var\(--grayA8\)\] {
+ color: var(--grayA8);
+}
+
+.text-\[var\(--grayA9\)\] {
+ color: var(--grayA9);
+}
+
+.text-\[var\(--indigoA6\)\] {
+ color: var(--indigoA6);
+}
+
+.text-\[var\(--redA2\)\] {
+ color: var(--redA2);
+}
+
+.text-accent {
+ color: var(--accent11);
+}
+
+.text-accent-foreground {
+ color: var(--accent2);
+}
+
+.text-accent-hover {
+ color: var(--accent12);
+}
+
+.text-card-foreground {
+ color: var(--gray11);
+}
+
+.text-current {
+ color: currentColor;
+}
+
+.text-destructive {
+ color: var(--red9);
+}
+
+.text-destructive-foreground {
+ color: var(--red1);
+}
+
+.text-foreground {
+ color: var(--gray12);
+}
+
+.text-gray-11 {
+ color: var(--gray11);
+}
+
+.text-gray-400 {
+ --tw-text-opacity: 1;
+ color: rgb(156 163 175 / var(--tw-text-opacity));
+}
+
+.text-gray-6 {
+ color: var(--gray6);
+}
+
+.text-muted-foreground {
+ color: var(--gray11);
+}
+
+.text-popover-foreground {
+ color: var(--gray11);
+}
+
+.text-primary {
+ color: var(--violet9);
+}
+
+.text-primary-foreground {
+ color: var(--violet1);
+}
+
+.text-secondary-foreground {
+ color: var(--blue1);
+}
+
+.text-transparent {
+ color: transparent;
+}
+
+.underline {
+ -webkit-text-decoration-line: underline;
+ text-decoration-line: underline;
+}
+
+.no-underline {
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+}
+
+.decoration-\[var\(--gray11\)\] {
+ -webkit-text-decoration-color: var(--gray11);
+ text-decoration-color: var(--gray11);
+}
+
+.underline-offset-4 {
+ text-underline-offset: 4px;
+}
+
+.underline-offset-8 {
+ text-underline-offset: 8px;
+}
+
+.opacity-0 {
+ opacity: 0;
+}
+
+.opacity-10 {
+ opacity: 0.1;
+}
+
+.opacity-100 {
+ opacity: 1;
+}
+
+.opacity-50 {
+ opacity: 0.5;
+}
+
+.opacity-60 {
+ opacity: 0.6;
+}
+
+.opacity-70 {
+ opacity: 0.7;
+}
+
+.opacity-80 {
+ opacity: 0.8;
+}
+
+.opacity-90 {
+ opacity: 0.9;
+}
+
+.opacity-\[0\.015\] {
+ opacity: 0.015;
+}
+
+.mix-blend-screen {
+ mix-blend-mode: screen;
+}
+
+.mix-blend-overlay {
+ mix-blend-mode: overlay;
+}
+
+.mix-blend-color-dodge {
+ mix-blend-mode: color-dodge;
+}
+
+.mix-blend-hard-light {
+ mix-blend-mode: hard-light;
+}
+
+.mix-blend-luminosity {
+ mix-blend-mode: luminosity;
+}
+
+.shadow {
+ --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color),
+ 0 1px 2px -1px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-2xl {
+ --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
+ --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-\[inset_0px_0px_2px_0px_rgba\(255\2c 255\2c 255\2c 0\.1\)\] {
+ --tw-shadow: inset 0px 0px 2px 0px rgba(255, 255, 255, 0.1);
+ --tw-shadow-colored: inset 0px 0px 2px 0px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-inner {
+ --tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-lg {
+ --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1),
+ 0 4px 6px -4px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color),
+ 0 4px 6px -4px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-md {
+ --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
+ 0 2px 4px -2px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-none {
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-sm {
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-xl {
+ --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1),
+ 0 8px 10px -6px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color),
+ 0 8px 10px -6px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-\[var\(--sky9\)\] {
+ --tw-shadow-color: var(--sky9);
+ --tw-shadow: var(--tw-shadow-colored);
+}
+
+.shadow-ghost-a5 {
+ --tw-shadow-color: var(--ghost-a5);
+ --tw-shadow: var(--tw-shadow-colored);
+}
+
+.outline-none {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.outline {
+ outline-style: solid;
+}
+
+.outline-1 {
+ outline-width: 1px;
+}
+
+.-outline-offset-1 {
+ outline-offset: -1px;
+}
+
+.-outline-offset-\[3px\] {
+ outline-offset: -3px;
+}
+
+.outline-\[--grayA2\] {
+ outline-color: var(--grayA2);
+}
+
+.outline-\[var\(--grayA5\)\] {
+ outline-color: var(--grayA5);
+}
+
+.outline-\[var\(--grayA6\)\] {
+ outline-color: var(--grayA6);
+}
+
+.ring-0 {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+}
+
+.ring-1 {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+}
+
+.ring-2 {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+}
+
+.ring-\[15px\] {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(15px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+}
+
+.ring-inset {
+ --tw-ring-inset: inset;
+}
+
+.ring-\[var\(--ghost-a4\)\] {
+ --tw-ring-color: var(--ghost-a4);
+}
+
+.ring-\[var\(--grayA1\)\] {
+ --tw-ring-color: var(--grayA1);
+}
+
+.ring-\[var\(--grayA2\)\] {
+ --tw-ring-color: var(--grayA2);
+}
+
+.ring-\[var\(--grayA3\)\] {
+ --tw-ring-color: var(--grayA3);
+}
+
+.ring-\[var\(--grayA4\)\] {
+ --tw-ring-color: var(--grayA4);
+}
+
+.ring-\[var\(--grayA5\)\] {
+ --tw-ring-color: var(--grayA5);
+}
+
+.ring-\[var\(--limeA3\)\] {
+ --tw-ring-color: var(--limeA3);
+}
+
+.ring-\[var\(--skyA3\)\] {
+ --tw-ring-color: var(--skyA3);
+}
+
+.ring-ring {
+ --tw-ring-color: var(--gray4);
+}
+
+.ring-transparent {
+ --tw-ring-color: transparent;
+}
+
+.ring-offset-background {
+ --tw-ring-offset-color: var(--gray1);
+}
+
+.blur {
+ --tw-blur: blur(8px);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.blur-lg {
+ --tw-blur: blur(16px);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.blur-md {
+ --tw-blur: blur(12px);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.blur-sm {
+ --tw-blur: blur(4px);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.blur-xl {
+ --tw-blur: blur(24px);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.brightness-0 {
+ --tw-brightness: brightness(0);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.brightness-150 {
+ --tw-brightness: brightness(1.5);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.brightness-50 {
+ --tw-brightness: brightness(0.5);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.brightness-\[2\] {
+ --tw-brightness: brightness(2);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.contrast-0 {
+ --tw-contrast: contrast(0);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.contrast-125 {
+ --tw-contrast: contrast(1.25);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.contrast-50 {
+ --tw-contrast: contrast(0.5);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.drop-shadow-xl {
+ --tw-drop-shadow: drop-shadow(0 20px 13px rgb(0 0 0 / 0.03))
+ drop-shadow(0 8px 5px rgb(0 0 0 / 0.08));
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.grayscale {
+ --tw-grayscale: grayscale(100%);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.saturate-0 {
+ --tw-saturate: saturate(0);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.saturate-150 {
+ --tw-saturate: saturate(1.5);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.saturate-50 {
+ --tw-saturate: saturate(0.5);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.filter {
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.backdrop-blur {
+ --tw-backdrop-blur: blur(8px);
+ -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
+ var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale)
+ var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
+ var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
+ var(--tw-backdrop-sepia);
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
+ var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale)
+ var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
+ var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
+ var(--tw-backdrop-sepia);
+}
+
+.backdrop-blur-md {
+ --tw-backdrop-blur: blur(12px);
+ -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
+ var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale)
+ var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
+ var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
+ var(--tw-backdrop-sepia);
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
+ var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale)
+ var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert)
+ var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
+ var(--tw-backdrop-sepia);
+}
+
+.transition {
+ transition-property:
+ color,
+ background-color,
+ border-color,
+ fill,
+ stroke,
+ opacity,
+ box-shadow,
+ transform,
+ filter,
+ -webkit-text-decoration-color,
+ -webkit-backdrop-filter;
+ transition-property: color, background-color, border-color,
+ text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter,
+ backdrop-filter;
+ transition-property:
+ color,
+ background-color,
+ border-color,
+ text-decoration-color,
+ fill,
+ stroke,
+ opacity,
+ box-shadow,
+ transform,
+ filter,
+ backdrop-filter,
+ -webkit-text-decoration-color,
+ -webkit-backdrop-filter;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.transition-all {
+ transition-property: all;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.transition-colors {
+ transition-property:
+ color,
+ background-color,
+ border-color,
+ fill,
+ stroke,
+ -webkit-text-decoration-color;
+ transition-property: color, background-color, border-color,
+ text-decoration-color, fill, stroke;
+ transition-property:
+ color,
+ background-color,
+ border-color,
+ text-decoration-color,
+ fill,
+ stroke,
+ -webkit-text-decoration-color;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.transition-opacity {
+ transition-property: opacity;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.transition-transform {
+ transition-property: transform;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.duration-1000 {
+ transition-duration: 1000ms;
+}
+
+.duration-200 {
+ transition-duration: 200ms;
+}
+
+.duration-300 {
+ transition-duration: 300ms;
+}
+
+.duration-500 {
+ transition-duration: 500ms;
+}
+
+.duration-700 {
+ transition-duration: 700ms;
+}
+
+.ease-in-out {
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.ease-out {
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
+}
+
+.will-change-auto {
+ will-change: auto;
+}
+
+.will-change-transform {
+ will-change: transform;
+}
+
+@keyframes enter {
+ from {
+ opacity: var(--tw-enter-opacity, 1);
+ transform: translate3d(
+ var(--tw-enter-translate-x, 0),
+ var(--tw-enter-translate-y, 0),
+ 0
+ )
+ scale3d(
+ var(--tw-enter-scale, 1),
+ var(--tw-enter-scale, 1),
+ var(--tw-enter-scale, 1)
+ )
+ rotate(var(--tw-enter-rotate, 0));
+ }
+}
+
+@keyframes exit {
+ to {
+ opacity: var(--tw-exit-opacity, 1);
+ transform: translate3d(
+ var(--tw-exit-translate-x, 0),
+ var(--tw-exit-translate-y, 0),
+ 0
+ )
+ scale3d(
+ var(--tw-exit-scale, 1),
+ var(--tw-exit-scale, 1),
+ var(--tw-exit-scale, 1)
+ )
+ rotate(var(--tw-exit-rotate, 0));
+ }
+}
+
+.animate-in {
+ animation-name: enter;
+ animation-duration: 150ms;
+ --tw-enter-opacity: initial;
+ --tw-enter-scale: initial;
+ --tw-enter-rotate: initial;
+ --tw-enter-translate-x: initial;
+ --tw-enter-translate-y: initial;
+}
+
+.fade-in-0 {
+ --tw-enter-opacity: 0;
+}
+
+.zoom-in-95 {
+ --tw-enter-scale: 0.95;
+}
+
+.duration-1000 {
+ animation-duration: 1000ms;
+}
+
+.duration-200 {
+ animation-duration: 200ms;
+}
+
+.duration-300 {
+ animation-duration: 300ms;
+}
+
+.duration-500 {
+ animation-duration: 500ms;
+}
+
+.duration-700 {
+ animation-duration: 700ms;
+}
+
+.ease-in-out {
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.ease-out {
+ animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
+}
+
+body[data-scroll-locked] {
+ padding: 1rem !important;
+}
+
+[data-accent-color='amber'] {
+ --accent1: var(--amber1);
+ --accent2: var(--amber2);
+ --accent3: var(--amber3);
+ --accent4: var(--amber4);
+ --accent5: var(--amber5);
+ --accent6: var(--amber6);
+ --accent7: var(--amber7);
+ --accent8: var(--amber8);
+ --accent9: var(--amber9);
+ --accent10: var(--amber10);
+ --accent11: var(--amber11);
+ --accent12: var(--amber12);
+ --accentA1: var(--amberA1);
+ --accentA2: var(--amberA2);
+ --accentA3: var(--amberA3);
+ --accentA4: var(--amberA4);
+ --accentA5: var(--amberA5);
+ --accentA6: var(--amberA6);
+ --accentA7: var(--amberA7);
+ --accentA8: var(--amberA8);
+ --accentA9: var(--amberA9);
+ --accentA10: var(--amberA10);
+ --accentA11: var(--amberA11);
+ --accentA12: var(--amberA12);
+}
+
+[data-accent-color='blue'] {
+ --accent1: var(--blue1);
+ --accent2: var(--blue2);
+ --accent3: var(--blue3);
+ --accent4: var(--blue4);
+ --accent5: var(--blue5);
+ --accent6: var(--blue6);
+ --accent7: var(--blue7);
+ --accent8: var(--blue8);
+ --accent9: var(--blue9);
+ --accent10: var(--blue10);
+ --accent11: var(--blue11);
+ --accent12: var(--blue12);
+ --accentA1: var(--blueA1);
+ --accentA2: var(--blueA2);
+ --accentA3: var(--blueA3);
+ --accentA4: var(--blueA4);
+ --accentA5: var(--blueA5);
+ --accentA6: var(--blueA6);
+ --accentA7: var(--blueA7);
+ --accentA8: var(--blueA8);
+ --accentA9: var(--blueA9);
+ --accentA10: var(--blueA10);
+ --accentA11: var(--blueA11);
+ --accentA12: var(--blueA12);
+}
+
+[data-accent-color='bronze'] {
+ --accent1: var(--bronze1);
+ --accent2: var(--bronze2);
+ --accent3: var(--bronze3);
+ --accent4: var(--bronze4);
+ --accent5: var(--bronze5);
+ --accent6: var(--bronze6);
+ --accent7: var(--bronze7);
+ --accent8: var(--bronze8);
+ --accent9: var(--bronze9);
+ --accent10: var(--bronze10);
+ --accent11: var(--bronze11);
+ --accent12: var(--bronze12);
+ --accentA1: var(--bronzeA1);
+ --accentA2: var(--bronzeA2);
+ --accentA3: var(--bronzeA3);
+ --accentA4: var(--bronzeA4);
+ --accentA5: var(--bronzeA5);
+ --accentA6: var(--bronzeA6);
+ --accentA7: var(--bronzeA7);
+ --accentA8: var(--bronzeA8);
+ --accentA9: var(--bronzeA9);
+ --accentA10: var(--bronzeA10);
+ --accentA11: var(--bronzeA11);
+ --accentA12: var(--bronzeA12);
+}
+
+[data-accent-color='brown'] {
+ --accent1: var(--brown1);
+ --accent2: var(--brown2);
+ --accent3: var(--brown3);
+ --accent4: var(--brown4);
+ --accent5: var(--brown5);
+ --accent6: var(--brown6);
+ --accent7: var(--brown7);
+ --accent8: var(--brown8);
+ --accent9: var(--brown9);
+ --accent10: var(--brown10);
+ --accent11: var(--brown11);
+ --accent12: var(--brown12);
+ --accentA1: var(--brownA1);
+ --accentA2: var(--brownA2);
+ --accentA3: var(--brownA3);
+ --accentA4: var(--brownA4);
+ --accentA5: var(--brownA5);
+ --accentA6: var(--brownA6);
+ --accentA7: var(--brownA7);
+ --accentA8: var(--brownA8);
+ --accentA9: var(--brownA9);
+ --accentA10: var(--brownA10);
+ --accentA11: var(--brownA11);
+ --accentA12: var(--brownA12);
+}
+
+[data-accent-color='crimson'] {
+ --accent1: var(--crimson1);
+ --accent2: var(--crimson2);
+ --accent3: var(--crimson3);
+ --accent4: var(--crimson4);
+ --accent5: var(--crimson5);
+ --accent6: var(--crimson6);
+ --accent7: var(--crimson7);
+ --accent8: var(--crimson8);
+ --accent9: var(--crimson9);
+ --accent10: var(--crimson10);
+ --accent11: var(--crimson11);
+ --accent12: var(--crimson12);
+ --accentA1: var(--crimsonA1);
+ --accentA2: var(--crimsonA2);
+ --accentA3: var(--crimsonA3);
+ --accentA4: var(--crimsonA4);
+ --accentA5: var(--crimsonA5);
+ --accentA6: var(--crimsonA6);
+ --accentA7: var(--crimsonA7);
+ --accentA8: var(--crimsonA8);
+ --accentA9: var(--crimsonA9);
+ --accentA10: var(--crimsonA10);
+ --accentA11: var(--crimsonA11);
+ --accentA12: var(--crimsonA12);
+}
+
+[data-accent-color='cyan'] {
+ --accent1: var(--cyan1);
+ --accent2: var(--cyan2);
+ --accent3: var(--cyan3);
+ --accent4: var(--cyan4);
+ --accent5: var(--cyan5);
+ --accent6: var(--cyan6);
+ --accent7: var(--cyan7);
+ --accent8: var(--cyan8);
+ --accent9: var(--cyan9);
+ --accent10: var(--cyan10);
+ --accent11: var(--cyan11);
+ --accent12: var(--cyan12);
+ --accentA1: var(--cyanA1);
+ --accentA2: var(--cyanA2);
+ --accentA3: var(--cyanA3);
+ --accentA4: var(--cyanA4);
+ --accentA5: var(--cyanA5);
+ --accentA6: var(--cyanA6);
+ --accentA7: var(--cyanA7);
+ --accentA8: var(--cyanA8);
+ --accentA9: var(--cyanA9);
+ --accentA10: var(--cyanA10);
+ --accentA11: var(--cyanA11);
+ --accentA12: var(--cyanA12);
+}
+
+[data-accent-color='gold'] {
+ --accent1: var(--gold1);
+ --accent2: var(--gold2);
+ --accent3: var(--gold3);
+ --accent4: var(--gold4);
+ --accent5: var(--gold5);
+ --accent6: var(--gold6);
+ --accent7: var(--gold7);
+ --accent8: var(--gold8);
+ --accent9: var(--gold9);
+ --accent10: var(--gold10);
+ --accent11: var(--gold11);
+ --accent12: var(--gold12);
+ --accentA1: var(--goldA1);
+ --accentA2: var(--goldA2);
+ --accentA3: var(--goldA3);
+ --accentA4: var(--goldA4);
+ --accentA5: var(--goldA5);
+ --accentA6: var(--goldA6);
+ --accentA7: var(--goldA7);
+ --accentA8: var(--goldA8);
+ --accentA9: var(--goldA9);
+ --accentA10: var(--goldA10);
+ --accentA11: var(--goldA11);
+ --accentA12: var(--goldA12);
+}
+
+[data-accent-color='grass'] {
+ --accent1: var(--grass1);
+ --accent2: var(--grass2);
+ --accent3: var(--grass3);
+ --accent4: var(--grass4);
+ --accent5: var(--grass5);
+ --accent6: var(--grass6);
+ --accent7: var(--grass7);
+ --accent8: var(--grass8);
+ --accent9: var(--grass9);
+ --accent10: var(--grass10);
+ --accent11: var(--grass11);
+ --accent12: var(--grass12);
+ --accentA1: var(--grassA1);
+ --accentA2: var(--grassA2);
+ --accentA3: var(--grassA3);
+ --accentA4: var(--grassA4);
+ --accentA5: var(--grassA5);
+ --accentA6: var(--grassA6);
+ --accentA7: var(--grassA7);
+ --accentA8: var(--grassA8);
+ --accentA9: var(--grassA9);
+ --accentA10: var(--grassA10);
+ --accentA11: var(--grassA11);
+ --accentA12: var(--grassA12);
+}
+
+[data-accent-color='gray'] {
+ --accent1: var(--gray1);
+ --accent2: var(--gray2);
+ --accent3: var(--gray3);
+ --accent4: var(--gray4);
+ --accent5: var(--gray5);
+ --accent6: var(--gray6);
+ --accent7: var(--gray7);
+ --accent8: var(--gray8);
+ --accent9: var(--gray9);
+ --accent10: var(--gray10);
+ --accent11: var(--gray11);
+ --accent12: var(--gray12);
+ --accentA1: var(--grayA1);
+ --accentA2: var(--grayA2);
+ --accentA3: var(--grayA3);
+ --accentA4: var(--grayA4);
+ --accentA5: var(--grayA5);
+ --accentA6: var(--grayA6);
+ --accentA7: var(--grayA7);
+ --accentA8: var(--grayA8);
+ --accentA9: var(--grayA9);
+ --accentA10: var(--grayA10);
+ --accentA11: var(--grayA11);
+ --accentA12: var(--grayA12);
+}
+
+[data-accent-color='green'] {
+ --accent1: var(--green1);
+ --accent2: var(--green2);
+ --accent3: var(--green3);
+ --accent4: var(--green4);
+ --accent5: var(--green5);
+ --accent6: var(--green6);
+ --accent7: var(--green7);
+ --accent8: var(--green8);
+ --accent9: var(--green9);
+ --accent10: var(--green10);
+ --accent11: var(--green11);
+ --accent12: var(--green12);
+ --accentA1: var(--greenA1);
+ --accentA2: var(--greenA2);
+ --accentA3: var(--greenA3);
+ --accentA4: var(--greenA4);
+ --accentA5: var(--greenA5);
+ --accentA6: var(--greenA6);
+ --accentA7: var(--greenA7);
+ --accentA8: var(--greenA8);
+ --accentA9: var(--greenA9);
+ --accentA10: var(--greenA10);
+ --accentA11: var(--greenA11);
+ --accentA12: var(--greenA12);
+}
+
+[data-accent-color='indigo'] {
+ --accent1: var(--indigo1);
+ --accent2: var(--indigo2);
+ --accent3: var(--indigo3);
+ --accent4: var(--indigo4);
+ --accent5: var(--indigo5);
+ --accent6: var(--indigo6);
+ --accent7: var(--indigo7);
+ --accent8: var(--indigo8);
+ --accent9: var(--indigo9);
+ --accent10: var(--indigo10);
+ --accent11: var(--indigo11);
+ --accent12: var(--indigo12);
+ --accentA1: var(--indigoA1);
+ --accentA2: var(--indigoA2);
+ --accentA3: var(--indigoA3);
+ --accentA4: var(--indigoA4);
+ --accentA5: var(--indigoA5);
+ --accentA6: var(--indigoA6);
+ --accentA7: var(--indigoA7);
+ --accentA8: var(--indigoA8);
+ --accentA9: var(--indigoA9);
+ --accentA10: var(--indigoA10);
+ --accentA11: var(--indigoA11);
+ --accentA12: var(--indigoA12);
+}
+
+[data-accent-color='iris'] {
+ --accent1: var(--iris1);
+ --accent2: var(--iris2);
+ --accent3: var(--iris3);
+ --accent4: var(--iris4);
+ --accent5: var(--iris5);
+ --accent6: var(--iris6);
+ --accent7: var(--iris7);
+ --accent8: var(--iris8);
+ --accent9: var(--iris9);
+ --accent10: var(--iris10);
+ --accent11: var(--iris11);
+ --accent12: var(--iris12);
+ --accentA1: var(--irisA1);
+ --accentA2: var(--irisA2);
+ --accentA3: var(--irisA3);
+ --accentA4: var(--irisA4);
+ --accentA5: var(--irisA5);
+ --accentA6: var(--irisA6);
+ --accentA7: var(--irisA7);
+ --accentA8: var(--irisA8);
+ --accentA9: var(--irisA9);
+ --accentA10: var(--irisA10);
+ --accentA11: var(--irisA11);
+ --accentA12: var(--irisA12);
+}
+
+[data-accent-color='jade'] {
+ --accent1: var(--jade1);
+ --accent2: var(--jade2);
+ --accent3: var(--jade3);
+ --accent4: var(--jade4);
+ --accent5: var(--jade5);
+ --accent6: var(--jade6);
+ --accent7: var(--jade7);
+ --accent8: var(--jade8);
+ --accent9: var(--jade9);
+ --accent10: var(--jade10);
+ --accent11: var(--jade11);
+ --accent12: var(--jade12);
+ --accentA1: var(--jadeA1);
+ --accentA2: var(--jadeA2);
+ --accentA3: var(--jadeA3);
+ --accentA4: var(--jadeA4);
+ --accentA5: var(--jadeA5);
+ --accentA6: var(--jadeA6);
+ --accentA7: var(--jadeA7);
+ --accentA8: var(--jadeA8);
+ --accentA9: var(--jadeA9);
+ --accentA10: var(--jadeA10);
+ --accentA11: var(--jadeA11);
+ --accentA12: var(--jadeA12);
+}
+
+[data-accent-color='lime'] {
+ --accent1: var(--lime1);
+ --accent2: var(--lime2);
+ --accent3: var(--lime3);
+ --accent4: var(--lime4);
+ --accent5: var(--lime5);
+ --accent6: var(--lime6);
+ --accent7: var(--lime7);
+ --accent8: var(--lime8);
+ --accent9: var(--lime9);
+ --accent10: var(--lime10);
+ --accent11: var(--lime11);
+ --accent12: var(--lime12);
+ --accentA1: var(--limeA1);
+ --accentA2: var(--limeA2);
+ --accentA3: var(--limeA3);
+ --accentA4: var(--limeA4);
+ --accentA5: var(--limeA5);
+ --accentA6: var(--limeA6);
+ --accentA7: var(--limeA7);
+ --accentA8: var(--limeA8);
+ --accentA9: var(--limeA9);
+ --accentA10: var(--limeA10);
+ --accentA11: var(--limeA11);
+ --accentA12: var(--limeA12);
+}
+
+[data-accent-color='mint'] {
+ --accent1: var(--mint1);
+ --accent2: var(--mint2);
+ --accent3: var(--mint3);
+ --accent4: var(--mint4);
+ --accent5: var(--mint5);
+ --accent6: var(--mint6);
+ --accent7: var(--mint7);
+ --accent8: var(--mint8);
+ --accent9: var(--mint9);
+ --accent10: var(--mint10);
+ --accent11: var(--mint11);
+ --accent12: var(--mint12);
+ --accentA1: var(--mintA1);
+ --accentA2: var(--mintA2);
+ --accentA3: var(--mintA3);
+ --accentA4: var(--mintA4);
+ --accentA5: var(--mintA5);
+ --accentA6: var(--mintA6);
+ --accentA7: var(--mintA7);
+ --accentA8: var(--mintA8);
+ --accentA9: var(--mintA9);
+ --accentA10: var(--mintA10);
+ --accentA11: var(--mintA11);
+ --accentA12: var(--mintA12);
+}
+
+[data-accent-color='orange'] {
+ --accent1: var(--orange1);
+ --accent2: var(--orange2);
+ --accent3: var(--orange3);
+ --accent4: var(--orange4);
+ --accent5: var(--orange5);
+ --accent6: var(--orange6);
+ --accent7: var(--orange7);
+ --accent8: var(--orange8);
+ --accent9: var(--orange9);
+ --accent10: var(--orange10);
+ --accent11: var(--orange11);
+ --accent12: var(--orange12);
+ --accentA1: var(--orangeA1);
+ --accentA2: var(--orangeA2);
+ --accentA3: var(--orangeA3);
+ --accentA4: var(--orangeA4);
+ --accentA5: var(--orangeA5);
+ --accentA6: var(--orangeA6);
+ --accentA7: var(--orangeA7);
+ --accentA8: var(--orangeA8);
+ --accentA9: var(--orangeA9);
+ --accentA10: var(--orangeA10);
+ --accentA11: var(--orangeA11);
+ --accentA12: var(--orangeA12);
+}
+
+[data-accent-color='pink'] {
+ --accent1: var(--pink1);
+ --accent2: var(--pink2);
+ --accent3: var(--pink3);
+ --accent4: var(--pink4);
+ --accent5: var(--pink5);
+ --accent6: var(--pink6);
+ --accent7: var(--pink7);
+ --accent8: var(--pink8);
+ --accent9: var(--pink9);
+ --accent10: var(--pink10);
+ --accent11: var(--pink11);
+ --accent12: var(--pink12);
+ --accentA1: var(--pinkA1);
+ --accentA2: var(--pinkA2);
+ --accentA3: var(--pinkA3);
+ --accentA4: var(--pinkA4);
+ --accentA5: var(--pinkA5);
+ --accentA6: var(--pinkA6);
+ --accentA7: var(--pinkA7);
+ --accentA8: var(--pinkA8);
+ --accentA9: var(--pinkA9);
+ --accentA10: var(--pinkA10);
+ --accentA11: var(--pinkA11);
+ --accentA12: var(--pinkA12);
+}
+
+[data-accent-color='plum'] {
+ --accent1: var(--plum1);
+ --accent2: var(--plum2);
+ --accent3: var(--plum3);
+ --accent4: var(--plum4);
+ --accent5: var(--plum5);
+ --accent6: var(--plum6);
+ --accent7: var(--plum7);
+ --accent8: var(--plum8);
+ --accent9: var(--plum9);
+ --accent10: var(--plum10);
+ --accent11: var(--plum11);
+ --accent12: var(--plum12);
+ --accentA1: var(--plumA1);
+ --accentA2: var(--plumA2);
+ --accentA3: var(--plumA3);
+ --accentA4: var(--plumA4);
+ --accentA5: var(--plumA5);
+ --accentA6: var(--plumA6);
+ --accentA7: var(--plumA7);
+ --accentA8: var(--plumA8);
+ --accentA9: var(--plumA9);
+ --accentA10: var(--plumA10);
+ --accentA11: var(--plumA11);
+ --accentA12: var(--plumA12);
+}
+
+[data-accent-color='purple'] {
+ --accent1: var(--purple1);
+ --accent2: var(--purple2);
+ --accent3: var(--purple3);
+ --accent4: var(--purple4);
+ --accent5: var(--purple5);
+ --accent6: var(--purple6);
+ --accent7: var(--purple7);
+ --accent8: var(--purple8);
+ --accent9: var(--purple9);
+ --accent10: var(--purple10);
+ --accent11: var(--purple11);
+ --accent12: var(--purple12);
+ --accentA1: var(--purpleA1);
+ --accentA2: var(--purpleA2);
+ --accentA3: var(--purpleA3);
+ --accentA4: var(--purpleA4);
+ --accentA5: var(--purpleA5);
+ --accentA6: var(--purpleA6);
+ --accentA7: var(--purpleA7);
+ --accentA8: var(--purpleA8);
+ --accentA9: var(--purpleA9);
+ --accentA10: var(--purpleA10);
+ --accentA11: var(--purpleA11);
+ --accentA12: var(--purpleA12);
+}
+
+[data-accent-color='red'] {
+ --accent1: var(--red1);
+ --accent2: var(--red2);
+ --accent3: var(--red3);
+ --accent4: var(--red4);
+ --accent5: var(--red5);
+ --accent6: var(--red6);
+ --accent7: var(--red7);
+ --accent8: var(--red8);
+ --accent9: var(--red9);
+ --accent10: var(--red10);
+ --accent11: var(--red11);
+ --accent12: var(--red12);
+ --accentA1: var(--redA1);
+ --accentA2: var(--redA2);
+ --accentA3: var(--redA3);
+ --accentA4: var(--redA4);
+ --accentA5: var(--redA5);
+ --accentA6: var(--redA6);
+ --accentA7: var(--redA7);
+ --accentA8: var(--redA8);
+ --accentA9: var(--redA9);
+ --accentA10: var(--redA10);
+ --accentA11: var(--redA11);
+ --accentA12: var(--redA12);
+}
+
+[data-accent-color='ruby'] {
+ --accent1: var(--ruby1);
+ --accent2: var(--ruby2);
+ --accent3: var(--ruby3);
+ --accent4: var(--ruby4);
+ --accent5: var(--ruby5);
+ --accent6: var(--ruby6);
+ --accent7: var(--ruby7);
+ --accent8: var(--ruby8);
+ --accent9: var(--ruby9);
+ --accent10: var(--ruby10);
+ --accent11: var(--ruby11);
+ --accent12: var(--ruby12);
+ --accentA1: var(--rubyA1);
+ --accentA2: var(--rubyA2);
+ --accentA3: var(--rubyA3);
+ --accentA4: var(--rubyA4);
+ --accentA5: var(--rubyA5);
+ --accentA6: var(--rubyA6);
+ --accentA7: var(--rubyA7);
+ --accentA8: var(--rubyA8);
+ --accentA9: var(--rubyA9);
+ --accentA10: var(--rubyA10);
+ --accentA11: var(--rubyA11);
+ --accentA12: var(--rubyA12);
+}
+
+[data-accent-color='sky'] {
+ --accent1: var(--sky1);
+ --accent2: var(--sky2);
+ --accent3: var(--sky3);
+ --accent4: var(--sky4);
+ --accent5: var(--sky5);
+ --accent6: var(--sky6);
+ --accent7: var(--sky7);
+ --accent8: var(--sky8);
+ --accent9: var(--sky9);
+ --accent10: var(--sky10);
+ --accent11: var(--sky11);
+ --accent12: var(--sky12);
+ --accentA1: var(--skyA1);
+ --accentA2: var(--skyA2);
+ --accentA3: var(--skyA3);
+ --accentA4: var(--skyA4);
+ --accentA5: var(--skyA5);
+ --accentA6: var(--skyA6);
+ --accentA7: var(--skyA7);
+ --accentA8: var(--skyA8);
+ --accentA9: var(--skyA9);
+ --accentA10: var(--skyA10);
+ --accentA11: var(--skyA11);
+ --accentA12: var(--skyA12);
+}
+
+[data-accent-color='teal'] {
+ --accent1: var(--teal1);
+ --accent2: var(--teal2);
+ --accent3: var(--teal3);
+ --accent4: var(--teal4);
+ --accent5: var(--teal5);
+ --accent6: var(--teal6);
+ --accent7: var(--teal7);
+ --accent8: var(--teal8);
+ --accent9: var(--teal9);
+ --accent10: var(--teal10);
+ --accent11: var(--teal11);
+ --accent12: var(--teal12);
+ --accentA1: var(--tealA1);
+ --accentA2: var(--tealA2);
+ --accentA3: var(--tealA3);
+ --accentA4: var(--tealA4);
+ --accentA5: var(--tealA5);
+ --accentA6: var(--tealA6);
+ --accentA7: var(--tealA7);
+ --accentA8: var(--tealA8);
+ --accentA9: var(--tealA9);
+ --accentA10: var(--tealA10);
+ --accentA11: var(--tealA11);
+ --accentA12: var(--tealA12);
+}
+
+[data-accent-color='tomato'] {
+ --accent1: var(--tomato1);
+ --accent2: var(--tomato2);
+ --accent3: var(--tomato3);
+ --accent4: var(--tomato4);
+ --accent5: var(--tomato5);
+ --accent6: var(--tomato6);
+ --accent7: var(--tomato7);
+ --accent8: var(--tomato8);
+ --accent9: var(--tomato9);
+ --accent10: var(--tomato10);
+ --accent11: var(--tomato11);
+ --accent12: var(--tomato12);
+ --accentA1: var(--tomatoA1);
+ --accentA2: var(--tomatoA2);
+ --accentA3: var(--tomatoA3);
+ --accentA4: var(--tomatoA4);
+ --accentA5: var(--tomatoA5);
+ --accentA6: var(--tomatoA6);
+ --accentA7: var(--tomatoA7);
+ --accentA8: var(--tomatoA8);
+ --accentA9: var(--tomatoA9);
+ --accentA10: var(--tomatoA10);
+ --accentA11: var(--tomatoA11);
+ --accentA12: var(--tomatoA12);
+}
+
+[data-accent-color='violet'] {
+ --accent1: var(--violet1);
+ --accent2: var(--violet2);
+ --accent3: var(--violet3);
+ --accent4: var(--violet4);
+ --accent5: var(--violet5);
+ --accent6: var(--violet6);
+ --accent7: var(--violet7);
+ --accent8: var(--violet8);
+ --accent9: var(--violet9);
+ --accent10: var(--violet10);
+ --accent11: var(--violet11);
+ --accent12: var(--violet12);
+ --accentA1: var(--violetA1);
+ --accentA2: var(--violetA2);
+ --accentA3: var(--violetA3);
+ --accentA4: var(--violetA4);
+ --accentA5: var(--violetA5);
+ --accentA6: var(--violetA6);
+ --accentA7: var(--violetA7);
+ --accentA8: var(--violetA8);
+ --accentA9: var(--violetA9);
+ --accentA10: var(--violetA10);
+ --accentA11: var(--violetA11);
+ --accentA12: var(--violetA12);
+}
+
+[data-accent-color='yellow'] {
+ --accent1: var(--yellow1);
+ --accent2: var(--yellow2);
+ --accent3: var(--yellow3);
+ --accent4: var(--yellow4);
+ --accent5: var(--yellow5);
+ --accent6: var(--yellow6);
+ --accent7: var(--yellow7);
+ --accent8: var(--yellow8);
+ --accent9: var(--yellow9);
+ --accent10: var(--yellow10);
+ --accent11: var(--yellow11);
+ --accent12: var(--yellow12);
+ --accentA1: var(--yellowA1);
+ --accentA2: var(--yellowA2);
+ --accentA3: var(--yellowA3);
+ --accentA4: var(--yellowA4);
+ --accentA5: var(--yellowA5);
+ --accentA6: var(--yellowA6);
+ --accentA7: var(--yellowA7);
+ --accentA8: var(--yellowA8);
+ --accentA9: var(--yellowA9);
+ --accentA10: var(--yellowA10);
+ --accentA11: var(--yellowA11);
+ --accentA12: var(--yellowA12);
+}
+
+[data-gray-color='mauve'],
+.radix-themes:where([data-gray-color='mauve']) {
+ --gray-1: var(--mauve1);
+ --gray-2: var(--mauve2);
+ --gray-3: var(--mauve3);
+ --gray-4: var(--mauve4);
+ --gray-5: var(--mauve5);
+ --gray-6: var(--mauve6);
+ --gray-7: var(--mauve7);
+ --gray-8: var(--mauve8);
+ --gray-9: var(--mauve9);
+ --gray-10: var(--mauve10);
+ --gray-11: var(--mauve11);
+ --gray-12: var(--mauve12);
+ --grayA1: var(--mauveA1);
+ --grayA2: var(--mauveA2);
+ --grayA3: var(--mauveA3);
+ --grayA4: var(--mauveA4);
+ --grayA5: var(--mauveA5);
+ --grayA6: var(--mauveA6);
+ --grayA7: var(--mauveA7);
+ --grayA8: var(--mauveA8);
+ --grayA9: var(--mauveA9);
+ --grayA10: var(--mauveA10);
+ --grayA11: var(--mauveA11);
+ --grayA12: var(--mauveA12);
+}
+
+[data-gray-color='olive'],
+.radix-themes:where([data-gray-color='olive']) {
+ --gray-1: var(--olive1);
+ --gray-2: var(--olive2);
+ --gray-3: var(--olive3);
+ --gray-4: var(--olive4);
+ --gray-5: var(--olive5);
+ --gray-6: var(--olive6);
+ --gray-7: var(--olive7);
+ --gray-8: var(--olive8);
+ --gray-9: var(--olive9);
+ --gray-10: var(--olive10);
+ --gray-11: var(--olive11);
+ --gray-12: var(--olive12);
+ --grayA1: var(--oliveA1);
+ --grayA2: var(--oliveA2);
+ --grayA3: var(--oliveA3);
+ --grayA4: var(--oliveA4);
+ --grayA5: var(--oliveA5);
+ --grayA6: var(--oliveA6);
+ --grayA7: var(--oliveA7);
+ --grayA8: var(--oliveA8);
+ --grayA9: var(--oliveA9);
+ --grayA10: var(--oliveA10);
+ --grayA11: var(--oliveA11);
+ --grayA12: var(--oliveA12);
+}
+
+[data-gray-color='sage'],
+.radix-themes:where([data-gray-color='sage']) {
+ --gray-1: var(--sage1);
+ --gray-2: var(--sage2);
+ --gray-3: var(--sage3);
+ --gray-4: var(--sage4);
+ --gray-5: var(--sage5);
+ --gray-6: var(--sage6);
+ --gray-7: var(--sage7);
+ --gray-8: var(--sage8);
+ --gray-9: var(--sage9);
+ --gray-10: var(--sage10);
+ --gray-11: var(--sage11);
+ --gray-12: var(--sage12);
+ --grayA1: var(--sageA1);
+ --grayA2: var(--sageA2);
+ --grayA3: var(--sageA3);
+ --grayA4: var(--sageA4);
+ --grayA5: var(--sageA5);
+ --grayA6: var(--sageA6);
+ --grayA7: var(--sageA7);
+ --grayA8: var(--sageA8);
+ --grayA9: var(--sageA9);
+ --grayA10: var(--sageA10);
+ --grayA11: var(--sageA11);
+ --grayA12: var(--sageA12);
+}
+
+[data-gray-color='sand'],
+.radix-themes:where([data-gray-color='sand']) {
+ --gray-1: var(--sand1);
+ --gray-2: var(--sand2);
+ --gray-3: var(--sand3);
+ --gray-4: var(--sand4);
+ --gray-5: var(--sand5);
+ --gray-6: var(--sand6);
+ --gray-7: var(--sand7);
+ --gray-8: var(--sand8);
+ --gray-9: var(--sand9);
+ --gray-10: var(--sand10);
+ --gray-11: var(--sand11);
+ --gray-12: var(--sand12);
+ --grayA1: var(--sandA1);
+ --grayA2: var(--sandA2);
+ --grayA3: var(--sandA3);
+ --grayA4: var(--sandA4);
+ --grayA5: var(--sandA5);
+ --grayA6: var(--sandA6);
+ --grayA7: var(--sandA7);
+ --grayA8: var(--sandA8);
+ --grayA9: var(--sandA9);
+ --grayA10: var(--sandA10);
+ --grayA11: var(--sandA11);
+ --grayA12: var(--sandA12);
+}
+
+[data-gray-color='slate'],
+.radix-themes:where([data-gray-color='slate']) {
+ --gray-1: var(--slate1);
+ --gray-2: var(--slate2);
+ --gray-3: var(--slate3);
+ --gray-4: var(--slate4);
+ --gray-5: var(--slate5);
+ --gray-6: var(--slate6);
+ --gray-7: var(--slate7);
+ --gray-8: var(--slate8);
+ --gray-9: var(--slate9);
+ --gray-10: var(--slate10);
+ --gray-11: var(--slate11);
+ --gray-12: var(--slate12);
+ --grayA1: var(--slateA1);
+ --grayA2: var(--slateA2);
+ --grayA3: var(--slateA3);
+ --grayA4: var(--slateA4);
+ --grayA5: var(--slateA5);
+ --grayA6: var(--slateA6);
+ --grayA7: var(--slateA7);
+ --grayA8: var(--slateA8);
+ --grayA9: var(--slateA9);
+ --grayA10: var(--slateA10);
+ --grayA11: var(--slateA11);
+ --grayA12: var(--slateA12);
+}
+
+:root {
+ --font-labil-grotesk: 'Labil Grotesk Variable';
+}
+
+.header-bg {
+ background: var(
+ --gradient--alphaLinear-2,
+ linear-gradient(180deg, var(--gray4) -46.44%, var(--gray3) 207.35%)
+ );
+}
+
+.footer-bg {
+ background: var(
+ --gradient--alphaLinear-2,
+ linear-gradient(180deg, var(--gray3) -46.44%, var(--gray2) 207.35%)
+ );
+}
+
+.card-mask {
+ mask-image: radial-gradient(
+ 164.24% 99.54% at 50% 109.77%,
+ rgba(255, 255, 255, 0) 10.93%,
+ rgba(255, 255, 255, 0.49) 67.34%,
+ #fff 100%
+ );
+ -webkit-mask-image: radial-gradient(
+ 164.24% 99.54% at 50% 109.77%,
+ rgba(255, 255, 255, 0) 10.93%,
+ rgba(255, 255, 255, 0.49) 67.34%,
+ #fff 100%
+ );
+}
+
+.scrollbarGutter-stable {
+ scrollbar-gutter: stable;
+}
+
+.scrollbarGutter-stableEdges {
+ scrollbar-gutter: stable both-edges;
+}
+
+::-webkit-resizer {
+ background-color: transparent !important;
+ border: 0px solid transparent !important;
+}
+
+::-webkit-scrollbar {
+ background-color: transparent !important;
+ border: 0px solid transparent !important;
+ width: 5px !important;
+ height: 5px !important;
+ border-radius: 9999px !important;
+}
+
+::-webkit-scrollbar-button {
+ background-color: transparent !important;
+ border: 0px solid transparent !important;
+ border-radius: 9999px !important;
+}
+
+::-webkit-scrollbar-corner {
+ background-color: transparent !important;
+ border: 0px solid transparent !important;
+ border-radius: 9999px !important;
+}
+
+::-webkit-scrollbar-thumb {
+ background-color: var(--gray8) !important;
+ border: 0px solid var(--grayA2) !important;
+ border-radius: 9999px !important;
+}
+
+::-webkit-scrollbar-track {
+ background-color: var(--gray5) !important;
+ border: 0px solid var(--gray5) !important;
+ border-right-width: 0 !important;
+ border-radius: 9999px !important;
+}
+
+::-webkit-scrollbar-track-piece {
+ background-color: transparent !important;
+ border: 0px solid transparent !important;
+ border-radius: 9999px !important;
+}
+
+.prodkt-mobile-navigation-button {
+ display: flex;
+ width: var(--Spacing-9, 64px);
+ height: var(--Spacing-9, 64px);
+ min-height: var(--Spacing-9, 64px);
+ padding: 14px;
+ justify-content: center;
+ align-items: center;
+ overflow: visible;
+ gap: 8px;
+ border-radius: 2.5rem !important;
+ border-width: 1px;
+ border-color: var(--grayA6);
+ --tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+ --tw-ring-color: var(--grayA5);
+ --tw-ring-offset-width: 1px;
+ background: radial-gradient(
+ 101.08% 100% at 50% 100%,
+ rgba(94, 94, 94, 0.32) 0%,
+ rgba(94, 94, 94, 0.01) 73.85%
+ ),
+ radial-gradient(
+ 100.02% 100% at 50% 100%,
+ rgba(255, 255, 255, 0.12) 0%,
+ rgba(255, 255, 255, 0.01) 68.75%
+ ),
+ radial-gradient(
+ 100.02% 100% at 50% 100%,
+ rgba(255, 255, 255, 0.07) 0%,
+ rgba(255, 255, 255, 0) 55.59%
+ ),
+ radial-gradient(
+ 100.02% 100% at 50% 100%,
+ rgba(255, 255, 255, 0.07) 0%,
+ rgba(255, 255, 255, 0.08) 55.59%
+ );
+ background-blend-mode: color-dodge, normal, normal, normal;
+ -webkit-backdrop-filter: blur(20px);
+ backdrop-filter: blur(20px);
+ box-shadow: 0px 4px 8px -3px var(--ghost-aa4);
+ &:after,
+ & :after {
+ border-radius: 2.4rem !important;
+ }
+ &:after,
+ & :after {
+ --tw-ring-color: transparent !important;
+ }
+ &:hover:after,
+ & :hover:after {
+ border-color: transparent !important;
+ }
+ &:after,
+ & :after {
+ overflow: hidden;
+ }
+ &:before,
+ & :before {
+ border-radius: 2.4rem !important;
+ }
+ &:before,
+ & :before {
+ --tw-ring-color: transparent !important;
+ }
+ &:hover:before,
+ & :hover:before {
+ border-color: transparent !important;
+ }
+ &:before,
+ & :before {
+ overflow: hidden;
+ }
+ &.themeColor {
+ border-radius: 2.5rem 2.5rem 5rem 5rem !important;
+ height: auto !important;
+ width: auto !important;
+ max-width: 154px !important;
+ }
+ &.themeing {
+ width: var(--Spacing-9, 56px) !important;
+ height: var(--Spacing-9, 56px) !important;
+ min-height: var(--Spacing-9, 56px) !important;
+ background: radial-gradient(
+ 101.08% 100% at 50% 100%,
+ var(--gray3) 0%,
+ var(--gray5) 73.85%
+ ),
+ radial-gradient(
+ 100.02% 100% at 50% 100%,
+ var(--gray3) 0%,
+ var(--gray6) 68.75%
+ ),
+ radial-gradient(
+ 100.02% 100% at 50% 100%,
+ var(--gray3) 0%,
+ var(--gray1) 55.59%
+ ),
+ radial-gradient(
+ 100.02% 100% at 50% 100%,
+ var(--gray3) 0%,
+ var(--gray2) 55.59%
+ );
+ -webkit-backdrop-filter: blur(20px);
+ backdrop-filter: blur(20px);
+ box-shadow: 0px 4px 8px -3px var(--ghost-a4);
+ }
+}
+
+.prodkt-blog-content {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ & p {
+ margin-bottom: 1.5rem;
+ }
+ & p {
+ text-wrap: balance;
+ }
+ & p {
+ line-height: 2;
+ }
+ & p {
+ color: var(--gray11);
+ }
+ & h2 {
+ font-size: 3rem;
+ line-height: 1;
+ }
+ & h2 {
+ font-weight: 300;
+ }
+ & h2 {
+ letter-spacing: -0.05em;
+ }
+ & h3 {
+ font-size: 1.875rem;
+ line-height: 2.25rem;
+ }
+ & h3 {
+ font-weight: 300;
+ }
+ & h3 {
+ letter-spacing: -0.05em;
+ }
+ & hr {
+ margin-top: 1.5rem;
+ margin-bottom: 1.5rem;
+ }
+}
+
+.prodkt-changelog-accordion {
+ & h3 {
+ margin-bottom: 0px !important;
+ }
+ & h3 {
+ & p {
+ margin-bottom: 0px;
+ }
+ & p {
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ }
+ & p {
+ letter-spacing: 0em;
+ }
+ }
+}
+
+.about-prodkt-heading {
+ background: linear-gradient(
+ 180deg,
+ var(--grayA12) -0.14%,
+ var(--gray12) 57.35%
+ );
+ background-clip: text;
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ text-shadow:
+ /* 0px 10.127px 104.764px var(--grayA1),
+ 0px 146.982px 87.564px var(--blueA1),
+ 0px 65.673px 65.673px var(--gray1),
+ 0px 15.636px 95.964px var(--gray1), */ 0px
+ 4px 140.2px var(--iris1);
+}
+
+.file\:border-0::file-selector-button {
+ border-width: 0px;
+}
+
+.file\:bg-transparent::file-selector-button {
+ background-color: transparent;
+}
+
+.file\:text-sm::file-selector-button {
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+}
+
+.file\:font-medium::file-selector-button {
+ font-weight: 500;
+}
+
+.file\:text-foreground::file-selector-button {
+ color: var(--gray12);
+}
+
+.placeholder\:text-muted-foreground::-moz-placeholder {
+ color: var(--gray11);
+}
+
+.placeholder\:text-muted-foreground::placeholder {
+ color: var(--gray11);
+}
+
+.after\:pointer-events-none::after {
+ content: var(--tw-content);
+ pointer-events: none;
+}
+
+.after\:absolute::after {
+ content: var(--tw-content);
+ position: absolute;
+}
+
+.after\:inset-0::after {
+ content: var(--tw-content);
+ inset: 0px;
+}
+
+.after\:inset-x-0::after {
+ content: var(--tw-content);
+ left: 0px;
+ right: 0px;
+}
+
+.after\:inset-y-0::after {
+ content: var(--tw-content);
+ top: 0px;
+ bottom: 0px;
+}
+
+.after\:bottom-0::after {
+ content: var(--tw-content);
+ bottom: 0px;
+}
+
+.after\:left-0::after {
+ content: var(--tw-content);
+ left: 0px;
+}
+
+.after\:left-1\/2::after {
+ content: var(--tw-content);
+ left: 50%;
+}
+
+.after\:right-0::after {
+ content: var(--tw-content);
+ right: 0px;
+}
+
+.after\:right-auto::after {
+ content: var(--tw-content);
+ right: auto;
+}
+
+.after\:top-0::after {
+ content: var(--tw-content);
+ top: 0px;
+}
+
+.after\:z-0::after {
+ content: var(--tw-content);
+ z-index: 0;
+}
+
+.after\:z-20::after {
+ content: var(--tw-content);
+ z-index: 20;
+}
+
+.after\:z-\[-2\]::after {
+ content: var(--tw-content);
+ z-index: -2;
+}
+
+.after\:z-\[2\]::after {
+ content: var(--tw-content);
+ z-index: 2;
+}
+
+.after\:mx-auto::after {
+ content: var(--tw-content);
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.after\:ml-0::after {
+ content: var(--tw-content);
+ margin-left: 0px;
+}
+
+.after\:size-full::after {
+ content: var(--tw-content);
+ width: 100%;
+ height: 100%;
+}
+
+.after\:size-px::after {
+ content: var(--tw-content);
+ width: 1px;
+ height: 1px;
+}
+
+.after\:h-1\/2::after {
+ content: var(--tw-content);
+ height: 50%;
+}
+
+.after\:h-full::after {
+ content: var(--tw-content);
+ height: 100%;
+}
+
+.after\:w-1::after {
+ content: var(--tw-content);
+ width: 0.25rem;
+}
+
+.after\:w-1\/2::after {
+ content: var(--tw-content);
+ width: 50%;
+}
+
+.after\:w-1\/4::after {
+ content: var(--tw-content);
+ width: 25%;
+}
+
+.after\:w-full::after {
+ content: var(--tw-content);
+ width: 100%;
+}
+
+.after\:origin-bottom::after {
+ content: var(--tw-content);
+ transform-origin: bottom;
+}
+
+.after\:-translate-x-1\/2::after {
+ content: var(--tw-content);
+ --tw-translate-x: -50%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+@keyframes spin {
+ to {
+ content: var(--tw-content);
+ transform: rotate(360deg);
+ }
+}
+
+.after\:animate-spinSlow1x::after {
+ content: var(--tw-content);
+ animation: spin 20.25s linear infinite;
+}
+
+@keyframes spin {
+ to {
+ content: var(--tw-content);
+ transform: rotate(360deg);
+ }
+}
+
+.after\:animate-spinSlow2x::after {
+ content: var(--tw-content);
+ animation: spin 22.25s linear infinite;
+}
+
+@keyframes spin {
+ to {
+ content: var(--tw-content);
+ transform: rotate(360deg);
+ }
+}
+
+.after\:animate-spinSlow3x::after {
+ content: var(--tw-content);
+ animation: spin 24.25s linear infinite;
+}
+
+@keyframes spin {
+ to {
+ content: var(--tw-content);
+ transform: rotate(360deg);
+ }
+}
+
+.after\:animate-spinSlow4x::after {
+ content: var(--tw-content);
+ animation: spin 26.25s linear infinite;
+}
+
+.after\:select-none::after {
+ content: var(--tw-content);
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+
+.after\:rounded-full::after {
+ content: var(--tw-content);
+ border-radius: 9999px;
+}
+
+.after\:rounded-t-3xl::after {
+ content: var(--tw-content);
+ border-top-left-radius: 1.5rem;
+ border-top-right-radius: 1.5rem;
+}
+
+.after\:bg-\[var\(--grayA12\)\]::after {
+ content: var(--tw-content);
+ background-color: var(--grayA12);
+}
+
+.after\:bg-\[var\(--grayA7\)\]::after {
+ content: var(--tw-content);
+ background-color: var(--grayA7);
+}
+
+.after\:bg-\[var\(--tomatoA8\)\]::after {
+ content: var(--tw-content);
+ background-color: var(--tomatoA8);
+}
+
+.after\:bg-gradient-to-b::after {
+ content: var(--tw-content);
+ background-image: linear-gradient(to bottom, var(--tw-gradient-stops));
+}
+
+.after\:bg-gradient-to-tr::after {
+ content: var(--tw-content);
+ background-image: linear-gradient(to top right, var(--tw-gradient-stops));
+}
+
+.after\:bg-radial-gradient-1::after {
+ content: var(--tw-content);
+ background-image: radial-gradient(
+ 87.07% 87.07% at 52.38% 100%,
+ var(--grayA1) 0%,
+ var(--grayA6) 100%
+ );
+}
+
+.after\:from-transparent::after {
+ content: var(--tw-content);
+ --tw-gradient-from: transparent var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.after\:to-\[var\(--grayA1\)\]::after {
+ content: var(--tw-content);
+ --tw-gradient-to: var(--grayA1) var(--tw-gradient-to-position);
+}
+
+.after\:to-transparent::after {
+ content: var(--tw-content);
+ --tw-gradient-to: transparent var(--tw-gradient-to-position);
+}
+
+.after\:opacity-0::after {
+ content: var(--tw-content);
+ opacity: 0;
+}
+
+.after\:opacity-100::after {
+ content: var(--tw-content);
+ opacity: 1;
+}
+
+.after\:mix-blend-hard-light::after {
+ content: var(--tw-content);
+ mix-blend-mode: hard-light;
+}
+
+.after\:mix-blend-soft-light::after {
+ content: var(--tw-content);
+ mix-blend-mode: soft-light;
+}
+
+.after\:blur-2xl::after {
+ content: var(--tw-content);
+ --tw-blur: blur(40px);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.after\:brightness-100::after {
+ content: var(--tw-content);
+ --tw-brightness: brightness(1);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.after\:transition-all::after {
+ content: var(--tw-content);
+ transition-property: all;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.after\:duration-200::after {
+ transition-duration: 200ms;
+ content: var(--tw-content);
+ animation-duration: 200ms;
+}
+
+.first\:mt-0:first-child {
+ margin-top: 0px;
+}
+
+.first\:rounded-l-md:first-child {
+ border-top-left-radius: 0.375rem;
+ border-bottom-left-radius: 0.375rem;
+}
+
+.first\:border-l:first-child {
+ border-left-width: 1px;
+}
+
+.last\:rounded-r-md:last-child {
+ border-top-right-radius: 0.375rem;
+ border-bottom-right-radius: 0.375rem;
+}
+
+.focus-within\:relative:focus-within {
+ position: relative;
+}
+
+.focus-within\:z-20:focus-within {
+ z-index: 20;
+}
+
+.hover\:min-w-48:hover {
+ min-width: 12rem;
+}
+
+.hover\:-translate-y-\[calc\(100\%_\+_40px\)\]:hover {
+ --tw-translate-y: calc(calc(100% + 40px) * -1);
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.hover\:rotate-45:hover {
+ --tw-rotate: 45deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.hover\:scale-100:hover {
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.hover\:scale-125:hover {
+ --tw-scale-x: 1.25;
+ --tw-scale-y: 1.25;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.hover\:border-\[var\(--grayA1\)\]:hover {
+ border-color: var(--grayA1);
+}
+
+.hover\:border-\[var\(--grayA5\)\]:hover {
+ border-color: var(--grayA5);
+}
+
+.hover\:bg-\[var\(--ghost-aa12\)\]:hover {
+ background-color: var(--ghost-aa12);
+}
+
+.hover\:bg-\[var\(--gray12\)\]:hover {
+ background-color: var(--gray12);
+}
+
+.hover\:bg-\[var\(--gray3\)\]:hover {
+ background-color: var(--gray3);
+}
+
+.hover\:bg-\[var\(--grayA1\)\]:hover {
+ background-color: var(--grayA1);
+}
+
+.hover\:bg-\[var\(--grayA12\)\]:hover {
+ background-color: var(--grayA12);
+}
+
+.hover\:bg-\[var\(--grayA2\)\]:hover {
+ background-color: var(--grayA2);
+}
+
+.hover\:bg-\[var\(--grayA3\)\]:hover {
+ background-color: var(--grayA3);
+}
+
+.hover\:bg-\[var\(--grayA6\)\]:hover {
+ background-color: var(--grayA6);
+}
+
+.hover\:bg-accent:hover {
+ background-color: var(--accent11);
+}
+
+.hover\:bg-accent-10:hover {
+ background-color: var(--accent10);
+}
+
+.hover\:bg-accent-9:hover {
+ background-color: var(--accent9);
+}
+
+.hover\:bg-destructive-9:hover {
+ background-color: var(--red9);
+}
+
+.hover\:bg-ghost:hover {
+ background-color: var(--ghost-a2);
+}
+
+.hover\:bg-gray-12:hover {
+ background-color: var(--gray12);
+}
+
+.hover\:bg-gray-3:hover {
+ background-color: var(--gray3);
+}
+
+.hover\:bg-gray-5:hover {
+ background-color: var(--gray5);
+}
+
+.hover\:bg-muted:hover {
+ background-color: var(--gray4);
+}
+
+.hover\:bg-primary:hover {
+ background-color: var(--violet9);
+}
+
+.hover\:bg-secondary-9:hover {
+ background-color: var(--blue9);
+}
+
+.hover\:bg-transparent:hover {
+ background-color: transparent;
+}
+
+.hover\:bg-opacity-0:hover {
+ --tw-bg-opacity: 0;
+}
+
+.hover\:p-1:hover {
+ padding: 0.25rem;
+}
+
+.hover\:text-\[var\(--gray1\)\]:hover {
+ color: var(--gray1);
+}
+
+.hover\:text-\[var\(--gray12\)\]:hover {
+ color: var(--gray12);
+}
+
+.hover\:text-\[var\(--gray9\)\]:hover {
+ color: var(--gray9);
+}
+
+.hover\:text-\[var\(--grayA12\)\]:hover {
+ color: var(--grayA12);
+}
+
+.hover\:text-accent-foreground:hover {
+ color: var(--accent2);
+}
+
+.hover\:text-accent-hover:hover {
+ color: var(--accent12);
+}
+
+.hover\:text-foreground:hover {
+ color: var(--gray12);
+}
+
+.hover\:text-gray-1:hover {
+ color: var(--gray1);
+}
+
+.hover\:text-gray-11:hover {
+ color: var(--gray11);
+}
+
+.hover\:text-gray-300:hover {
+ --tw-text-opacity: 1;
+ color: rgb(209 213 219 / var(--tw-text-opacity));
+}
+
+.hover\:text-muted-foreground:hover {
+ color: var(--gray11);
+}
+
+.hover\:text-primary-foreground:hover {
+ color: var(--violet1);
+}
+
+.hover\:underline:hover {
+ -webkit-text-decoration-line: underline;
+ text-decoration-line: underline;
+}
+
+.hover\:underline-offset-4:hover {
+ text-underline-offset: 4px;
+}
+
+.hover\:opacity-100:hover {
+ opacity: 1;
+}
+
+.hover\:duration-1000:hover {
+ transition-duration: 1000ms;
+}
+
+.hover\:ease-in-out:hover {
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.hover\:duration-1000:hover {
+ animation-duration: 1000ms;
+}
+
+.hover\:ease-in-out:hover {
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.hover\:after\:size-full:hover::after {
+ content: var(--tw-content);
+ width: 100%;
+ height: 100%;
+}
+
+.hover\:after\:rounded-t-3xl:hover::after {
+ content: var(--tw-content);
+ border-top-left-radius: 1.5rem;
+ border-top-right-radius: 1.5rem;
+}
+
+.hover\:after\:opacity-100:hover::after {
+ content: var(--tw-content);
+ opacity: 1;
+}
+
+.hover\:after\:blur:hover::after {
+ content: var(--tw-content);
+ --tw-blur: blur(8px);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.focus\:border-transparent:focus {
+ border-color: transparent;
+}
+
+.focus\:bg-accent:focus {
+ background-color: var(--accent11);
+}
+
+.focus\:bg-ghost:focus {
+ background-color: var(--ghost-a2);
+}
+
+.focus\:bg-primary:focus {
+ background-color: var(--violet9);
+}
+
+.focus\:text-accent-foreground:focus {
+ color: var(--accent2);
+}
+
+.focus\:text-accent-hover:focus {
+ color: var(--accent12);
+}
+
+.focus\:text-primary-foreground:focus {
+ color: var(--violet1);
+}
+
+.focus\:opacity-100:focus {
+ opacity: 1;
+}
+
+.focus\:shadow-none:focus {
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.focus\:outline-none:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.focus\:ring-0:focus {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+}
+
+.focus\:ring-1:focus {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+}
+
+.focus\:ring-2:focus {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+}
+
+.focus\:ring-ring:focus {
+ --tw-ring-color: var(--gray4);
+}
+
+.focus\:ring-offset-2:focus {
+ --tw-ring-offset-width: 2px;
+}
+
+.focus-visible\:outline-none:focus-visible {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.focus-visible\:ring-1:focus-visible {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+}
+
+.focus-visible\:ring-2:focus-visible {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
+ var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0
+ calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
+ var(--tw-shadow, 0 0 #0000);
+}
+
+.focus-visible\:ring-ring:focus-visible {
+ --tw-ring-color: var(--gray4);
+}
+
+.focus-visible\:ring-offset-1:focus-visible {
+ --tw-ring-offset-width: 1px;
+}
+
+.focus-visible\:ring-offset-2:focus-visible {
+ --tw-ring-offset-width: 2px;
+}
+
+.focus-visible\:ring-offset-background:focus-visible {
+ --tw-ring-offset-color: var(--gray1);
+}
+
+.active\:border-\[var\(--grayA9\)\]:active {
+ border-color: var(--grayA9);
+}
+
+.disabled\:pointer-events-none:disabled {
+ pointer-events: none;
+}
+
+.disabled\:cursor-not-allowed:disabled {
+ cursor: not-allowed;
+}
+
+.disabled\:opacity-50:disabled {
+ opacity: 0.5;
+}
+
+.group:hover .group-hover\:scale-100 {
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.group:hover .group-hover\:scale-105 {
+ --tw-scale-x: 1.05;
+ --tw-scale-y: 1.05;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.group:hover .group-hover\:scale-125 {
+ --tw-scale-x: 1.25;
+ --tw-scale-y: 1.25;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.group:hover .group-hover\:bg-\[var\(--ghost-a3\)\] {
+ background-color: var(--ghost-a3);
+}
+
+.group:hover .group-hover\:bg-\[var\(--grayA1\)\] {
+ background-color: var(--grayA1);
+}
+
+.group:hover .group-hover\:from-\[var\(--grayA11\)\] {
+ --tw-gradient-from: var(--grayA11) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.group:hover .group-hover\:to-\[var\(--grayA6\)\] {
+ --tw-gradient-to: var(--grayA6) var(--tw-gradient-to-position);
+}
+
+.group:hover .group-hover\:fill-primary {
+ fill: var(--violet9);
+}
+
+.group:hover .group-hover\:stroke-\[var\(--accent9\)\] {
+ stroke: var(--accent9);
+}
+
+.group:hover .group-hover\:stroke-\[var\(--grayA8\)\] {
+ stroke: var(--grayA8);
+}
+
+.group:hover .group-hover\:text-\[var\(--gray2\)\] {
+ color: var(--gray2);
+}
+
+.group:hover .group-hover\:text-\[var\(--grayA12\)\] {
+ color: var(--grayA12);
+}
+
+.group:hover .group-hover\:underline {
+ -webkit-text-decoration-line: underline;
+ text-decoration-line: underline;
+}
+
+.group:hover .group-hover\:decoration-\[var\(--gray9\)\] {
+ -webkit-text-decoration-color: var(--gray9);
+ text-decoration-color: var(--gray9);
+}
+
+.group:hover .group-hover\:decoration-\[var\(--grayA10\)\] {
+ -webkit-text-decoration-color: var(--grayA10);
+ text-decoration-color: var(--grayA10);
+}
+
+.group:hover .group-hover\:opacity-100 {
+ opacity: 1;
+}
+
+.group:hover
+ .group-hover\:shadow-\[inset_0px_0px_1px_1px_rgba\(255\2c
+ 255\2c
+ 255\2c
+ \.125\)\] {
+ --tw-shadow: inset 0px 0px 1px 1px rgba(255, 255, 255, 0.125);
+ --tw-shadow-colored: inset 0px 0px 1px 1px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
+ var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.group:hover .group-hover\:saturate-150 {
+ --tw-saturate: saturate(1.5);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.group.destructive .group-\[\.destructive\]\:bg-gray-2 {
+ background-color: var(--gray2);
+}
+
+.group.destructive .group-\[\.destructive\]\:font-medium {
+ font-weight: 500;
+}
+
+.group.destructive .group-\[\.destructive\]\:text-destructive-6 {
+ color: var(--red6);
+}
+
+.group.destructive .group-\[\.destructive\]\:text-foreground {
+ color: var(--gray12);
+}
+
+.group.destructive .group-\[\.destructive\]\:opacity-100 {
+ opacity: 1;
+}
+
+.group.destructive .group-\[\.destructive\]\:hover\:bg-gray-4:hover {
+ background-color: var(--gray4);
+}
+
+.group.destructive .group-\[\.destructive\]\:hover\:text-destructive-12:hover {
+ color: var(--red12);
+}
+
+.group.destructive .group-\[\.destructive\]\:focus\:ring-destructive-12:focus {
+ --tw-ring-color: var(--red12);
+}
+
+.group.destructive .group-\[\.destructive\]\:focus\:ring-gray-12:focus {
+ --tw-ring-color: var(--gray12);
+}
+
+.group.destructive
+ .group-\[\.destructive\]\:focus\:ring-offset-destructive-10:focus {
+ --tw-ring-offset-color: var(--red10);
+}
+
+.peer:disabled ~ .peer-disabled\:cursor-not-allowed {
+ cursor: not-allowed;
+}
+
+.peer:disabled ~ .peer-disabled\:opacity-70 {
+ opacity: 0.7;
+}
+
+.aria-selected\:bg-accent[aria-selected='true'] {
+ background-color: var(--accent11);
+}
+
+.aria-selected\:bg-ghost[aria-selected='true'] {
+ background-color: var(--ghost-a2);
+}
+
+.aria-selected\:bg-transparent[aria-selected='true'] {
+ background-color: transparent;
+}
+
+.aria-selected\:text-accent-foreground[aria-selected='true'] {
+ color: var(--accent2);
+}
+
+.aria-selected\:text-gray-selected[aria-selected='true'] {
+ color: var(--gray12);
+}
+
+.aria-selected\:text-muted-foreground[aria-selected='true'] {
+ color: var(--gray11);
+}
+
+.aria-selected\:opacity-100[aria-selected='true'] {
+ opacity: 1;
+}
+
+.aria-selected\:opacity-30[aria-selected='true'] {
+ opacity: 0.3;
+}
+
+.data-\[disabled\=\"true\"\]\:pointer-events-none[data-disabled='true'] {
+ pointer-events: none;
+}
+
+.data-\[disabled\]\:pointer-events-none[data-disabled] {
+ pointer-events: none;
+}
+
+.data-\[panel-group-direction\=vertical\]\:h-px[data-panel-group-direction='vertical'] {
+ height: 1px;
+}
+
+.data-\[panel-group-direction\=vertical\]\:w-full[data-panel-group-direction='vertical'] {
+ width: 100%;
+}
+
+.data-\[side\=bottom\]\:translate-y-1[data-side='bottom'] {
+ --tw-translate-y: 0.25rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.data-\[side\=left\]\:-translate-x-1[data-side='left'] {
+ --tw-translate-x: -0.25rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.data-\[side\=right\]\:translate-x-1[data-side='right'] {
+ --tw-translate-x: 0.25rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.data-\[side\=top\]\:-translate-y-1[data-side='top'] {
+ --tw-translate-y: -0.25rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.data-\[state\=checked\]\:translate-x-5[data-state='checked'] {
+ --tw-translate-x: 1.25rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.data-\[state\=unchecked\]\:translate-x-0[data-state='unchecked'] {
+ --tw-translate-x: 0px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.data-\[swipe\=cancel\]\:translate-x-0[data-swipe='cancel'] {
+ --tw-translate-x: 0px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.data-\[swipe\=end\]\:translate-x-\[var\(--radix-toast-swipe-end-x\)\][data-swipe='end'] {
+ --tw-translate-x: var(--radix-toast-swipe-end-x);
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.data-\[swipe\=move\]\:translate-x-\[var\(--radix-toast-swipe-move-x\)\][data-swipe='move'] {
+ --tw-translate-x: var(--radix-toast-swipe-move-x);
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+@keyframes accordion-up {
+ from {
+ height: var(--radix-accordion-content-height);
+ }
+
+ to {
+ height: 0;
+ }
+}
+
+.data-\[state\=closed\]\:animate-accordion-up[data-state='closed'] {
+ animation: accordion-up 0.2s ease-out;
+}
+
+@keyframes accordion-down {
+ from {
+ height: 0;
+ }
+
+ to {
+ height: var(--radix-accordion-content-height);
+ }
+}
+
+.data-\[state\=open\]\:animate-accordion-down[data-state='open'] {
+ animation: accordion-down 0.2s ease-out;
+}
+
+.data-\[panel-group-direction\=vertical\]\:flex-col[data-panel-group-direction='vertical'] {
+ flex-direction: column;
+}
+
+.data-\[state\=checked\]\:bg-primary[data-state='checked'] {
+ background-color: var(--violet9);
+}
+
+.data-\[state\=on\]\:bg-accent[data-state='on'] {
+ background-color: var(--accent11);
+}
+
+.data-\[state\=open\]\:bg-accent[data-state='open'] {
+ background-color: var(--accent11);
+}
+
+.data-\[state\=open\]\:bg-secondary[data-state='open'] {
+ background-color: var(--blue10);
+}
+
+.data-\[state\=selected\]\:bg-muted[data-state='selected'] {
+ background-color: var(--gray4);
+}
+
+.data-\[state\=unchecked\]\:bg-input[data-state='unchecked'] {
+ background-color: var(--gray4);
+}
+
+.data-\[state\=checked\]\:text-primary-foreground[data-state='checked'] {
+ color: var(--violet1);
+}
+
+.data-\[state\=on\]\:text-accent-foreground[data-state='on'] {
+ color: var(--accent2);
+}
+
+.data-\[state\=open\]\:text-accent-foreground[data-state='open'] {
+ color: var(--accent2);
+}
+
+.data-\[state\=open\]\:text-muted-foreground[data-state='open'] {
+ color: var(--gray11);
+}
+
+.data-\[disabled\=\"true\"\]\:opacity-50[data-disabled='true'] {
+ opacity: 0.5;
+}
+
+.data-\[disabled\]\:opacity-50[data-disabled] {
+ opacity: 0.5;
+}
+
+.data-\[swipe\=move\]\:transition-none[data-swipe='move'] {
+ transition-property: none;
+}
+
+.data-\[state\=closed\]\:duration-300[data-state='closed'] {
+ transition-duration: 300ms;
+}
+
+.data-\[state\=open\]\:duration-500[data-state='open'] {
+ transition-duration: 500ms;
+}
+
+.data-\[motion\^\=from-\]\:animate-in[data-motion^='from-'] {
+ animation-name: enter;
+ animation-duration: 150ms;
+ --tw-enter-opacity: initial;
+ --tw-enter-scale: initial;
+ --tw-enter-rotate: initial;
+ --tw-enter-translate-x: initial;
+ --tw-enter-translate-y: initial;
+}
+
+.data-\[state\=open\]\:animate-in[data-state='open'] {
+ animation-name: enter;
+ animation-duration: 150ms;
+ --tw-enter-opacity: initial;
+ --tw-enter-scale: initial;
+ --tw-enter-rotate: initial;
+ --tw-enter-translate-x: initial;
+ --tw-enter-translate-y: initial;
+}
+
+.data-\[state\=visible\]\:animate-in[data-state='visible'] {
+ animation-name: enter;
+ animation-duration: 150ms;
+ --tw-enter-opacity: initial;
+ --tw-enter-scale: initial;
+ --tw-enter-rotate: initial;
+ --tw-enter-translate-x: initial;
+ --tw-enter-translate-y: initial;
+}
+
+.data-\[motion\^\=to-\]\:animate-out[data-motion^='to-'] {
+ animation-name: exit;
+ animation-duration: 150ms;
+ --tw-exit-opacity: initial;
+ --tw-exit-scale: initial;
+ --tw-exit-rotate: initial;
+ --tw-exit-translate-x: initial;
+ --tw-exit-translate-y: initial;
+}
+
+.data-\[state\=closed\]\:animate-out[data-state='closed'] {
+ animation-name: exit;
+ animation-duration: 150ms;
+ --tw-exit-opacity: initial;
+ --tw-exit-scale: initial;
+ --tw-exit-rotate: initial;
+ --tw-exit-translate-x: initial;
+ --tw-exit-translate-y: initial;
+}
+
+.data-\[state\=hidden\]\:animate-out[data-state='hidden'] {
+ animation-name: exit;
+ animation-duration: 150ms;
+ --tw-exit-opacity: initial;
+ --tw-exit-scale: initial;
+ --tw-exit-rotate: initial;
+ --tw-exit-translate-x: initial;
+ --tw-exit-translate-y: initial;
+}
+
+.data-\[swipe\=end\]\:animate-out[data-swipe='end'] {
+ animation-name: exit;
+ animation-duration: 150ms;
+ --tw-exit-opacity: initial;
+ --tw-exit-scale: initial;
+ --tw-exit-rotate: initial;
+ --tw-exit-translate-x: initial;
+ --tw-exit-translate-y: initial;
+}
+
+.data-\[motion\^\=from-\]\:fade-in[data-motion^='from-'] {
+ --tw-enter-opacity: 0;
+}
+
+.data-\[motion\^\=to-\]\:fade-out[data-motion^='to-'] {
+ --tw-exit-opacity: 0;
+}
+
+.data-\[state\=closed\]\:fade-out-0[data-state='closed'] {
+ --tw-exit-opacity: 0;
+}
+
+.data-\[state\=closed\]\:fade-out-80[data-state='closed'] {
+ --tw-exit-opacity: 0.8;
+}
+
+.data-\[state\=hidden\]\:fade-out[data-state='hidden'] {
+ --tw-exit-opacity: 0;
+}
+
+.data-\[state\=open\]\:fade-in-0[data-state='open'] {
+ --tw-enter-opacity: 0;
+}
+
+.data-\[state\=visible\]\:fade-in[data-state='visible'] {
+ --tw-enter-opacity: 0;
+}
+
+.data-\[state\=closed\]\:zoom-out-95[data-state='closed'] {
+ --tw-exit-scale: 0.95;
+}
+
+.data-\[state\=open\]\:zoom-in-90[data-state='open'] {
+ --tw-enter-scale: 0.9;
+}
+
+.data-\[state\=open\]\:zoom-in-95[data-state='open'] {
+ --tw-enter-scale: 0.95;
+}
+
+.data-\[motion\=from-end\]\:slide-in-from-right-52[data-motion='from-end'] {
+ --tw-enter-translate-x: 13rem;
+}
+
+.data-\[motion\=from-start\]\:slide-in-from-left-52[data-motion='from-start'] {
+ --tw-enter-translate-x: -13rem;
+}
+
+.data-\[motion\=to-end\]\:slide-out-to-right-52[data-motion='to-end'] {
+ --tw-exit-translate-x: 13rem;
+}
+
+.data-\[motion\=to-start\]\:slide-out-to-left-52[data-motion='to-start'] {
+ --tw-exit-translate-x: -13rem;
+}
+
+.data-\[side\=bottom\]\:slide-in-from-top-2[data-side='bottom'] {
+ --tw-enter-translate-y: -0.5rem;
+}
+
+.data-\[side\=left\]\:slide-in-from-right-2[data-side='left'] {
+ --tw-enter-translate-x: 0.5rem;
+}
+
+.data-\[side\=right\]\:slide-in-from-left-2[data-side='right'] {
+ --tw-enter-translate-x: -0.5rem;
+}
+
+.data-\[side\=top\]\:slide-in-from-bottom-2[data-side='top'] {
+ --tw-enter-translate-y: 0.5rem;
+}
+
+.data-\[state\=closed\]\:slide-out-to-bottom[data-state='closed'] {
+ --tw-exit-translate-y: 100%;
+}
+
+.data-\[state\=closed\]\:slide-out-to-left[data-state='closed'] {
+ --tw-exit-translate-x: -100%;
+}
+
+.data-\[state\=closed\]\:slide-out-to-left-1\/2[data-state='closed'] {
+ --tw-exit-translate-x: -50%;
+}
+
+.data-\[state\=closed\]\:slide-out-to-right[data-state='closed'] {
+ --tw-exit-translate-x: 100%;
+}
+
+.data-\[state\=closed\]\:slide-out-to-right-full[data-state='closed'] {
+ --tw-exit-translate-x: 100%;
+}
+
+.data-\[state\=closed\]\:slide-out-to-top[data-state='closed'] {
+ --tw-exit-translate-y: -100%;
+}
+
+.data-\[state\=closed\]\:slide-out-to-top-\[48\%\][data-state='closed'] {
+ --tw-exit-translate-y: -48%;
+}
+
+.data-\[state\=open\]\:slide-in-from-bottom[data-state='open'] {
+ --tw-enter-translate-y: 100%;
+}
+
+.data-\[state\=open\]\:slide-in-from-left[data-state='open'] {
+ --tw-enter-translate-x: -100%;
+}
+
+.data-\[state\=open\]\:slide-in-from-left-1\/2[data-state='open'] {
+ --tw-enter-translate-x: -50%;
+}
+
+.data-\[state\=open\]\:slide-in-from-right[data-state='open'] {
+ --tw-enter-translate-x: 100%;
+}
+
+.data-\[state\=open\]\:slide-in-from-top[data-state='open'] {
+ --tw-enter-translate-y: -100%;
+}
+
+.data-\[state\=open\]\:slide-in-from-top-\[48\%\][data-state='open'] {
+ --tw-enter-translate-y: -48%;
+}
+
+.data-\[state\=open\]\:slide-in-from-top-full[data-state='open'] {
+ --tw-enter-translate-y: -100%;
+}
+
+.data-\[state\=closed\]\:duration-300[data-state='closed'] {
+ animation-duration: 300ms;
+}
+
+.data-\[state\=open\]\:duration-500[data-state='open'] {
+ animation-duration: 500ms;
+}
+
+.data-\[panel-group-direction\=vertical\]\:after\:left-0[data-panel-group-direction='vertical']::after {
+ content: var(--tw-content);
+ left: 0px;
+}
+
+.data-\[panel-group-direction\=vertical\]\:after\:h-1[data-panel-group-direction='vertical']::after {
+ content: var(--tw-content);
+ height: 0.25rem;
+}
+
+.data-\[panel-group-direction\=vertical\]\:after\:w-full[data-panel-group-direction='vertical']::after {
+ content: var(--tw-content);
+ width: 100%;
+}
+
+.data-\[panel-group-direction\=vertical\]\:after\:-translate-y-1\/2[data-panel-group-direction='vertical']::after {
+ content: var(--tw-content);
+ --tw-translate-y: -50%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.data-\[panel-group-direction\=vertical\]\:after\:translate-x-0[data-panel-group-direction='vertical']::after {
+ content: var(--tw-content);
+ --tw-translate-x: 0px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.group[data-state='open'] .group-data-\[state\=open\]\:rotate-180 {
+ --tw-rotate: 180deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.dark\:flex:is(.dark *) {
+ display: flex;
+}
+
+.dark\:hidden:is(.dark *) {
+ display: none;
+}
+
+.dark\:border-\[var\(--gray4\)\]:is(.dark *) {
+ border-color: var(--gray4);
+}
+
+.dark\:border-\[var\(--gray5\)\]:is(.dark *) {
+ border-color: var(--gray5);
+}
+
+.dark\:border-\[var\(--gray6\)\]:is(.dark *) {
+ border-color: var(--gray6);
+}
+
+.dark\:border-\[var\(--grayA3\)\]:is(.dark *) {
+ border-color: var(--grayA3);
+}
+
+.dark\:bg-\[var\(--gray1\)\]:is(.dark *) {
+ background-color: var(--gray1);
+}
+
+.dark\:bg-\[var\(--gray2\)\]:is(.dark *) {
+ background-color: var(--gray2);
+}
+
+.dark\:bg-\[var\(--gray3\)\]:is(.dark *) {
+ background-color: var(--gray3);
+}
+
+.dark\:bg-\[var\(--grayA2\)\]:is(.dark *) {
+ background-color: var(--grayA2);
+}
+
+.dark\:from-\[var\(--gray1\)\]:is(.dark *) {
+ --tw-gradient-from: var(--gray1) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.dark\:from-\[var\(--gray4\)\]:is(.dark *) {
+ --tw-gradient-from: var(--gray4) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.dark\:from-\[var\(--grayA12\)\]:is(.dark *) {
+ --tw-gradient-from: var(--grayA12) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.dark\:to-\[var\(--gray1\)\]:is(.dark *) {
+ --tw-gradient-to: var(--gray1) var(--tw-gradient-to-position);
+}
+
+.dark\:to-\[var\(--gray5\)\]:is(.dark *) {
+ --tw-gradient-to: var(--gray5) var(--tw-gradient-to-position);
+}
+
+.dark\:to-\[var\(--grayA11\)\]:is(.dark *) {
+ --tw-gradient-to: var(--grayA11) var(--tw-gradient-to-position);
+}
+
+.dark\:fill-\[var\(--amberA8\)\]:is(.dark *) {
+ fill: var(--amberA8);
+}
+
+.dark\:fill-\[var\(--grayA10\)\]:is(.dark *) {
+ fill: var(--grayA10);
+}
+
+.dark\:fill-\[var\(--grayA3\)\]:is(.dark *) {
+ fill: var(--grayA3);
+}
+
+.dark\:fill-\[var\(--grayA8\)\]:is(.dark *) {
+ fill: var(--grayA8);
+}
+
+.dark\:fill-\[var\(--greenA5\)\]:is(.dark *) {
+ fill: var(--greenA5);
+}
+
+.dark\:fill-\[var\(--redA8\)\]:is(.dark *) {
+ fill: var(--redA8);
+}
+
+.dark\:text-\[var\(--accent10\)\]:is(.dark *) {
+ color: var(--accent10);
+}
+
+.dark\:text-\[var\(--gray10\)\]:is(.dark *) {
+ color: var(--gray10);
+}
+
+.dark\:text-\[var\(--gray12\)\]:is(.dark *) {
+ color: var(--gray12);
+}
+
+.dark\:decoration-\[var\(--gray8\)\]:is(.dark *) {
+ -webkit-text-decoration-color: var(--gray8);
+ text-decoration-color: var(--gray8);
+}
+
+.dark\:outline-\[var\(--gray4\)\]:is(.dark *) {
+ outline-color: var(--gray4);
+}
+
+.dark\:ring-\[var\(--gray4\)\]:is(.dark *) {
+ --tw-ring-color: var(--gray4);
+}
+
+.dark\:ring-\[var\(--gray6\)\]:is(.dark *) {
+ --tw-ring-color: var(--gray6);
+}
+
+.dark\:brightness-100:is(.dark *) {
+ --tw-brightness: brightness(1);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.dark\:brightness-\[1\.2\]:is(.dark *) {
+ --tw-brightness: brightness(1.2);
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
+ var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
+ var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.dark\:after\:bg-\[var\(--grayA2\)\]:is(.dark *)::after {
+ content: var(--tw-content);
+ background-color: var(--grayA2);
+}
+
+.dark\:after\:from-\[var\(--grayA5\)\]:is(.dark *)::after {
+ content: var(--tw-content);
+ --tw-gradient-from: var(--grayA5) var(--tw-gradient-from-position);
+ --tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
+}
+
+.dark\:after\:to-\[var\(--grayA1\)\]:is(.dark *)::after {
+ content: var(--tw-content);
+ --tw-gradient-to: var(--grayA1) var(--tw-gradient-to-position);
+}
+
+.dark\:hover\:bg-\[var\(--gray2\)\]:hover:is(.dark *) {
+ background-color: var(--gray2);
+}
+
+.dark\:hover\:bg-transparent:hover:is(.dark *) {
+ background-color: transparent;
+}
+
+.dark\:hover\:text-\[var\(--gray1\)\]:hover:is(.dark *) {
+ color: var(--gray1);
+}
+
+.dark\:hover\:text-\[var\(--gray11\)\]:hover:is(.dark *) {
+ color: var(--gray11);
+}
+
+.dark\:hover\:text-\[var\(--gray12\)\]:hover:is(.dark *) {
+ color: var(--gray12);
+}
+
+@media (min-width: 640px) {
+ .sm\:sticky {
+ position: sticky;
+ }
+
+ .sm\:bottom-0 {
+ bottom: 0px;
+ }
+
+ .sm\:right-0 {
+ right: 0px;
+ }
+
+ .sm\:top-auto {
+ top: auto;
+ }
+
+ .sm\:mb-10 {
+ margin-bottom: 2.5rem;
+ }
+
+ .sm\:mt-0 {
+ margin-top: 0px;
+ }
+
+ .sm\:flex {
+ display: flex;
+ }
+
+ .sm\:w-1\/2 {
+ width: 50%;
+ }
+
+ .sm\:w-full {
+ width: 100%;
+ }
+
+ .sm\:max-w-\[425px\] {
+ max-width: 425px;
+ }
+
+ .sm\:max-w-sm {
+ max-width: 24rem;
+ }
+
+ .sm\:translate-y-24 {
+ --tw-translate-y: 6rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ }
+
+ .sm\:flex-row {
+ flex-direction: row;
+ }
+
+ .sm\:flex-col {
+ flex-direction: column;
+ }
+
+ .sm\:items-start {
+ align-items: flex-start;
+ }
+
+ .sm\:justify-end {
+ justify-content: flex-end;
+ }
+
+ .sm\:gap-2\.5 {
+ gap: 0.625rem;
+ }
+
+ .sm\:space-x-2 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(0.5rem * var(--tw-space-x-reverse));
+ margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
+ }
+
+ .sm\:space-x-4 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(1rem * var(--tw-space-x-reverse));
+ margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
+ }
+
+ .sm\:space-y-0 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(0px * var(--tw-space-y-reverse));
+ }
+
+ .sm\:rounded-lg {
+ border-radius: 0.5rem;
+ }
+
+ .sm\:rounded-r-none {
+ border-top-right-radius: 0px;
+ border-bottom-right-radius: 0px;
+ }
+
+ .sm\:\!p-4 {
+ padding: 1rem !important;
+ }
+
+ .sm\:px-6 {
+ padding-left: 1.5rem;
+ padding-right: 1.5rem;
+ }
+
+ .sm\:py-10 {
+ padding-top: 2.5rem;
+ padding-bottom: 2.5rem;
+ }
+
+ .sm\:pt-10 {
+ padding-top: 2.5rem;
+ }
+
+ .sm\:text-left {
+ text-align: left;
+ }
+
+ .sm\:text-7xl {
+ font-size: 4.5rem;
+ line-height: 1;
+ }
+
+ .sm\:leading-\[75\%\] {
+ line-height: 75%;
+ }
+
+ .data-\[state\=open\]\:sm\:slide-in-from-bottom-full[data-state='open'] {
+ --tw-enter-translate-y: 100%;
+ }
+}
+
+@media (min-width: 768px) {
+ .md\:absolute {
+ position: absolute;
+ }
+
+ .md\:relative {
+ position: relative;
+ }
+
+ .md\:left-0 {
+ left: 0px;
+ }
+
+ .md\:col-span-2 {
+ grid-column: span 2 / span 2;
+ }
+
+ .md\:mb-24 {
+ margin-bottom: 6rem;
+ }
+
+ .md\:min-h-screen {
+ min-height: 100vh;
+ }
+
+ .md\:w-1\/2 {
+ width: 50%;
+ }
+
+ .md\:w-4\/12 {
+ width: 33.333333%;
+ }
+
+ .md\:w-7\/12 {
+ width: 58.333333%;
+ }
+
+ .md\:w-\[var\(--radix-navigation-menu-viewport-width\)\] {
+ width: var(--radix-navigation-menu-viewport-width);
+ }
+
+ .md\:w-auto {
+ width: auto;
+ }
+
+ .md\:max-w-\[420px\] {
+ max-width: 420px;
+ }
+
+ .md\:translate-y-40 {
+ --tw-translate-y: 10rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ }
+
+ .md\:scale-100 {
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ }
+
+ .md\:grid-cols-1 {
+ grid-template-columns: repeat(1, minmax(0, 1fr));
+ }
+
+ .md\:grid-cols-2 {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+
+ .md\:grid-cols-4 {
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+ }
+
+ .md\:place-items-center {
+ place-items: center;
+ }
+
+ .md\:items-center {
+ align-items: center;
+ }
+
+ .md\:justify-center {
+ justify-content: center;
+ }
+
+ .md\:gap-0 {
+ gap: 0px;
+ }
+
+ .md\:-space-x-px > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(-1px * var(--tw-space-x-reverse));
+ margin-left: calc(-1px * calc(1 - var(--tw-space-x-reverse)));
+ }
+
+ .md\:-space-y-px > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(-1px * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(-1px * var(--tw-space-y-reverse));
+ }
+
+ .md\:text-balance {
+ text-wrap: balance;
+ }
+
+ .md\:rounded-l-2xl {
+ border-top-left-radius: 1rem;
+ border-bottom-left-radius: 1rem;
+ }
+
+ .md\:p-0 {
+ padding: 0px;
+ }
+
+ .md\:px-20 {
+ padding-left: 5rem;
+ padding-right: 5rem;
+ }
+
+ .md\:pb-20 {
+ padding-bottom: 5rem;
+ }
+
+ .md\:pt-0 {
+ padding-top: 0px;
+ }
+
+ .md\:text-3xl {
+ font-size: 1.875rem;
+ line-height: 2.25rem;
+ }
+
+ .md\:text-5xl {
+ font-size: 3rem;
+ line-height: 1;
+ }
+
+ .md\:text-8xl {
+ font-size: 6rem;
+ line-height: 1;
+ }
+
+ .md\:leading-\[75\%\] {
+ line-height: 75%;
+ }
+
+ .md\:leading-\[90\%\] {
+ line-height: 90%;
+ }
+}
+
+@media (min-width: 1024px) {
+ .lg\:relative {
+ position: relative;
+ }
+
+ .lg\:mx-auto {
+ margin-left: auto;
+ margin-right: auto;
+ }
+
+ .lg\:mb-0 {
+ margin-bottom: 0px;
+ }
+
+ .lg\:w-1\/4 {
+ width: 25%;
+ }
+
+ .lg\:w-3\/12 {
+ width: 25%;
+ }
+
+ .lg\:w-9\/12 {
+ width: 75%;
+ }
+
+ .lg\:max-w-full {
+ max-width: 100%;
+ }
+
+ .lg\:translate-y-1\/4 {
+ --tw-translate-y: 25%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ }
+
+ .lg\:grid-cols-1 {
+ grid-template-columns: repeat(1, minmax(0, 1fr));
+ }
+
+ .lg\:grid-cols-3 {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ }
+
+ .lg\:justify-center {
+ justify-content: center;
+ }
+
+ .lg\:px-4 {
+ padding-left: 1rem;
+ padding-right: 1rem;
+ }
+
+ .lg\:py-20 {
+ padding-top: 5rem;
+ padding-bottom: 5rem;
+ }
+
+ .lg\:pb-0 {
+ padding-bottom: 0px;
+ }
+
+ .lg\:pb-10 {
+ padding-bottom: 2.5rem;
+ }
+
+ .lg\:pb-28 {
+ padding-bottom: 7rem;
+ }
+
+ .lg\:pl-12 {
+ padding-left: 3rem;
+ }
+
+ .lg\:pl-36 {
+ padding-left: 9rem;
+ }
+
+ .lg\:pl-px {
+ padding-left: 1px;
+ }
+
+ .lg\:text-5xl {
+ font-size: 3rem;
+ line-height: 1;
+ }
+}
+
+@media (min-width: 1280px) {
+ .xl\:mr-10 {
+ margin-right: 2.5rem;
+ }
+
+ .xl\:flex {
+ display: flex;
+ }
+
+ .xl\:inline-flex {
+ display: inline-flex;
+ }
+
+ .xl\:grid {
+ display: grid;
+ }
+
+ .xl\:hidden {
+ display: none;
+ }
+
+ .xl\:w-auto {
+ width: auto;
+ }
+
+ .xl\:max-w-7xl {
+ max-width: 80rem;
+ }
+
+ .xl\:translate-y-1\/3 {
+ --tw-translate-y: 33.333333%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ }
+
+ .xl\:grid-cols-1 {
+ grid-template-columns: repeat(1, minmax(0, 1fr));
+ }
+
+ .xl\:grid-cols-2 {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+
+ .xl\:grid-cols-3 {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ }
+
+ .xl\:flex-col {
+ flex-direction: column;
+ }
+
+ .xl\:flex-nowrap {
+ flex-wrap: nowrap;
+ }
+
+ .xl\:gap-12 {
+ gap: 3rem;
+ }
+
+ .xl\:gap-16 {
+ gap: 4rem;
+ }
+
+ .xl\:p-20 {
+ padding: 5rem;
+ }
+
+ .xl\:pt-20 {
+ padding-top: 5rem;
+ }
+
+ .xl\:text-5xl {
+ font-size: 3rem;
+ line-height: 1;
+ }
+}
+
+.\[\&\+div\]\:text-xs + div {
+ font-size: 0.75rem;
+ line-height: 1rem;
+}
+
+.\[\&\:has\(\>\.day-range-end\)\]\:rounded-r-md:has(> .day-range-end) {
+ border-top-right-radius: 0.375rem;
+ border-bottom-right-radius: 0.375rem;
+}
+
+.\[\&\:has\(\>\.day-range-start\)\]\:rounded-l-md:has(> .day-range-start) {
+ border-top-left-radius: 0.375rem;
+ border-bottom-left-radius: 0.375rem;
+}
+
+.\[\&\:has\(\[aria-selected\]\)\]\:rounded-md:has([aria-selected]) {
+ border-radius: 0.375rem;
+}
+
+.\[\&\:has\(\[aria-selected\]\)\]\:bg-accent:has([aria-selected]) {
+ background-color: var(--accent11);
+}
+
+.first\:\[\&\:has\(\[aria-selected\]\)\]\:rounded-l-md:has(
+ [aria-selected]
+ ):first-child {
+ border-top-left-radius: 0.375rem;
+ border-bottom-left-radius: 0.375rem;
+}
+
+.last\:\[\&\:has\(\[aria-selected\]\)\]\:rounded-r-md:has(
+ [aria-selected]
+ ):last-child {
+ border-top-right-radius: 0.375rem;
+ border-bottom-right-radius: 0.375rem;
+}
+
+.\[\&\:has\(\[aria-selected\]\.day-range-end\)\]\:rounded-r-md:has(
+ [aria-selected].day-range-end
+ ) {
+ border-top-right-radius: 0.375rem;
+ border-bottom-right-radius: 0.375rem;
+}
+
+.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role='checkbox']) {
+ padding-right: 0px;
+}
+
+.\[\&\:not\(\:first-child\)\]\:mt-6:not(:first-child) {
+ margin-top: 1.5rem;
+}
+
+.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\] > [role='checkbox'] {
+ --tw-translate-y: 2px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.\[\&\>li\]\:mt-2 > li {
+ margin-top: 0.5rem;
+}
+
+.\[\&\>span\]\:line-clamp-1 > span {
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 1;
+}
+
+.\[\&\>svg\+div\]\:translate-y-\[-3px\] > svg + div {
+ --tw-translate-y: -3px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.\[\&\>svg\]\:absolute > svg {
+ position: absolute;
+}
+
+.\[\&\>svg\]\:left-4 > svg {
+ left: 1rem;
+}
+
+.\[\&\>svg\]\:top-4 > svg {
+ top: 1rem;
+}
+
+.\[\&\>svg\]\:size-2\.5 > svg {
+ width: 0.625rem;
+ height: 0.625rem;
+}
+
+.\[\&\>svg\]\:size-3 > svg {
+ width: 0.75rem;
+ height: 0.75rem;
+}
+
+.\[\&\>svg\]\:size-3\.5 > svg {
+ width: 0.875rem;
+ height: 0.875rem;
+}
+
+.\[\&\>svg\]\:text-destructive > svg {
+ color: var(--red9);
+}
+
+.\[\&\>svg\]\:text-foreground > svg {
+ color: var(--gray12);
+}
+
+.\[\&\>svg\]\:text-muted-foreground > svg {
+ color: var(--gray11);
+}
+
+.\[\&\>svg\~\*\]\:pl-7 > svg ~ * {
+ padding-left: 1.75rem;
+}
+
+.\[\&\>tr\]\:last\:border-b-0:last-child > tr {
+ border-bottom-width: 0px;
+}
+
+.\[\&\[data-panel-group-direction\=vertical\]\>div\]\:rotate-90[data-panel-group-direction='vertical']
+ > div {
+ --tw-rotate: 90deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.\[\&\[data-state\=open\]\>svg\]\:rotate-180[data-state='open'] > svg {
+ --tw-rotate: 180deg;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y))
+ rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
+ scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.\[\&_\.recharts-cartesian-axis-tick_text\]\:fill-muted-foreground
+ .recharts-cartesian-axis-tick
+ text {
+ fill: var(--gray11);
+}
+
+.\[\&_\.recharts-curve\.recharts-tooltip-cursor\]\:stroke-border
+ .recharts-curve.recharts-tooltip-cursor {
+ stroke: var(--gray4);
+}
+
+.\[\&_\.recharts-dot\[stroke\=\'\#fff\'\]\]\:stroke-transparent
+ .recharts-dot[stroke='#fff'] {
+ stroke: transparent;
+}
+
+.\[\&_\.recharts-layer\]\:outline-none .recharts-layer {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.\[\&_\.recharts-polar-grid_\[stroke\=\'\#ccc\'\]\]\:stroke-border
+ .recharts-polar-grid
+ [stroke='#ccc'] {
+ stroke: var(--gray4);
+}
+
+.\[\&_\.recharts-radial-bar-background-sector\]\:fill-muted
+ .recharts-radial-bar-background-sector {
+ fill: var(--gray4);
+}
+
+.\[\&_\.recharts-rectangle\.recharts-tooltip-cursor\]\:fill-muted
+ .recharts-rectangle.recharts-tooltip-cursor {
+ fill: var(--gray4);
+}
+
+.\[\&_\.recharts-reference-line_\[stroke\=\'\#ccc\'\]\]\:stroke-border
+ .recharts-reference-line
+ [stroke='#ccc'] {
+ stroke: var(--gray4);
+}
+
+.\[\&_\.recharts-sector\[stroke\=\'\#fff\'\]\]\:stroke-transparent
+ .recharts-sector[stroke='#fff'] {
+ stroke: transparent;
+}
+
+.\[\&_\.recharts-sector\]\:outline-none .recharts-sector {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.\[\&_\.recharts-surface\]\:outline-none .recharts-surface {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading] {
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+}
+
+.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading] {
+ padding-top: 0.375rem;
+ padding-bottom: 0.375rem;
+}
+
+.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading] {
+ font-size: 0.75rem;
+ line-height: 1rem;
+}
+
+.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading] {
+ font-weight: 500;
+}
+
+.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading] {
+ color: var(--gray11);
+}
+
+.\[\&_p\]\:leading-relaxed p {
+ line-height: 1.625;
+}
+
+.\[\&_tr\:last-child\]\:border-0 tr:last-child {
+ border-width: 0px;
+}
+
+.\[\&_tr\]\:border-b tr {
+ border-bottom-width: 1px;
+}
diff --git a/apps/marketing/public/resume/BryanFunk_CV-Resume_v2_001_reduced.pdf b/apps/marketing/public/resume/BryanFunk_CV-Resume_v2_001_reduced.pdf
new file mode 100644
index 0000000..2304be7
Binary files /dev/null and b/apps/marketing/public/resume/BryanFunk_CV-Resume_v2_001_reduced.pdf differ
diff --git a/apps/marketing/public/resume/bryan-funk-resume-promo.webp b/apps/marketing/public/resume/bryan-funk-resume-promo.webp
new file mode 100644
index 0000000..d1b47c7
Binary files /dev/null and b/apps/marketing/public/resume/bryan-funk-resume-promo.webp differ
diff --git a/apps/marketing/src/components/avatar.tsx b/apps/marketing/src/components/avatar.tsx
deleted file mode 100644
index e000271..0000000
--- a/apps/marketing/src/components/avatar.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import {
- Avatar,
- AvatarFallback,
- AvatarImage,
-} from '@prodkt/ui/primitives/avatar'
-
-export const MyAvatar = () => {
- return (
-
-
- CN
-
- )
-}
diff --git a/apps/marketing/src/components/docs-aside.astro b/apps/marketing/src/components/docs-aside.astro
index a6b947c..2a88342 100644
--- a/apps/marketing/src/components/docs-aside.astro
+++ b/apps/marketing/src/components/docs-aside.astro
@@ -51,14 +51,14 @@ interface DocTabsProps {
documentationData: DocGroupItem[]
}
-const response = await GET()
+const response = await GET(Astro)
const data = await response.json()
const { documentationData } = data as DocTabsProps
---
@@ -70,7 +70,7 @@ const { documentationData } = data as DocTabsProps
&:has(.border-b):last-of-type {
@apply border-b-0 border-b-transparent rounded-b-none;
}
- @apply sticky top-[80px] bg-[var(--grayA1)] overflow-hidden w-[327px] rounded-xl p-0;
+ @apply sticky top-[80px] bg-[var(--grayA1)] overflow-hidden rounded-xl p-0;
ol {
@apply py-1;
li {
@@ -82,6 +82,6 @@ const { documentationData } = data as DocTabsProps
}
.prodkt-docs-aside *[data-state='open'] > button {
- @apply bg-black !important;
+ @apply bg-[var(--ghost-aa11)] !important;
}
diff --git a/apps/marketing/src/components/download-resume.tsx b/apps/marketing/src/components/download-resume.tsx
new file mode 100644
index 0000000..f2c7bff
--- /dev/null
+++ b/apps/marketing/src/components/download-resume.tsx
@@ -0,0 +1,62 @@
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+/* eslint-disable jsdoc/require-returns */
+
+import { CloudDownload } from 'lucide-react'
+
+import BryanResume from '@prodkt/assets/resume/bryan-funk-resume-promo.webp'
+
+/**
+ *
+ */
+export default function ResumeSection() {
+ return (
+
+ )
+}
diff --git a/apps/marketing/src/components/login.tsx b/apps/marketing/src/components/login.tsx
new file mode 100644
index 0000000..93718c6
--- /dev/null
+++ b/apps/marketing/src/components/login.tsx
@@ -0,0 +1,73 @@
+import { Button } from '@prodkt/ui/primitives/button'
+import { Input } from '@prodkt/ui/primitives/input'
+import { Label } from '@prodkt/ui/primitives/label'
+
+/**
+ *
+ */
+export function LoginSection() {
+ return (
+
+
+
+
+
+
+
+ A portfolio platform from Bryan Funk
+
+
+
+
+
+ )
+}
diff --git a/apps/marketing/src/components/page-header.astro b/apps/marketing/src/components/page-header.astro
index 8378027..8c0016b 100644
--- a/apps/marketing/src/components/page-header.astro
+++ b/apps/marketing/src/components/page-header.astro
@@ -1,7 +1,7 @@
---
import { cva } from 'class-variance-authority'
-import { cn } from '@prodkt/ui/cn/cn'
+import { cn } from '@/utils/cn'
const pageHeaderVariants = cva('', {
variants: {
@@ -16,7 +16,7 @@ const pageHeaderVariants = cva('', {
cn(
!minimal ? 'justify-center' : '',
fullWidth ? 'w-full mx-0' : 'mx-auto',
- 'flex flex-col items-center justify-between gap-20 relative h-auto',
+ 'flex flex-col items-center justify-between relative h-auto p-6 pt-10 md:pt-0 md:p-0',
),
},
},
@@ -53,119 +53,118 @@ const {
{text}
{bullet1}
{bullet2}
{bullet3}
{bullet4}
@@ -179,7 +178,7 @@ const {
0px 4px 24px var(--gray1),
0px 1px 1px var(--gray6);
@apply bg-gradient-to-b from-[var(--gray12)] to-[var(--gray1)] brightness-[2] contrast-50 dark:brightness-[1.2] dark:contrast-100;
- @apply bg-clip-text text-transparent px-2 py-2;
+ @apply bg-clip-text text-transparent;
leading-trim: both;
text-edge: cap;
diff --git a/apps/marketing/src/components/plutio/plutio.astro b/apps/marketing/src/components/plutio/plutio.astro
new file mode 100644
index 0000000..f7003ee
--- /dev/null
+++ b/apps/marketing/src/components/plutio/plutio.astro
@@ -0,0 +1,34 @@
+---
+// @ts-nocheck
+---
+
+
diff --git a/apps/marketing/src/components/portfolio-slider.astro b/apps/marketing/src/components/portfolio-slider.astro
index b393aaf..1ab960c 100644
--- a/apps/marketing/src/components/portfolio-slider.astro
+++ b/apps/marketing/src/components/portfolio-slider.astro
@@ -22,10 +22,10 @@ const { template } = Astro.props
@@ -84,43 +84,42 @@ const { template } = Astro.props
swiper-container {
width: 100%;
height: 100%;
+ max-height: calc(100dvh - 100px);
}
.mySwiper swiper-slide {
text-align: center;
font-size: 18px;
display: flex;
- @rounded-3xl overflow-hidden border flex shrink w-auto mx-auto border-[var(--grayA6)];
+ @apply rounded-3xl overflow-hidden mx-auto my-auto;
justify-content: center;
align-items: center;
- @apply rounded-[2rem] overflow-hidden;
}
.mySwiper swiper-slide:has(.swiper-slide-active) {
- @apply overflow-hidden w-auto scale-100 transition-all duration-500;
+ @apply w-auto scale-100 transition-all duration-500 opacity-100;
}
.mySwiper swiper-slide:not(.swiper-slide-active) img {
- @apply overflow-hidden w-auto scale-75 blur-sm relative transition-all duration-1000;
+ @apply overflow-hidden scale-75 blur-sm relative transition-all duration-1000 brightness-50;
}
.mySwiper swiper-slide img {
display: sw >
+ placeholder?: string
+ className?: string
+ characterLimit?: number
+ proseInvert?: boolean
+}) {
+ const editor = useEditor({
+ extensions: [
+ StarterKit as AnyExtension,
+ Highlight,
+ Typography,
+ Link.configure({
+ HTMLAttributes: {
+ class: 'cursor-pointer',
+ },
+ }),
+ Placeholder.configure({
+ placeholder: placeholder ?? 'Write something...',
+ }),
+ CharacterCount.configure({
+ limit: characterLimit ?? undefined,
+ }),
+ ],
+ content,
+ editorProps: {
+ attributes: {
+ class: `prose prose-sm dark:prose-invert focus:outline-none${proseInvert ? ' prose-invert' : ''}`,
+ },
+ },
+ onUpdate: ({ editor }) => {
+ setContent(editor.getHTML())
+ },
+ })
+
+ return (
+
+ )
+}
diff --git a/apps/marketing/src/components/signup.tsx b/apps/marketing/src/components/signup.tsx
new file mode 100644
index 0000000..e388245
--- /dev/null
+++ b/apps/marketing/src/components/signup.tsx
@@ -0,0 +1,71 @@
+import { Button } from '@prodkt/ui/primitives/button'
+import { Input } from '@prodkt/ui/primitives/input'
+import { Label } from '@prodkt/ui/primitives/label'
+
+/**
+ *
+ */
+export function RegisterSection() {
+ return (
+
+
+
+
+
+ {/* */}
+ {/* */}
+
+
Create Account
+
+ Register below to access exclusive content and downlaods
+
+
+
+
+
+
+
+
+
+
+
+ A portfolio platform from Bryan Funk
+
+
+
+
+
+ )
+}
diff --git a/apps/marketing/src/components/work-history.tsx b/apps/marketing/src/components/work-history.tsx
new file mode 100644
index 0000000..ab5c33b
--- /dev/null
+++ b/apps/marketing/src/components/work-history.tsx
@@ -0,0 +1,245 @@
+/* eslint-disable jsdoc/require-returns */
+/* eslint-disable jsdoc/require-param-description */
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+
+import { useEffect, useState } from 'react'
+
+import type { Database } from '@/database.types'
+
+import {
+ DesignBoiseLogo,
+ ImpLogo,
+ LumenLogo,
+ TovutiLogo,
+} from '@prodkt/ui/brands/employers'
+import {
+ Tabs,
+ TabsContent,
+ TabsList,
+ TabsTrigger,
+} from '@prodkt/ui/primitives/tabs'
+
+import { createClientSupabaseClient } from '@/supabase'
+// import { GET as getSupabaseClient } from '@/supabase'
+import { formatDate } from '@/utils/formatDate'
+
+interface WorkItem {
+ secondary_heading?: string
+ secondary_subheading?: string
+ // highlights?: Highlight[]; // Use the proper type here
+ highlights?: { id: string; highlight?: string }[] // Ensure your highlight has the proper structure
+ logo: string | null | boolean
+ name?: string
+ position?: string
+ position_subheading?: string
+ start_date: string | null
+ end_date: string | null
+}
+
+type Resumes = Database['public']['Tables']['resumes']['Row'] & {
+ id: string
+ work: WorkItem[] // Declare it as an array of WorkItem objects
+}
+
+/**
+ *
+ */
+
+/**
+ *
+ * @param root0
+ * @param root0.initialWorkHistory
+ */
+
+const supabase = createClientSupabaseClient()
+
+/**
+ *
+ * @param root0
+ * @param root0.initialWorkHistory
+ */
+export function WorkHistory({ initialWorkHistory = [] }) {
+ const [workHistory, setWorkHistory] = useState([])
+ const [error, setError] = useState(null)
+
+ useEffect(() => {
+ const fetchWorkHistory = async () => {
+ if (initialWorkHistory.length > 0) return
+
+ try {
+ const { data, error } = await supabase
+ .from('resumes')
+ .select('*,image(filename_disk)')
+ .eq('status', 'published')
+
+ if (error) {
+ throw new Error(error.message)
+ }
+
+ if (Array.isArray(data)) {
+ setWorkHistory(data as unknown as Resumes[])
+ } else {
+ throw new Error('Unexpected data format')
+ }
+ } catch (err) {
+ console.error('Error fetching work history:', err)
+ setError(
+ err instanceof Error
+ ? err
+ : new Error('Failed to fetch work history'),
+ )
+ }
+ }
+
+ fetchWorkHistory().catch((error: unknown) => {
+ console.error('Failed to fetch work history:', error)
+ })
+ }, [initialWorkHistory])
+
+ if (error) {
+ return Error: {error.message}
+ }
+
+ return (
+
+ {workHistory.map((resume) => {
+ if (!Array.isArray(resume.work)) {
+ return null
+ }
+
+ // Sort work items by end_date in descending order
+ const sortedWork = resume.work.toSorted((a, b) => {
+ const dateA = new Date(formatDate(a.start_date))
+ const dateB = new Date(formatDate(b.end_date))
+ return dateB.getTime() - dateA.getTime()
+ })
+
+ return sortedWork.map((workItem, index) => (
+
+
+
+
+ {!workItem.logo ? (
+
+ {workItem.name}
+
+ ) : null}
+ {workItem.logo && workItem.name === 'Tovuti LMS' ? (
+
+ ) : null}
+ {workItem.logo && workItem.name === 'Design Boise' ? (
+
+ ) : null}
+ {workItem.logo &&
+ workItem.name === 'International Minute Press' ? (
+
+ ) : null}
+ {workItem.logo && workItem.name === 'Lumen Creative' ? (
+
+ ) : null}
+
+
+
+ {workItem.position}
+
+
+ {workItem.position_subheading}
+
+
+ {workItem.secondary_heading &&
+ workItem.secondary_heading.length > 0 ? (
+
+
+ {workItem.secondary_heading}
+
+ {workItem.secondary_subheading &&
+ workItem.secondary_subheading.length > 0 ? (
+
+ {workItem.secondary_subheading}
+
+ ) : null}
+
+ ) : null}
+
+
+
+
+ {formatDate(workItem.start_date)}
+
+
+
+
+
+ {formatDate(workItem.end_date)}
+
+
+
+
+
+
+
+
+
+
+
+ Highlights
+
+
+ Work
+
+
+
+
+ {workItem.highlights?.map((highlight, index) => {
+ const highlightKey = highlight.id
+ ? `highlight-${resume.id}-${highlight.id}`
+ : // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ `highlight-${resume.id}-fallback-${index}`
+
+ return (
+
+
+
+
+ dangerouslySetInnerHTML={{
+ __html: highlight.highlight ?? '',
+ }}
+ />
+
+
+ )
+ })}
+
+
+
+
+
+ Work examples coming soon.
+
+
+
+
+
+
+
+
+ ))
+ })}
+
+ )
+}
diff --git a/apps/marketing/src/database.types.ts b/apps/marketing/src/database.types.ts
index 8eda098..4fdb001 100644
--- a/apps/marketing/src/database.types.ts
+++ b/apps/marketing/src/database.types.ts
@@ -537,10 +537,12 @@ export type Database = {
frontmatter: string | null
html: string | null
id: string
+ isStory: boolean | null
named_export: string | null
slug: string | null
sort: number | null
status: string
+ storybook_id: string | null
syntax: string | null
title: string | null
user_created: string | null
@@ -554,10 +556,12 @@ export type Database = {
frontmatter?: string | null
html?: string | null
id: string
+ isStory?: boolean | null
named_export?: string | null
slug?: string | null
sort?: number | null
status?: string
+ storybook_id?: string | null
syntax?: string | null
title?: string | null
user_created?: string | null
@@ -571,10 +575,12 @@ export type Database = {
frontmatter?: string | null
html?: string | null
id?: string
+ isStory?: boolean | null
named_export?: string | null
slug?: string | null
sort?: number | null
status?: string
+ storybook_id?: string | null
syntax?: string | null
title?: string | null
user_created?: string | null
@@ -2369,11 +2375,26 @@ export type Database = {
},
]
}
+ documentation_navigation: {
+ Row: {
+ id: string
+ }
+ Insert: {
+ id: string
+ }
+ Update: {
+ id?: string
+ }
+ Relationships: []
+ }
documentation_page: {
Row: {
date_created: string | null
date_updated: string | null
+ excerpt: string | null
id: string
+ image: string | null
+ order_id: string | null
slug: string | null
sort: number | null
status: string
@@ -2384,7 +2405,10 @@ export type Database = {
Insert: {
date_created?: string | null
date_updated?: string | null
+ excerpt?: string | null
id: string
+ image?: string | null
+ order_id?: string | null
slug?: string | null
sort?: number | null
status?: string
@@ -2395,7 +2419,10 @@ export type Database = {
Update: {
date_created?: string | null
date_updated?: string | null
+ excerpt?: string | null
id?: string
+ image?: string | null
+ order_id?: string | null
slug?: string | null
sort?: number | null
status?: string
@@ -2404,6 +2431,20 @@ export type Database = {
user_updated?: string | null
}
Relationships: [
+ {
+ foreignKeyName: 'documentation_page_image_foreign'
+ columns: ['image']
+ isOneToOne: false
+ referencedRelation: 'directus_files'
+ referencedColumns: ['id']
+ },
+ {
+ foreignKeyName: 'documentation_page_order_id_foreign'
+ columns: ['order_id']
+ isOneToOne: false
+ referencedRelation: 'documentation_navigation'
+ referencedColumns: ['id']
+ },
{
foreignKeyName: 'documentation_page_user_created_foreign'
columns: ['user_created']
@@ -3002,23 +3043,33 @@ export type Database = {
folder: {
Row: {
id: string
+ image: string | null
parent: string | null
project: string | null
title: string | null
}
Insert: {
id: string
+ image?: string | null
parent?: string | null
project?: string | null
title?: string | null
}
Update: {
id?: string
+ image?: string | null
parent?: string | null
project?: string | null
title?: string | null
}
Relationships: [
+ {
+ foreignKeyName: 'folder_image_foreign'
+ columns: ['image']
+ isOneToOne: false
+ referencedRelation: 'directus_files'
+ referencedColumns: ['id']
+ },
{
foreignKeyName: 'folder_parent_foreign'
columns: ['parent']
diff --git a/apps/marketing/src/layouts/PublicLayout.astro b/apps/marketing/src/layouts/PublicLayout.astro
index 7d398ca..46e37ea 100644
--- a/apps/marketing/src/layouts/PublicLayout.astro
+++ b/apps/marketing/src/layouts/PublicLayout.astro
@@ -5,11 +5,14 @@ import { ThemeProvider } from 'next-themes'
import { Footer } from '@prodkt/ui/prodkt-components/footer'
import { Header } from '@prodkt/ui/prodkt-components/header'
-import { PageFooter } from '@prodkt/ui/prodkt-components/page-footer'
+import PageFooter from '@prodkt/ui/prodkt-components/page-footer'
import BaseHead from '@/components/BaseHead.astro'
+import Plutio from '@/components/plutio/plutio.astro'
import PostHog from '@/components/posthog/PostHog.astro'
+type DataTheme = 'dark-theme' | 'light-theme'
+type Typography = 'prodkt' | 'trendy' | 'techy' | 'press' | 'giest' | 'steady'
type Appearance = 'inherit' | 'light' | 'dark'
type AccentColor =
| 'gray'
@@ -38,12 +41,14 @@ type AccentColor =
| 'lime'
| 'mint'
| 'sky'
-type GrayColor = 'auto' | 'gray' | 'mauve' | 'slate' | 'sage' | 'olive' | 'sand'
+type GrayColor = 'gray' | 'mauve' | 'slate' | 'sage' | 'olive' | 'sand'
interface ThemeOptions {
appearance: Appearance
accentColor: AccentColor
+ theme: DataTheme
grayColor: GrayColor
+ typography: Typography
}
interface Props {
@@ -51,12 +56,16 @@ interface Props {
React.RefAttributes
grayColor?: ThemeOptions['grayColor'] & React.RefAttributes
appearance?: ThemeOptions['appearance'] & React.RefAttributes
+ theme?: ThemeOptions['theme'] & React.RefAttributes
+ typography?: ThemeOptions['typography'] & React.RefAttributes
}
const {
accentColor = 'violet',
- grayColor = 'mauve',
- appearance = 'light',
+ grayColor = 'slate',
+ appearance = 'dark',
+ theme = 'dark-theme',
+ typography = 'prodkt',
} = Astro.props
---
@@ -67,16 +76,42 @@ const {
data-is-root-theme='true'
data-accent-color={accentColor}
data-gray-color={grayColor}
+ data-theme={theme}
+ data-typography={typography}
data-has-background='false'
data-panel-background='translucent'
data-radius='large'
data-scaling='100%'
+ transition:persist
+ transition:persist-props
>
+
+
+
+export type TeamMemberProps =
+ Database['public']['Tables']['profiles']['Row'] & {
+ joined_at: string
+ }
+
+export type NotificationProps =
+ Database['public']['Tables']['notifications']['Row'] & {
+ project: { title: string; slug: string; icon: string }
+ initiator: { full_name: string }
+ }
+
+export type ProjectInviteProps = Database['public']['Tables']['project_invites']
+
+export type ProjectApiKeyProps =
+ Database['public']['Tables']['project_api_keys']
+
+export type ProjectApiKeyWithoutTokenProps = Omit<
+ ProjectApiKeyProps['Row'],
+ 'token'
+>
+
+export type ExtendedInviteProps = ProjectInviteProps['Row'] & {
+ project: { name: string; slug: string; icon: string }
+ creator: { full_name: string }
+}
+
+export type AnalyticsProps = {
+ key: string
+ clicks: number
+ visitors: number
+}[]
+
+export type ChangelogProps = Database['public']['Tables']['changelogs']
+
+export type ChangelogWithAuthorProps =
+ Database['public']['Tables']['changelogs']['Row'] & {
+ author: ProfileProps['Row']
+ }
+
+export type ChangelogSubscriberProps =
+ Database['public']['Tables']['changelog_subscribers']
+
+export type FeedbackProps = Database['public']['Tables']['feedback']
+
+export type FeedbackTagProps = Database['public']['Tables']['feedback_tags']
+
+export type FeedbackWithUserProps =
+ Database['public']['Tables']['feedback']['Row'] & {
+ user: ProfileProps['Row'] & { isTeamMember: boolean }
+ tags: { name: string; color: string }[]
+ has_upvoted: boolean
+ }
+
+export type FeedbackWithUserInputProps =
+ Database['public']['Tables']['feedback']['Insert'] & {
+ tags?: string[]
+ user?: ProfileProps['Update']
+ }
+
+export type FeedbackCommentProps =
+ Database['public']['Tables']['feedback_comments']
+
+export type FeedbackCommentWithUserProps =
+ Database['public']['Tables']['feedback_comments']['Row'] & {
+ user: ProfileProps['Row'] & { isTeamMember: boolean }
+ has_upvoted: boolean
+ replies: FeedbackCommentWithUserProps[]
+ }
+
+export type ProfileProps = Database['public']['Tables']['profiles']
+
+// Helper Types
+export interface ErrorProps {
+ message: string
+ status: number
+}
+
+// Incase error is null, data won't be and vice versa
+export type ApiResponse<
+ T,
+ E extends ErrorProps | null = ErrorProps | null,
+> = Promise<
+ E extends null ? { data: T; error: null } : { data: null; error: E }
+>
+
+export interface NavbarTabProps {
+ name: string
+ icon: {
+ dark: Record
| string
+ light: Record | string
+ }
+ slug: string
+}
+
+export interface CategoryTabProps {
+ name: string
+ slug: string
+}
diff --git a/apps/marketing/src/middleware/index.ts b/apps/marketing/src/middleware/index.ts
index e4282e2..3dff071 100644
--- a/apps/marketing/src/middleware/index.ts
+++ b/apps/marketing/src/middleware/index.ts
@@ -1,62 +1,74 @@
+import type { APIContext } from 'astro'
+
import { defineMiddleware } from 'astro:middleware'
import micromatch from 'micromatch'
-import { supabase } from '@/supabase'
+import { GET as getSupabaseClient } from '@/supabase'
const protectedRoutes = ['/dashboard(|/)']
const redirectRoutes = ['/signin(|/)', '/register(|/)']
const proptectedAPIRoutes = ['/api/guestbook(|/)']
export const onRequest = defineMiddleware(
- async ({ locals, url, cookies, redirect }, next) => {
- if (micromatch.isMatch(url.pathname, protectedRoutes)) {
- const accessToken = cookies.get('sb-access-token')
- const refreshToken = cookies.get('sb-refresh-token')
+ async (context: APIContext, next: () => Promise) => {
+ const supabaseResponse = await getSupabaseClient(context)
+ if (!supabaseResponse?.supabase) {
+ return new Response('Unable to initialize Supabase client', {
+ status: 500,
+ })
+ }
+ if (micromatch.isMatch(context.url.pathname, protectedRoutes)) {
+ const accessToken = context.cookies.get('sb-access-token')
+ const refreshToken = context.cookies.get('sb-refresh-token')
if (!accessToken || !refreshToken) {
- return redirect('/signin')
+ return context.redirect('/login')
}
- const { data, error } = await supabase.auth.setSession({
+ const { data, error } = await supabaseResponse.supabase.auth.setSession({
refresh_token: refreshToken.value,
access_token: accessToken.value,
})
if (error) {
- cookies.delete('sb-access-token', {
+ context.cookies.delete('sb-access-token', {
path: '/',
})
- cookies.delete('sb-refresh-token', {
+ context.cookies.delete('sb-refresh-token', {
path: '/',
})
- return redirect('/signin')
+ return context.redirect('/login')
}
- locals.email = data.user?.email ?? ''
- cookies.set('sb-access-token', data?.session?.access_token ?? '', {
- sameSite: 'strict',
- path: '/',
- secure: true,
- })
- cookies.set('sb-refresh-token', data?.session?.refresh_token ?? '', {
+ context.locals.email = data.user?.email ?? ''
+ context.cookies.set('sb-access-token', data.session?.access_token ?? '', {
sameSite: 'strict',
path: '/',
secure: true,
})
+ context.cookies.set(
+ 'sb-refresh-token',
+ data.session?.refresh_token ?? '',
+ {
+ sameSite: 'strict',
+ path: '/',
+ secure: true,
+ },
+ )
}
- if (micromatch.isMatch(url.pathname, redirectRoutes)) {
- const accessToken = cookies.get('sb-access-token')
- const refreshToken = cookies.get('sb-refresh-token')
+ if (micromatch.isMatch(context.url.pathname, redirectRoutes)) {
+ const accessToken = context.cookies.get('sb-access-token')
+ const refreshToken = context.cookies.get('sb-refresh-token')
if (accessToken && refreshToken) {
- return redirect('/dashboard')
+ return context.redirect('/dashboard')
}
}
- if (micromatch.isMatch(url.pathname, proptectedAPIRoutes)) {
- const accessToken = cookies.get('sb-access-token')
- const refreshToken = cookies.get('sb-refresh-token')
+ if (micromatch.isMatch(context.url.pathname, proptectedAPIRoutes)) {
+ const accessToken = context.cookies.get('sb-access-token')
+ const refreshToken = context.cookies.get('sb-refresh-token')
// Check for tokens
if (!accessToken || !refreshToken) {
@@ -69,7 +81,7 @@ export const onRequest = defineMiddleware(
}
// Verify the tokens
- const { error } = await supabase.auth.setSession({
+ const { error } = await supabaseResponse.supabase.auth.setSession({
access_token: accessToken.value,
refresh_token: refreshToken.value,
})
diff --git a/apps/marketing/src/pages/404.astro b/apps/marketing/src/pages/404.astro
index eec4661..d52915a 100644
--- a/apps/marketing/src/pages/404.astro
+++ b/apps/marketing/src/pages/404.astro
@@ -6,7 +6,7 @@ import Layout from '@/layouts/PublicLayout.astro'
diff --git a/apps/marketing/src/pages/api/docs-toc.json.ts b/apps/marketing/src/pages/api/docs-toc.json.ts
index 9dd362a..b6a986f 100644
--- a/apps/marketing/src/pages/api/docs-toc.json.ts
+++ b/apps/marketing/src/pages/api/docs-toc.json.ts
@@ -1,9 +1,13 @@
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+/* eslint-disable jsdoc/require-returns */
+/* eslint-disable jsdoc/require-param-description */
+
import type { Database, Json } from '@/database.types'
import type { SupabaseClient } from '@supabase/supabase-js'
+import type { APIContext } from 'astro'
import { supabase } from '@/supabase'
-const supabaseClient: SupabaseClient = supabase
interface Page {
slug: string
title: string
@@ -73,11 +77,25 @@ async function fetchDocumentationData(
* Handle GET request.
* @param root0
* @param root0.params
+ * @param context
* @returns The response object.
*/
-export async function GET() {
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
try {
- const documentationData = await fetchDocumentationData(supabaseClient)
+ const documentationData = await fetchDocumentationData(
+ SupabaseClient as SupabaseClient,
+ )
if (!documentationData || documentationData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
diff --git a/apps/marketing/src/pages/api/route.ts b/apps/marketing/src/pages/api/route.ts
new file mode 100644
index 0000000..42a8a13
--- /dev/null
+++ b/apps/marketing/src/pages/api/route.ts
@@ -0,0 +1,31 @@
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+/* eslint-disable jsdoc/require-param-description */
+
+import type { APIContext } from 'astro'
+
+import { createServerClient, parseCookieHeader } from '@supabase/ssr'
+
+/**
+ *
+ * @param context
+ */
+export function GET(context: APIContext) {
+ const supabase = createServerClient(
+ import.meta.env.PUBLIC_SUPABASE_URL,
+ import.meta.env.PUBLIC_SUPABASE_ANON_KEY,
+ {
+ cookies: {
+ getAll() {
+ return parseCookieHeader(context.request.headers.get('Cookie') ?? '')
+ },
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) => {
+ context.cookies.set(name, value, options)
+ })
+ },
+ },
+ },
+ )
+
+ return supabase
+}
diff --git a/apps/marketing/src/pages/api/work-history.json.ts b/apps/marketing/src/pages/api/work-history.json.ts
new file mode 100644
index 0000000..8d433dc
--- /dev/null
+++ b/apps/marketing/src/pages/api/work-history.json.ts
@@ -0,0 +1,77 @@
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+/* eslint-disable jsdoc/require-returns */
+/* eslint-disable jsdoc/require-param-description */
+
+import type { Database } from '@/database.types'
+import type { SupabaseClient } from '@supabase/supabase-js'
+import type { APIContext } from 'astro'
+
+import { supabase } from '@/supabase'
+
+type Resumes = Database['public']['Tables']['resumes']['Row']
+/**
+ *
+ * @param supabase
+ */
+async function fetchWorkHistoryData(
+ supabase: SupabaseClient,
+): Promise {
+ const response = await supabase
+ .from('resumes')
+ .select('*, status,title,label,image,email,phone,url,summary,work,skills')
+ .eq('title', 'Bryan Funk')
+ .eq('status', 'published')
+
+ if (response.error) {
+ console.error(response.error)
+ return null
+ }
+
+ return response.data as Resumes[]
+}
+
+/**
+ * Handle GET request.
+ * @param root0
+ * @param root0.params
+ * @param context
+ * @returns The response object.
+ */
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+
+ const { supabase: SupabaseClient } = supabaseResult
+ try {
+ const WorkHistory = await fetchWorkHistoryData(
+ SupabaseClient as SupabaseClient,
+ )
+ if (!WorkHistory || WorkHistory.length === 0) {
+ console.error('Data is empty or undefined')
+ return new Response(JSON.stringify({ error: 'No data found.' }), {
+ status: 404,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ return new Response(
+ JSON.stringify({
+ WorkHistory,
+ status: 200,
+ }),
+ {
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ },
+ )
+ } catch (error) {
+ console.error('Error fetching changelog data:', error)
+ return new Response(JSON.stringify({ error: 'Internal Server Error.' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+}
diff --git a/apps/marketing/src/pages/auth/callback.ts b/apps/marketing/src/pages/auth/callback.ts
new file mode 100644
index 0000000..9a1a3f3
--- /dev/null
+++ b/apps/marketing/src/pages/auth/callback.ts
@@ -0,0 +1,33 @@
+import type { APIRoute } from 'astro'
+
+import { GET as getSupabaseClient } from '@/supabase'
+
+export const GET: APIRoute = async (context) => {
+ const supabaseResponse = await getSupabaseClient(context)
+ const authCode = context.url.searchParams.get('code')
+
+ if (!authCode) {
+ return new Response('No code provided', { status: 400 })
+ }
+
+ const { data, error } =
+ await supabaseResponse.supabase.auth.exchangeCodeForSession(authCode)
+
+ if (error) {
+ return new Response(error.message, { status: 500 })
+ }
+
+ const { access_token, refresh_token } = data.session
+
+ context.cookies.set('sb-access-token', access_token, {
+ path: '/',
+ secure: true,
+ httpOnly: true,
+ })
+ context.cookies.set('sb-refresh-token', refresh_token, {
+ path: '/',
+ secure: true,
+ httpOnly: true,
+ })
+ return context.redirect('/dashboard')
+}
diff --git a/apps/marketing/src/pages/auth/confirm.ts b/apps/marketing/src/pages/auth/confirm.ts
new file mode 100644
index 0000000..1ce803d
--- /dev/null
+++ b/apps/marketing/src/pages/auth/confirm.ts
@@ -0,0 +1,41 @@
+import { createServerClient, parseCookieHeader } from '@supabase/ssr'
+import { type EmailOtpType } from '@supabase/supabase-js'
+import { type APIRoute } from 'astro'
+
+export const GET: APIRoute = async ({ request, cookies, redirect }) => {
+ const requestUrl = new URL(request.url)
+ const token_hash = requestUrl.searchParams.get('token_hash')
+ const type = requestUrl.searchParams.get('type') as EmailOtpType | null
+ const next = requestUrl.searchParams.get('next') ?? '/'
+
+ if (token_hash && type) {
+ const supabase = createServerClient(
+ import.meta.env.PUBLIC_SUPABASE_URL,
+ import.meta.env.PUBLIC_SUPABASE_ANON_KEY,
+ {
+ cookies: {
+ getAll() {
+ return parseCookieHeader(request.headers.get('Cookie') ?? '')
+ },
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) => {
+ cookies.set(name, value, options)
+ })
+ },
+ },
+ },
+ )
+
+ const { error } = await supabase.auth.verifyOtp({
+ type,
+ token_hash,
+ })
+
+ if (!error) {
+ return redirect(next)
+ }
+ }
+
+ // return the user to an error page with some instructions
+ return redirect('/auth/auth-code-error')
+}
diff --git a/apps/marketing/src/pages/auth/login.ts b/apps/marketing/src/pages/auth/login.ts
new file mode 100644
index 0000000..dc5a595
--- /dev/null
+++ b/apps/marketing/src/pages/auth/login.ts
@@ -0,0 +1,60 @@
+import type { Provider } from '@supabase/supabase-js'
+import type { APIRoute } from 'astro'
+
+import { GET as getSupabaseClient } from '@/supabase'
+
+export const POST: APIRoute = async (context) => {
+ const formData = await context.request.formData()
+ const email = formData.get('email')?.toString()
+ const password = formData.get('password')?.toString()
+ const provider = formData.get('provider')?.toString()
+
+ const supabaseResponse = await getSupabaseClient(context)
+
+ if (provider) {
+ const { data, error } =
+ await supabaseResponse.supabase.auth.signInWithOAuth({
+ provider: provider as Provider,
+ options: {
+ redirectTo:
+ import.meta.env['PUBLIC_VERCEL_ENV'] === 'development'
+ ? 'http://localhost:4321/auth/confirm'
+ : 'https://prodkt.cloud/auth/confirm',
+ },
+ })
+
+ if (error) {
+ return new Response(error.message, { status: 500 })
+ }
+
+ return context.redirect(data.url)
+ }
+
+ if (!email || !password) {
+ return new Response('Email and password are required', { status: 400 })
+ }
+
+ const { data, error } =
+ await supabaseResponse.supabase.auth.signInWithPassword({
+ email,
+ password,
+ })
+
+ if (error) {
+ return new Response(error.message, { status: 500 })
+ }
+
+ const { access_token, refresh_token } = data.session
+ context.cookies.set('sb-access-token', access_token, {
+ sameSite: 'strict',
+ path: '/',
+ secure: true,
+ })
+ context.cookies.set('sb-refresh-token', refresh_token, {
+ sameSite: 'strict',
+ path: '/',
+ secure: true,
+ })
+
+ return context.redirect('/dashboard')
+}
diff --git a/apps/marketing/src/pages/auth/register.ts b/apps/marketing/src/pages/auth/register.ts
new file mode 100644
index 0000000..1cbdb72
--- /dev/null
+++ b/apps/marketing/src/pages/auth/register.ts
@@ -0,0 +1,26 @@
+import type { APIRoute } from 'astro'
+
+import { GET as getSupabaseClient } from '@/supabase'
+
+export const POST: APIRoute = async (context) => {
+ const formData = await context.request.formData()
+ const email = formData.get('email')?.toString()
+ const password = formData.get('password')?.toString()
+
+ if (!email || !password) {
+ return new Response('Email and password are required', { status: 400 })
+ }
+
+ const { supabase } = await getSupabaseClient(context)
+
+ const { error } = await supabase.auth.signUp({
+ email,
+ password,
+ })
+
+ if (error) {
+ return new Response(error.message, { status: 500 })
+ }
+
+ return context.redirect('/login')
+}
diff --git a/apps/marketing/src/pages/auth/signout.ts b/apps/marketing/src/pages/auth/signout.ts
new file mode 100644
index 0000000..7a2241c
--- /dev/null
+++ b/apps/marketing/src/pages/auth/signout.ts
@@ -0,0 +1,11 @@
+import type { APIRoute } from 'astro'
+
+import { GET as getSupabaseClient } from '@/supabase'
+
+export const GET: APIRoute = async (context) => {
+ const initSupabase = await getSupabaseClient(context)
+ await initSupabase.supabase.auth.signOut({ scope: 'local' })
+ context.cookies.delete('sb-access-token', { path: '/' })
+ context.cookies.delete('sb-refresh-token', { path: '/' })
+ return context.redirect('/login')
+}
diff --git a/apps/marketing/src/pages/blog/[slug]/index.astro b/apps/marketing/src/pages/blog/[slug]/index.astro
index 6c49f0e..b6797ca 100644
--- a/apps/marketing/src/pages/blog/[slug]/index.astro
+++ b/apps/marketing/src/pages/blog/[slug]/index.astro
@@ -52,7 +52,7 @@ const blogCreated = data.blogData[0]?.date_created as string
const blogAlt = data.blogData[0]?.title as string
const blogContent = data.blogData[0]?.content_block
-const contentBlock = data.blogData[0]?.content_block
+const contentBlock = data.blogData[0]?.content_block ?? ''
// Load the content block into cheerio
// @ts-ignore
diff --git a/apps/marketing/src/pages/blog/[slug]/index.json.ts b/apps/marketing/src/pages/blog/[slug]/index.json.ts
index 055e8ab..da5ae21 100644
--- a/apps/marketing/src/pages/blog/[slug]/index.json.ts
+++ b/apps/marketing/src/pages/blog/[slug]/index.json.ts
@@ -1,38 +1,29 @@
-import type { Database } from '@/database.types'
import type { SupabaseClient } from '@supabase/supabase-js'
import type { APIContext } from 'astro'
-import { supabase } from '@/supabase'
+import { getSecret } from 'astro:env/server'
-const supabaseClient: SupabaseClient = supabase
-type Articles = Database['public']['Tables']['articles']['Row']
-type Authors = Database['public']['Tables']['authors']['Row']
-type Files = Database['public']['Tables']['directus_files']['Row']
+import { supabase } from '@/supabase'
-interface ArticlesWithRelations {
- id: Articles['id']
- status: Articles['status']
- sort: Articles['sort']
- date_created: Articles['date_created']
- date_updated: Articles['date_updated']
- title: Articles['title']
- excerpt: Articles['excerpt']
- slug: Articles['slug']
- author?:
- | (Pick & {
- avatar: Pick | null
- })
- | null
- image: Pick | null
-}
/**
*
* @param root0 The API context.
* @param root0.params The parameters object.
+ * @param context
* @returns The response object.
*/
-export async function GET({ params }: APIContext) {
- const { slug } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { slug } = context.params
if (typeof slug !== 'string') {
return new Response(
JSON.stringify({ error: 'Slug is required and must be a string.' }),
@@ -45,8 +36,9 @@ export async function GET({ params }: APIContext) {
)
}
+ const { supabase: SupabaseClient } = supabaseResult
try {
- const blogData = await fetchBlogData(supabaseClient, slug)
+ const blogData = await fetchBlogData(SupabaseClient, slug)
if (!blogData || blogData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
@@ -91,21 +83,32 @@ export async function GET({ params }: APIContext) {
async function fetchBlogData(
supabase: SupabaseClient,
slug: string,
-): Promise {
- const response = await supabase
+): Promise {
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ // Start building the query
+ let query = supabase
.from('articles')
.select(
`
- *,slug,author(title,last_name,first_name,avatar(filename_disk)),image(filename_disk)
- )
- `,
+ *,slug,author(title,last_name,first_name,avatar(filename_disk)),image(filename_disk)
+ `,
)
- .neq('status', 'draft')
.eq('slug', slug)
- if (response.error === null && response.data !== null) {
- return response.data as unknown as ArticlesWithRelations[]
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ console.log('Excluding drafts from query.')
+ query = query.neq('status', 'draft')
}
+
+ const response = await query
+
+ if (response.error === null) {
+ return response.data
+ }
+
console.error(response.error)
return null
}
diff --git a/apps/marketing/src/pages/blog/index.astro b/apps/marketing/src/pages/blog/index.astro
index 1be4489..b6b60a1 100644
--- a/apps/marketing/src/pages/blog/index.astro
+++ b/apps/marketing/src/pages/blog/index.astro
@@ -32,36 +32,43 @@ interface BlogData {
}[]
}
-const response = await GET()
+const response = await GET(Astro)
const data = (await response.json()) as BlogData
---
-
-
- {
- data ? (
- data.blogData.map((item: any) => (
-
- ))
- ) : (
-
Loading...
- )
- }
+
+
+
+ {
+ data ? (
+ data.blogData.map((item: any) => (
+
+ ))
+ ) : (
+
Loading...
+ )
+ }
+
diff --git a/apps/marketing/src/pages/blog/index.json.ts b/apps/marketing/src/pages/blog/index.json.ts
index c95e731..936e200 100644
--- a/apps/marketing/src/pages/blog/index.json.ts
+++ b/apps/marketing/src/pages/blog/index.json.ts
@@ -1,29 +1,12 @@
-import type { Database } from '@/database.types'
-import type { PostgrestResponse, SupabaseClient } from '@supabase/supabase-js'
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+/* eslint-disable jsdoc/require-param-description */
-import { supabase } from '@/supabase'
+import type { SupabaseClient } from '@supabase/supabase-js'
+import type { APIContext } from 'astro'
-type Articles = Database['public']['Tables']['articles']['Row']
-type Authors = Database['public']['Tables']['authors']['Row']
-type Files = Database['public']['Tables']['directus_files']['Row']
-
-interface ArticlesWithRelations {
- id: Articles['id']
- status: Articles['status']
- sort: Articles['sort']
- date_created: Articles['date_created']
- date_updated: Articles['date_updated']
- title: Articles['title']
- excerpt: Articles['excerpt']
- slug: Articles['slug']
- author?:
- | (Pick
& {
- avatar: Pick | null
- })
- | null
- image: Pick | null
-}
-const supabaseClient: SupabaseClient = supabase
+import { getSecret } from 'astro:env/server'
+
+import { supabase } from '@/supabase'
/**
* Fetch flow data from the database.
@@ -31,21 +14,36 @@ const supabaseClient: SupabaseClient = supabase
* @returns A promise that resolves to an array of Nodes or null.
*/
async function fetchBlogData(
- supabase: SupabaseClient,
-): Promise {
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-expect-error
- const response: PostgrestResponse = await supabase
+ supabase: SupabaseClient,
+): Promise {
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ console.log('isDevMode:', isDevMode)
+
+ // Start building the query
+ let query = supabase
.from('articles')
.select(
- 'id,status,sort,date_created,date_updated,author(title,last_name,first_name,avatar(filename_disk)),title,excerpt,slug,image(filename_disk)',
+ 'id, status, sort, date_created, date_updated, title, excerpt, slug, image!inner(id,filename_disk), author!inner(id,title, first_name, last_name, avatar!inner(id,filename_disk))',
)
- .neq('status', 'draft')
+
.order('date_created', { ascending: false })
- // Type guard to check if response.error exists
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ // console.log('Excluding drafts from query.')
+ query = query.neq('status', 'draft')
+ }
+
+ const response = await query
+
+ // Log the response to see what is returned
+ // console.log('Response received:', response)
+
+ // Check for errors
if (response.error) {
- console.error(response.error)
+ console.error('Error fetching articles:', response.error)
return null
}
@@ -54,12 +52,26 @@ async function fetchBlogData(
/**
* Handle GET request.
+ * @param context
* @returns The response object.
*/
-export async function GET() {
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+
+ const { supabase: SupabaseClient } = supabaseResult
+
try {
- const blogData = await fetchBlogData(supabaseClient)
- if (!blogData || blogData.length === 0) {
+ const blogData = await fetchBlogData(SupabaseClient)
+ if (!blogData) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
status: 404,
diff --git a/apps/marketing/src/pages/changelog/index.astro b/apps/marketing/src/pages/changelog/index.astro
index 0e03379..b2f0a63 100644
--- a/apps/marketing/src/pages/changelog/index.astro
+++ b/apps/marketing/src/pages/changelog/index.astro
@@ -29,7 +29,7 @@ interface ChangelogData {
changelogData: Changelog[]
}
-const response = await GET()
+const response = await GET(Astro)
const data = (await response.json()) as ChangelogData
// Type guard to check if the value is an array of TagItem
@@ -78,108 +78,112 @@ const processTagsForItem = (item: Changelog): TagList => {
---
-
- {
- data ? (
- data.changelogData.map((item: any) => {
- const tagListData = processTagsForItem(item)
- return (
-
-
- {item.new ? (
-
- {item.new.map((item: any) => (
-
-
- {item.changeTo}
-
-
-
- ))}
-
- ) : null}
- {item.improvements ? (
-
- {item.improvements.map((improvement: any) => (
-
-
- {improvement.changeTo}
-
-
-
- ))}
-
- ) : null}
- {item.api ? (
-
- {item.api.map((item: any) => (
-
-
- {item.changeTo}
-
-
-
- ))}
-
- ) : null}
- {item.fixes ? (
-
- {item.fixes.map((fix: any) => (
-
-
- {fix.changeTo}
-
-
-
- ))}
-
- ) : null}
-
- )
- })
- ) : (
- Loading...
- )
- }
+
+
+ {
+ data ? (
+ data.changelogData.map((item: any) => {
+ const tagListData = processTagsForItem(item)
+ return (
+
+
+ {item.new ? (
+
+ {item.new.map((item: any) => (
+
+
+ {item.changeTo}
+
+
+
+ ))}
+
+ ) : null}
+ {item.improvements ? (
+
+ {item.improvements.map((improvement: any) => (
+
+
+ {improvement.changeTo}
+
+
+
+ ))}
+
+ ) : null}
+ {item.api ? (
+
+ {item.api.map((item: any) => (
+
+
+ {item.changeTo}
+
+
+
+ ))}
+
+ ) : null}
+ {item.fixes ? (
+
+ {item.fixes.map((fix: any) => (
+
+
+ {fix.changeTo}
+
+
+
+ ))}
+
+ ) : null}
+
+ )
+ })
+ ) : (
+
Loading...
+ )
+ }
+
diff --git a/apps/marketing/src/pages/changelog/index.json.ts b/apps/marketing/src/pages/changelog/index.json.ts
index 17f351d..9d3aa2b 100644
--- a/apps/marketing/src/pages/changelog/index.json.ts
+++ b/apps/marketing/src/pages/changelog/index.json.ts
@@ -1,12 +1,11 @@
import type { Database } from '@/database.types'
import type { PostgrestResponse, SupabaseClient } from '@supabase/supabase-js'
+import type { APIContext } from 'astro'
import { supabase } from '@/supabase'
type Changelog = Database['public']['Tables']['changelogs']['Row']
-const supabaseClient: SupabaseClient = supabase
-
/**
* Fetch flow data from the database.
* @param supabase The Supabase client.
@@ -21,6 +20,7 @@ async function fetchChangelogData(
'*,id,title,content,project_id,publish_date,published,summary,author_id(*),slug,image(filename_disk),improvements',
)
.neq('published', false)
+ .order('publish_date', { ascending: false })
// Type guard to check if response.error exists
if (response.error) {
@@ -33,11 +33,26 @@ async function fetchChangelogData(
/**
* Handle GET request.
+ * @param context
* @returns The response object.
*/
-export async function GET() {
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+
+ const { supabase: SupabaseClient } = supabaseResult
try {
- const changelogData = await fetchChangelogData(supabaseClient)
+ const changelogData = await fetchChangelogData(
+ SupabaseClient as SupabaseClient,
+ )
if (!changelogData || changelogData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
diff --git a/apps/marketing/src/pages/codeblocks/[templateSlug]/[codeblockSlug]/index.astro b/apps/marketing/src/pages/codeblocks/[templateSlug]/[codeblockSlug]/index.astro
index f7d9199..0924882 100644
--- a/apps/marketing/src/pages/codeblocks/[templateSlug]/[codeblockSlug]/index.astro
+++ b/apps/marketing/src/pages/codeblocks/[templateSlug]/[codeblockSlug]/index.astro
@@ -48,6 +48,9 @@ interface Codeblock {
title: string | null
user_created: string | null
user_updated: string | null
+ isStory?: boolean
+ storybook_id?: string
+ filename?: string
}
interface Layout {
layouts: Json | null
@@ -84,18 +87,24 @@ interface Data {
const response = await GET(Astro)
const data = (await response.json()) as Data
+const container =
+ data.codeblockData?.isStory !== true
+ ? await experimental_AstroContainer.create()
+ : null
+const result =
+ container !== null
+ ? await container.renderToString(componentMap[data.NamedExport])
+ : ''
-const container = await experimental_AstroContainer.create()
-const result = await container.renderToString(componentMap[data.NamedExport])
const files = {
- '/index.astro': {
- code: `${data.codeblockData.html}`,
- readOnly: true, // Set as non-editable, defaults to `false`
- active: true, // Set as main file, defaults to `false`
- hidden: false, // Tab visibility, defaults to `false`
+ [`${data.codeblockData.filename ?? 'index.astro'}`]: {
+ code: `${data.codeblockData.frontmatter}
+ ${data.codeblockData.html}`,
+ readOnly: true,
+ active: true,
+ hidden: false,
},
'/layouts/Layout.astro': {
- // code: `${(data.templateData as Template).build_template?.layouts?.[0]?.code}`,
code: `${data.templateData.build_template?.layouts?.[0]?.code}`,
readOnly: true, // Set as non-editable, defaults to `false`
active: false, // Set as main file, defaults to `false`
@@ -113,25 +122,13 @@ const files = {
active: false, // Set as main file, defaults to `false`
hidden: false, // Tab visibility, defaults to `false`
},
- // '/tailwind.config.mjs': {
- // code: `${data.stylesheets[0].tailwind_config}`,
- // readOnly: false, // Set as non-editable, defaults to `false`
- // active: false, // Set as main file, defaults to `false`
- // hidden: true // Tab visibility, defaults to `false`
- // },
- // '/styles/global.css': {
- // code: `${data.stylesheets[0].src}`,
- // readOnly: false, // Set as non-editable, defaults to `false`
- // active: false, // Set as main file, defaults to `false`
- // hidden: false // Tab visibility, defaults to `false`
- // },
}
---
-
+ {
+ data.codeblockData?.isStory !== true ? (
+
+ ) : null
+ }
+ {
+ data.codeblockData?.isStory === true ? (
+
+ ) : null
+ }
diff --git a/apps/marketing/src/pages/codeblocks/[templateSlug]/[codeblockSlug]/index.json.ts b/apps/marketing/src/pages/codeblocks/[templateSlug]/[codeblockSlug]/index.json.ts
index 0a01567..f7a88b6 100644
--- a/apps/marketing/src/pages/codeblocks/[templateSlug]/[codeblockSlug]/index.json.ts
+++ b/apps/marketing/src/pages/codeblocks/[templateSlug]/[codeblockSlug]/index.json.ts
@@ -1,37 +1,49 @@
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
/* eslint-disable jsdoc/require-returns */
/* eslint-disable jsdoc/require-param-description */
/* eslint-disable jsdoc/check-param-names */
-import type { Database } from '@/database.types'
+import type { SupabaseClient } from '@supabase/supabase-js'
import type { APIContext } from 'astro'
-import { type SupabaseClient } from '@supabase/supabase-js'
+import { getSecret } from 'astro:env/server'
import { supabase } from '@/supabase'
-const supabaseClient: SupabaseClient = supabase
-
-type CodeblockTypes = Database['public']['Tables']['codeblocks']['Row']
-
/**
*
* @param root0
* @param root0.params
* @param root0.request
+ * @param context
*/
-export async function GET({ params }: APIContext) {
- const { slug, templateSlug, codeblockSlug } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
+ const { slug, templateSlug, codeblockSlug } = context.params
try {
const codeblockData = await fetchCodeblockBySlug(
- supabaseClient,
+ SupabaseClient,
codeblockSlug,
)
if (!codeblockData) {
console.error('No codeblock found for the specified slug.')
return new Response(
- JSON.stringify({ error: 'No codeblock found for the specified slug.' }),
+ JSON.stringify({
+ error: 'No codeblock found for the specified slug.',
+ codeblockSlug,
+ }),
{
status: 404,
headers: {
@@ -41,7 +53,7 @@ export async function GET({ params }: APIContext) {
)
}
- const templateData = await fetchBuildTemplate(supabaseClient, templateSlug)
+ const templateData = await fetchBuildTemplate(SupabaseClient, templateSlug)
if (!templateData) {
console.error('No build template found for theme.')
@@ -92,22 +104,29 @@ export async function GET({ params }: APIContext) {
async function fetchCodeblockBySlug(
supabase: SupabaseClient,
slug: string | undefined,
-): Promise {
- const { data, error } = await supabase
+) {
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ let query = supabase
.from('codeblocks')
- .select('*,category(*),card_image(*)')
+ .select('*,category(*),card_image(*),isStory,storybook_id')
.eq('slug', slug)
- .neq('status', 'draft')
- .single()
- if (error ?? !data) {
- console.error('Error fetching codeblock data:', error)
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ query = query.neq('status', 'draft')
+ }
+
+ const response = await query.single()
+
+ if (response.error) {
+ console.error('Error fetching themes:', response.error)
return null
}
- return data
+ return response.data
}
-
/**
*
* @param supabase
@@ -117,20 +136,29 @@ async function fetchCodeblockBySlug(
async function fetchBuildTemplate(
supabase: SupabaseClient,
templateSlug: string | undefined,
-): Promise {
- const { data, error } = await supabase
+) {
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ // Build the query
+ let query = supabase
.from('themes')
.select(
- '*,build_template!inner(package_json,astro_config,env,layouts,logos(logo(filename_disk),logo_onDark(filename_disk))),logos(logo_onDark(filename_disk),logo(filename_disk))',
+ '*, build_template!inner(package_json,astro_config,env,layouts, logos!inner(logo!inner(filename_disk), logo_onDark!inner(filename_disk))),logos!inner(logo_onDark!inner(filename_disk),logo!inner(filename_disk))',
)
.eq('slug', templateSlug)
- .neq('status', 'draft')
- .single()
- if (error ?? !data) {
- console.error('Error fetching codeblock data:', error)
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ query = query.neq('status', 'draft')
+ }
+
+ const response = await query.single()
+
+ if (response.error) {
+ console.error('Error fetching themes:', response.error)
return null
}
- return data
+ return response.data
}
diff --git a/apps/marketing/src/pages/codeblocks/[templateSlug]/index.astro b/apps/marketing/src/pages/codeblocks/[templateSlug]/index.astro
index d4c87d9..28192bc 100644
--- a/apps/marketing/src/pages/codeblocks/[templateSlug]/index.astro
+++ b/apps/marketing/src/pages/codeblocks/[templateSlug]/index.astro
@@ -18,7 +18,7 @@ type GroupedData = {
type DataResponse = {
groupedData: GroupedData[]
}
-const response = await GET()
+const response = await GET(Astro)
const data = (await response.json()) as DataResponse
---
diff --git a/apps/marketing/src/pages/codeblocks/[templateSlug]/index.json.ts b/apps/marketing/src/pages/codeblocks/[templateSlug]/index.json.ts
index 628df22..309e5af 100644
--- a/apps/marketing/src/pages/codeblocks/[templateSlug]/index.json.ts
+++ b/apps/marketing/src/pages/codeblocks/[templateSlug]/index.json.ts
@@ -2,6 +2,7 @@
import type { Database } from '@/database.types'
import type { PostgrestResponse, SupabaseClient } from '@supabase/supabase-js'
+import type { APIContext } from 'astro'
import { supabase } from '@/supabase'
@@ -15,7 +16,7 @@ async function fetchCodeblockData(
const response: PostgrestResponse = await supabase
.from('codeblocks')
.select('id, title, slug, category(*), card_image(filename_disk)')
- .neq('status', 'draft')
+ // .neq('status', 'draft')
.single()
if (response.error) {
@@ -38,7 +39,7 @@ async function fetchThemeData(
const response: PostgrestResponse = await supabase
.from('themes')
.select('id, title, slug, build_template, logo(filename_disk), status')
- .neq('status', 'draft')
+ // .neq('status', 'draft')
.single()
if (response.error) {
@@ -76,11 +77,28 @@ async function fetchCodeblockThemeData(
return null
}
-export async function GET() {
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
try {
- const codeblockData = await fetchCodeblockData(supabase)
- const themeData = await fetchThemeData(supabase)
- const codeblockThemeData = await fetchCodeblockThemeData(supabase)
+ const codeblockData = await fetchCodeblockData(
+ SupabaseClient as SupabaseClient,
+ )
+ const themeData = await fetchThemeData(
+ SupabaseClient as SupabaseClient,
+ )
+ const codeblockThemeData = await fetchCodeblockThemeData(
+ SupabaseClient as SupabaseClient,
+ )
if (!codeblockData || !themeData || !codeblockThemeData) {
return new Response(JSON.stringify({ error: 'No data found.' }), {
diff --git a/apps/marketing/src/pages/codeblocks/index.astro b/apps/marketing/src/pages/codeblocks/index.astro
index 4abf34d..75db3b1 100644
--- a/apps/marketing/src/pages/codeblocks/index.astro
+++ b/apps/marketing/src/pages/codeblocks/index.astro
@@ -19,31 +19,41 @@ type GroupedData = {
type DataResponse = {
groupedData: GroupedData[]
}
-const response = await GET()
+const response = await GET(Astro)
const data = (await response.json()) as DataResponse
---
-
-
- {
- data ? (
- data.groupedData.map((item: any) => (
-
- ))
- ) : (
-
Loading...
- )
- }
+
+
+
+ {
+ data ? (
+ data.groupedData.map((item: any) => (
+
+ ))
+ ) : (
+
Loading...
+ )
+ }
+
diff --git a/apps/marketing/src/pages/codeblocks/index.json.ts b/apps/marketing/src/pages/codeblocks/index.json.ts
index 0a05fc8..90a03e1 100644
--- a/apps/marketing/src/pages/codeblocks/index.json.ts
+++ b/apps/marketing/src/pages/codeblocks/index.json.ts
@@ -1,121 +1,158 @@
-/* eslint-disable @typescript-eslint/no-explicit-any */
-/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+/* eslint-disable jsdoc/require-returns */
+/* eslint-disable jsdoc/require-param-description */
/* eslint-disable jsdoc/require-jsdoc */
import type { Database } from '@/database.types'
-import type { PostgrestResponse, SupabaseClient } from '@supabase/supabase-js'
+import type { SupabaseClient } from '@supabase/supabase-js'
+import type { APIContext } from 'astro'
-import { supabase } from '@/supabase'
+import { getSecret } from 'astro:env/server'
-type CodeblockThemes = Database['public']['Tables']['codeblocks_themes']['Row']
+import { supabase } from '@/supabase'
-async function fetchCodeblockData(
- supabase: SupabaseClient
,
- // biome-ignore lint/suspicious/noExplicitAny:
-): Promise {
- // biome-ignore lint/suspicious/noExplicitAny:
- const response: PostgrestResponse = await supabase
+// Function to fetch codeblock data
+/**
+ *
+ * @param supabase
+ */
+async function fetchCodeblockData(supabase: SupabaseClient) {
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ // Build the query
+ let query = supabase
.from('codeblocks')
.select('id, title, slug, category(*), card_image(filename_disk)')
- .neq('status', 'draft')
+ .order('date_created', { ascending: false })
+
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ query = query.neq('status', 'draft')
+ }
+
+ const response = await query
if (response.error) {
console.error('Error fetching codeblocks:', response.error)
return null
}
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
- if (response.data) {
- // console.log('Fetched Codeblock data:', response.data) // Log the data
- return response.data
- }
-
- return null
+ return response.data
}
-async function fetchThemeData(
- supabase: SupabaseClient,
- // biome-ignore lint/suspicious/noExplicitAny:
-): Promise {
- // biome-ignore lint/suspicious/noExplicitAny:
- const response: PostgrestResponse = await supabase
+async function fetchThemeData(supabase: SupabaseClient) {
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ // console.log('isDevMode:', isDevMode)
+
+ // Build the query
+ let query = supabase
.from('themes')
- .select('id, title, slug, build_template, logo(filename_disk), status')
- .neq('status', 'draft')
+ .select(
+ '*,logos!inner(logo_onDark!inner(filename_disk),logo!inner(filename_disk))',
+ )
+
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ query = query.neq('status', 'draft')
+ }
+
+ const response = await query
if (response.error) {
console.error('Error fetching themes:', response.error)
return null
}
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
- if (response.data) {
- // console.log('Fetched Theme data:', response.data) // Log the data
- return response.data
- }
-
- return null
+ return response.data
}
-async function fetchCodeblockThemeData(
- supabase: SupabaseClient,
-): Promise {
- const response: PostgrestResponse = await supabase
+async function fetchCodeblockThemeData(supabase: SupabaseClient) {
+ // console.log('isDevMode:', isDevMode)
+
+ // Build the query
+ const query = supabase
.from('codeblocks_themes')
.select('codeblocks_id, themes_id')
+ const response = await query
+
if (response.error) {
- console.error('Error fetching codeblocks_themes:', response.error)
+ console.error('Error fetching themes:', response.error)
return null
}
return response.data
}
-export async function GET() {
+// type Files = Database['public']['Tables']['codeblocks']['Row']
+type Codeblocks = Database['public']['Tables']['codeblocks']['Row']
+type CodeblockThemes = Database['public']['Tables']['codeblocks_themes']['Row']
+type Themes = Database['public']['Tables']['themes']['Row']
+
+interface GroupData {
+ id: Codeblocks['id'] | null
+ codeblockData: Codeblocks[] | null
+ themeData: Themes | null
+ codeblockThemeData: CodeblockThemes[] | null
+}
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
+
try {
- const codeblockData = await fetchCodeblockData(supabase)
- const themeData = await fetchThemeData(supabase)
- const codeblockThemeData = await fetchCodeblockThemeData(supabase)
+ const codeblockData = await fetchCodeblockData(
+ SupabaseClient as SupabaseClient,
+ )
+ const themeData = await fetchThemeData(
+ SupabaseClient as SupabaseClient,
+ )
+ const codeblockThemeData = await fetchCodeblockThemeData(
+ SupabaseClient as SupabaseClient,
+ )
if (!codeblockData || !themeData || !codeblockThemeData) {
- return new Response(JSON.stringify({ error: 'No data found.' }), {
- status: 404,
- headers: { 'Content-Type': 'application/json' },
- })
+ return new Response(
+ JSON.stringify({
+ error: 'No groupedData found.',
+ codeblockData,
+ themeData,
+ codeblockThemeData,
+ }),
+ {
+ status: 404,
+ headers: { 'Content-Type': 'application/json' },
+ },
+ )
}
-
- console.log('Mapping codeblocks to themes...')
-
+ // console.log('Mapping codeblocks to themes...')
// Manually map codeblocks to themes
const groupedData = codeblockData.map((codeblock) => {
const matchingThemes = codeblockThemeData
- .filter((ct) => {
- const isMatch = ct.codeblocks_id === codeblock.id
- if (isMatch) {
- console.log(
- `Found match for codeblock ID ${codeblock.id} with theme ID ${ct.themes_id}`,
- )
- }
- return isMatch
- })
- .map((ct) => {
- const theme = themeData.find((theme) => theme.id === ct.themes_id)
- if (theme) {
- console.log(`Theme found for theme ID ${ct.themes_id}:`, theme)
- } else {
- console.warn(`No theme found for theme ID ${ct.themes_id}`)
- }
- return theme
- })
+ .filter((ct) => ct.codeblocks_id === codeblock.id)
+ .map((ct) =>
+ themeData.find(
+ (theme: GroupData['themeData']) => theme?.id === ct.themes_id,
+ ),
+ )
return {
...codeblock,
themes: matchingThemes.filter(Boolean), // Filter out undefined if no match
}
})
-
- // console.log('Final grouped data:', groupedData)
+ // console.log(JSON.stringify(groupedData, null, 3))
return new Response(
JSON.stringify({
diff --git a/apps/marketing/src/pages/dashboard.astro b/apps/marketing/src/pages/dashboard.astro
new file mode 100644
index 0000000..b9e0764
--- /dev/null
+++ b/apps/marketing/src/pages/dashboard.astro
@@ -0,0 +1,9 @@
+---
+import Layout from '@/layouts/PublicLayout.astro'
+---
+
+
+
+
Dashboard
+
+
diff --git a/apps/marketing/src/pages/docs/[pageSlug]/[groupSlug]/index.astro b/apps/marketing/src/pages/docs/[pageSlug]/[groupSlug]/index.astro
index b7908e4..df29925 100644
--- a/apps/marketing/src/pages/docs/[pageSlug]/[groupSlug]/index.astro
+++ b/apps/marketing/src/pages/docs/[pageSlug]/[groupSlug]/index.astro
@@ -51,48 +51,54 @@ const { groupData } = data
---
-
-
-
-
+
- {
- groupData.map((item, index) => (
-
- {item.block?.map((block, contentIndex) => (
-
- ))}
-
- ))
- }
-
-
-
-
+
+
+
+
diff --git a/apps/marketing/src/pages/docs/[pageSlug]/[groupSlug]/index.json.ts b/apps/marketing/src/pages/docs/[pageSlug]/[groupSlug]/index.json.ts
index 88f82ce..0d650a5 100644
--- a/apps/marketing/src/pages/docs/[pageSlug]/[groupSlug]/index.json.ts
+++ b/apps/marketing/src/pages/docs/[pageSlug]/[groupSlug]/index.json.ts
@@ -6,7 +6,6 @@ import { supabase } from '@/supabase'
type Documentation = Database['public']['Tables']['documentation']['Row']
-const supabaseClient: SupabaseClient = supabase
/**
*
* @param supabase
@@ -19,7 +18,7 @@ async function fetchData(
const response: PostgrestResponse = await supabase
.from('documentation')
.select('*, block, group!inner (group_slug,page!inner (title,slug)),group')
- .eq('group.group_slug', `${groupSlug}`)
+ .eq('group.group_slug', groupSlug ?? '')
// .limit(1)
// .single()
@@ -45,12 +44,27 @@ async function fetchData(
* Handle GET request.
* @param root0
* @param root0.params
+ * @param context
* @returns The response object.
*/
-export async function GET({ params }: APIContext) {
- const { groupSlug } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
+ const { groupSlug } = context.params
try {
- const groupData = await fetchData(supabaseClient, groupSlug)
+ const groupData = await fetchData(
+ SupabaseClient as SupabaseClient,
+ groupSlug,
+ )
if (!groupData || groupData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
@@ -62,7 +76,7 @@ export async function GET({ params }: APIContext) {
}
return new Response(
JSON.stringify({
- params,
+ params: context.params,
groupData,
fetchData,
status: 200,
diff --git a/apps/marketing/src/pages/docs/[pageSlug]/index.astro b/apps/marketing/src/pages/docs/[pageSlug]/index.astro
index 1c2bc2a..06efc16 100644
--- a/apps/marketing/src/pages/docs/[pageSlug]/index.astro
+++ b/apps/marketing/src/pages/docs/[pageSlug]/index.astro
@@ -10,150 +10,107 @@ import DocsAside from '@/components/docs-aside.astro'
import Layout from '@/layouts/PublicLayout.astro'
import { formatDate } from '@/utils/formatDate'
-import PageHeader from '../../../components/page-header.astro'
import { GET } from './index.json'
-// interface DocGroupItem {
-// id: string;
-// status: string;
-// sort: string | null;
-// user_created: string;
-// date_created: string;
-// user_updated: string;
-// date_updated: string;
-// title: string;
-// anchor_slug: string;
-// block: DocBlock[] | null;
-// group: DocGroup;
-// group_codeblocks: boolean;
-// }
-
-// interface DocBlock {
-// block_subheading: string;
-// block_content: string;
-// codeblock_filename?: string;
-// codeblock?: string | null;
-// }
-
-// interface DocGroup {
-// page: DocPage;
-// date_created: string | null;
-// date_updated: string | null;
-// group_slug: string | null;
-// id: string;
-// sort: number | null;
-// status: string;
-// title: string;
-// user_created: string | null;
-// user_updated: string | null;
-// }
-
-// interface DocPage {
-// slug: string;
-// title: string;
-// status: string;
-// }
-
-interface GroupDataItem {
+interface DocDataItem {
anchor_slug: string | null
// block: Json | null
block?: Block[]
- docData: []
block_content: Json | null
date_created: string | null
date_updated: string | null
- group: DocumentationGroup & { page: DocumentationPage }
+ group: string | null
group_codeblocks: boolean | null
id: string
sort: number | null
status: string
- title: string
+ title: string | undefined
user_created: string | null
user_updated: string | null
}
+type DocData = DocDataItem[]
+
+type Documentation = Database['public']['Tables']['documentation']['Row'] & {
+ docData: DocData
+}
// Define the types
interface Block {
block_content: string
}
-// interface GroupDataItem {
-// anchor_slug: string | null
-// block: Json | null
-// block_content: Json | null
-// date_created: string | null
-// date_updated: string | null
-// group: string | null
-// group_codeblocks: boolean | null
-// id: string
-// sort: number | null
-// status: string
-// title: string | undefined
-// user_created: string | null
-// user_updated: string | null
-// }
-// ;[]
-
-type GroupData = GroupDataItem[]
-
-type DocumentationPage =
- Database['public']['Tables']['documentation_page']['Row']
-type DocumentationGroup =
- Database['public']['Tables']['docummentation_group']['Row']
-type Documentation = Database['public']['Tables']['documentation']['Row'] & {
- docData: GroupData
-}
const response = await GET(Astro)
const data = (await response.json()) as Documentation
+const { docData } = data
---
-
-
-
-
+
-
- {
- data.docData.map((item, index) => (
- <>
-
-
{item?.title}
-
- >
- ))
- }
-
-
-
+
+
+
+
+
+
+
+
+ {
+ data.docData.map((item) => (
+ <>
+
+ {item?.title}
+
+ >
+ ))
+ }
+
+
+
+
+
diff --git a/apps/marketing/src/pages/docs/[pageSlug]/index.json.ts b/apps/marketing/src/pages/docs/[pageSlug]/index.json.ts
index 7e2168b..ca20648 100644
--- a/apps/marketing/src/pages/docs/[pageSlug]/index.json.ts
+++ b/apps/marketing/src/pages/docs/[pageSlug]/index.json.ts
@@ -6,8 +6,6 @@ import { supabase } from '@/supabase'
type Documentation = Database['public']['Tables']['documentation']['Row']
-const supabaseClient: SupabaseClient = supabase
-
/**
* Fetch flow data from the database.
* @param supabase The Supabase client.
@@ -22,7 +20,9 @@ async function fetchData(
): Promise {
const response: PostgrestResponse = await supabase
.from('documentation')
- .select('*, group!inner (page!inner (slug, sort, title), sort, id)')
+ .select(
+ '*, group!inner (page!inner (slug, sort, title,image(filename_disk),excerpt), sort, id)',
+ )
.eq('group.page.slug', pageSlug ? pageSlug : '')
.order('sort', { referencedTable: 'group', ascending: false })
@@ -56,17 +56,32 @@ async function fetchData(
* @param root0
* @param root0.params
* @param root0.request
+ * @param context
*/
-export async function GET({ params, request }: APIContext) {
- const { pageSlug } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
+ const { pageSlug } = context.params
try {
- const docData = await fetchData(supabaseClient, pageSlug)
+ const docData = await fetchData(
+ SupabaseClient as SupabaseClient,
+ pageSlug,
+ )
if (!docData || docData.length === 0) {
console.error('Data is empty or undefined')
return new Response(
JSON.stringify({
error: 'No data found.',
- path: new URL(request.url).pathname,
+ path: new URL(context.request.url).pathname,
}),
{
status: 404,
@@ -78,7 +93,7 @@ export async function GET({ params, request }: APIContext) {
}
return new Response(
JSON.stringify({
- params,
+ params: context.params,
docData,
fetchData,
status: 200,
diff --git a/apps/marketing/src/pages/docs/index.astro b/apps/marketing/src/pages/docs/index.astro
index 3fc223b..3bc5e71 100644
--- a/apps/marketing/src/pages/docs/index.astro
+++ b/apps/marketing/src/pages/docs/index.astro
@@ -15,53 +15,17 @@ import { formatDate } from '@/utils/formatDate'
import PageHeader from '../../components/page-header.astro'
import { GET } from './index.json'
-// interface DocBlock {
-// block_subheading: string
-// block_content: string
-// codeblock_filename?: string
-// codeblock?: string | null
-// }
-
-// interface DocGroupItem {
-// id: string
-// status: string
-// sort: any // Adjust type based on your data
-// user_created: string
-// date_created: string
-// user_updated: string
-// date_updated: string
-// group: {
-// page: {
-// id: string
-// slug: string
-// sort: any // Adjust type based on your data
-// title: string
-// status: string
-// date_created: string
-// date_updated: string | null
-// user_created: string
-// user_updated: string | null
-// }
-// title: string
-// }
-// title: string
-// anchor_slug: string
-// block: DocBlock[]
-// group_codeblocks: boolean
-// }
-
-// interface DocContent {
-// block: Documentation['block']
-// block_content: Documentation['block'] | Json | string[] | Json[]
-// }
-
type Documentation = Database['public']['Tables']['documentation']['Row'] & {
group: DocumentationGroup
documentationPages: DocumentationPage[]
}
type DocumentationPage =
- Database['public']['Tables']['documentation_page']['Row']
+ Database['public']['Tables']['documentation_page']['Row'] & {
+ image: {
+ filename_disk: Database['public']['Tables']['directus_files']['Row']['filename_disk']
+ }
+ }
type DocumentationGroup =
Database['public']['Tables']['docummentation_group']['Row'] & {
@@ -72,7 +36,7 @@ type DocumentationGroup =
// documentationData: DocumentationGroup
// }
-const response = await GET()
+const response = await GET(Astro)
const data = await response.json()
// @ts-ignore
@@ -85,43 +49,44 @@ const sortedPages = [...documentationPages].sort(
-
- {
- sortedPages.length > 0 ? (
- sortedPages.map((item: DocumentationPage) => (
-
- | undefined
- }
- alt='test'
- link={`/docs/${item.slug}`}
- title={item.title || 'Untitled'}
- excerpt={item.title || 'No description available'}
- date={formatDate(item.date_created) || 'Date not available'}
- />
- ))
- ) : (
- Loading...
- )
- }
+
+
+
+ {
+ sortedPages.length > 0 ? (
+ sortedPages.map((item: DocumentationPage) => (
+
+ ))
+ ) : (
+
Loading...
+ )
+ }
+
-
-
= supabase
interface Page {
slug: string
title: string
@@ -79,7 +79,10 @@ async function fetchDocumentationPages(
`
*,slug,
title,
- status
+ status,
+ image!inner(filename_disk),excerpt,
+ order_id,
+ sort
`,
)
.neq('status', 'draft')
@@ -96,11 +99,25 @@ async function fetchDocumentationPages(
* Handle GET request.
* @param root0
* @param root0.params
+ * @param context
* @returns The response object.
*/
-export async function GET() {
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
try {
- const documentationData = await fetchDocumentationData(supabaseClient)
+ const documentationData = await fetchDocumentationData(
+ SupabaseClient as SupabaseClient,
+ )
if (!documentationData || documentationData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
@@ -110,7 +127,9 @@ export async function GET() {
},
})
}
- const documentationPages = await fetchDocumentationPages(supabaseClient)
+ const documentationPages = await fetchDocumentationPages(
+ SupabaseClient as SupabaseClient,
+ )
if (!documentationPages) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
diff --git a/apps/marketing/src/pages/files/index.astro b/apps/marketing/src/pages/files/index.astro
index 9a4d0b9..3ee064e 100644
--- a/apps/marketing/src/pages/files/index.astro
+++ b/apps/marketing/src/pages/files/index.astro
@@ -8,82 +8,49 @@ import Layout from '@/layouts/PublicLayout.astro'
import PageHeader from '../../components/page-header.astro'
import { GET } from './index.json'
-const response = await GET()
+const response = await GET(Astro)
const data = (await response.json()) as any
---
-
-
- {
- data ? (
- data.fileData.map((item: any) => (
-
- ))
- ) : (
-
Loading...
- )
- }
+
+
+ {
+ data ? (
+ data.fileData.map((item: any) => (
+
+ ))
+ ) : (
+
Loading...
+ )
+ }
+
-
-
diff --git a/apps/marketing/src/pages/files/index.json.ts b/apps/marketing/src/pages/files/index.json.ts
index 26b6f8a..7daf198 100644
--- a/apps/marketing/src/pages/files/index.json.ts
+++ b/apps/marketing/src/pages/files/index.json.ts
@@ -1,5 +1,6 @@
import type { Database } from '@/database.types'
import type { PostgrestResponse, SupabaseClient } from '@supabase/supabase-js'
+import type { APIContext } from 'astro'
import { supabase } from '@/supabase'
@@ -27,7 +28,6 @@ interface FilesWithRelations {
}
}
}
-const supabaseClient: SupabaseClient = supabase
/**
* Fetch flow data from the database.
@@ -55,11 +55,25 @@ async function fetchFileData(
/**
* Handle GET request.
+ * @param context
* @returns The response object.
*/
-export async function GET() {
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
try {
- const fileData = await fetchFileData(supabaseClient)
+ const fileData = await fetchFileData(
+ SupabaseClient as SupabaseClient,
+ )
if (!fileData || fileData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
diff --git a/apps/marketing/src/pages/flows/[slug]/index.json.ts b/apps/marketing/src/pages/flows/[slug]/index.json.ts
index 34799b8..13dc97f 100644
--- a/apps/marketing/src/pages/flows/[slug]/index.json.ts
+++ b/apps/marketing/src/pages/flows/[slug]/index.json.ts
@@ -4,8 +4,6 @@ import type { APIContext } from 'astro'
import { supabase } from '@/supabase'
-const supabaseClient: SupabaseClient = supabase
-
type Nodes = Database['public']['Tables']['flows']['Row']
// type Nodes = Database['public']['Tables']['flow_nodes']['Row']
@@ -13,10 +11,22 @@ type Nodes = Database['public']['Tables']['flows']['Row']
*
* @param root0 The API context.
* @param root0.params The parameters object.
+ * @param context
* @returns The response object.
*/
-export async function GET({ params }: APIContext) {
- const { slug } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
+ const { slug } = context.params
if (typeof slug !== 'string') {
return new Response(
@@ -31,7 +41,10 @@ export async function GET({ params }: APIContext) {
}
try {
- const flowData = await fetchFlowData(supabaseClient, slug)
+ const flowData = await fetchFlowData(
+ SupabaseClient as SupabaseClient,
+ slug,
+ )
if (!flowData || flowData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
@@ -47,8 +60,7 @@ export async function GET({ params }: APIContext) {
const FlowTitle = flowItem?.title
const { data: FilterFlowNodes, error: flowNodesRelationshipError } =
- await supabase
- .from('flows_flow_nodes')
+ await SupabaseClient.from('flows_flow_nodes')
.select('flows_id,flow_nodes_id')
.eq('flows_id', FlowID ?? '')
@@ -59,8 +71,7 @@ export async function GET({ params }: APIContext) {
}
const { data: FilterFlowEdges, error: flowEdgesRelationshipError } =
- await supabase
- .from('flows_flow_edges')
+ await SupabaseClient.from('flows_flow_edges')
.select('flows_id,flow_edges_id')
.eq('flows_id', FlowID ?? '')
@@ -73,8 +84,9 @@ export async function GET({ params }: APIContext) {
const flowNodesMatch = FilterFlowNodes.map((node) => node.flow_nodes_id)
const flowEdgesMatch = FilterFlowEdges.map((node) => node.flow_edges_id)
- const { data: FlowNodes, error: nodesError } = await supabase
- .from('flow_nodes')
+ const { data: FlowNodes, error: nodesError } = await SupabaseClient.from(
+ 'flow_nodes',
+ )
.select('*,image(filename_disk)')
.in('id', flowNodesMatch)
@@ -82,8 +94,9 @@ export async function GET({ params }: APIContext) {
throw new Error(`Error fetching nodes: ${String(nodesError.message)}`)
}
- const { data: FlowEdges, error: edgesError } = await supabase
- .from('flow_edges')
+ const { data: FlowEdges, error: edgesError } = await SupabaseClient.from(
+ 'flow_edges',
+ )
.select('*,source(*),target(*)')
.in('id', flowEdgesMatch)
@@ -137,7 +150,7 @@ async function fetchFlowData(
.neq('status', 'draft')
.eq('slug', slug)
- if (response.error === null && response.data !== null) {
+ if (response.error === null) {
return response.data as unknown as Nodes[]
}
console.error(response.error)
diff --git a/apps/marketing/src/pages/flows/index.astro b/apps/marketing/src/pages/flows/index.astro
index 1bdd3b6..d939742 100644
--- a/apps/marketing/src/pages/flows/index.astro
+++ b/apps/marketing/src/pages/flows/index.astro
@@ -14,37 +14,44 @@ type FlowNodes = Database['public']['Tables']['flows']['Row']
interface FlowData {
flowData: FlowNodes[]
}
-const response = await GET()
+const response = await GET(Astro)
const data = (await response.json()) as FlowData
---
-
-
- {
- data ? (
- data.flowData.map((item: any) => (
-
- ))
- ) : (
-
Loading...
- )
- }
+
+
+
+ {
+ data ? (
+ data.flowData.map((item: any) => (
+
+ ))
+ ) : (
+
Loading...
+ )
+ }
+
diff --git a/apps/marketing/src/pages/flows/index.json.ts b/apps/marketing/src/pages/flows/index.json.ts
index e36143a..69cce39 100644
--- a/apps/marketing/src/pages/flows/index.json.ts
+++ b/apps/marketing/src/pages/flows/index.json.ts
@@ -1,12 +1,11 @@
import type { Database } from '@/database.types'
import type { PostgrestResponse, SupabaseClient } from '@supabase/supabase-js'
+import type { APIContext } from 'astro'
import { supabase } from '@/supabase'
type Nodes = Database['public']['Tables']['flows']['Row']
-const supabaseClient: SupabaseClient
= supabase
-
/**
* Fetch flow data from the database.
* @param supabase The Supabase client.
@@ -31,11 +30,25 @@ async function fetchFlowData(
/**
* Handle GET request.
+ * @param context
* @returns The response object.
*/
-export async function GET() {
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
try {
- const flowData = await fetchFlowData(supabaseClient)
+ const flowData = await fetchFlowData(
+ SupabaseClient as SupabaseClient,
+ )
if (!flowData || flowData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
diff --git a/apps/marketing/src/pages/index.astro b/apps/marketing/src/pages/index.astro
index 2dc8957..004b04c 100644
--- a/apps/marketing/src/pages/index.astro
+++ b/apps/marketing/src/pages/index.astro
@@ -1,6 +1,7 @@
---
import { AboutProdkt } from '@prodkt/ui/prodkt-components/about-prodkt'
import { HeroHeader } from '@prodkt/ui/prodkt-components/hero-header'
+import FeatureSection1 from '@prodkt/ui/prodkt-components/prodkt-features'
import Layout from '@/layouts/PublicLayout.astro'
---
@@ -17,12 +18,15 @@ import Layout from '@/layouts/PublicLayout.astro'
>
-
+
+
+
+
diff --git a/apps/marketing/src/pages/login.astro b/apps/marketing/src/pages/login.astro
new file mode 100644
index 0000000..b5ffc79
--- /dev/null
+++ b/apps/marketing/src/pages/login.astro
@@ -0,0 +1,8 @@
+---
+import { LoginSection } from '@/components/login'
+import Layout from '@/layouts/PublicLayout.astro'
+---
+
+
+
+
diff --git a/apps/marketing/src/pages/projects/[projectSlug]/[workSlug]/index.json.ts b/apps/marketing/src/pages/projects/[projectSlug]/[workSlug]/index.json.ts
index c243622..7e3ea86 100644
--- a/apps/marketing/src/pages/projects/[projectSlug]/[workSlug]/index.json.ts
+++ b/apps/marketing/src/pages/projects/[projectSlug]/[workSlug]/index.json.ts
@@ -1,23 +1,32 @@
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+/* eslint-disable jsdoc/require-param-description */
+/* eslint-disable jsdoc/check-param-names */
+
import type { Database } from '@/database.types'
import type { SupabaseClient } from '@supabase/supabase-js'
import type { APIContext } from 'astro'
+import { getSecret } from 'astro:env/server'
+
import { supabase } from '@/supabase'
-const supabaseClient: SupabaseClient = supabase
type Work = Database['public']['Tables']['work']['Row']
type Technology = Database['public']['Tables']['work_technology']['Row']
type Template = Database['public']['Tables']['work_showcase_templates']['Row']
-type TemplateFiles =
- Database['public']['Tables']['showcase_templates_files']['Row']
+// type TemplateFiles =
+// Database['public']['Tables']['showcase_templates_files']['Row']
/**
*
* @param root0 The API context.
* @param root0.params The parameters object.
+ * @param context
* @returns The response object.
*/
-export async function GET({ params }: APIContext) {
- const { projectSlug, workSlug } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+
+ const { supabase: SupabaseClient } = supabaseResult
+ const { projectSlug, workSlug } = context.params
if (typeof workSlug !== 'string') {
return new Response(
@@ -31,7 +40,10 @@ export async function GET({ params }: APIContext) {
)
}
- const workData = await fetchWorkData(supabaseClient, workSlug)
+ const workData = await fetchWorkData(
+ SupabaseClient as SupabaseClient
,
+ workSlug,
+ )
if (!workData || workData.length === 0) {
console.error('Data is empty or undefined')
@@ -45,15 +57,24 @@ export async function GET({ params }: APIContext) {
const workId = workData[0]?.id
- const technologyData = await fetchTechnologyData(supabaseClient, workId)
- const templateData = await fetchTemplateData(supabaseClient, workId)
+ const technologyData = await fetchTechnologyData(
+ SupabaseClient as SupabaseClient,
+ workId,
+ )
+ const templateData = await fetchTemplateData(
+ SupabaseClient as SupabaseClient,
+ workId,
+ )
// Extract all templateIds from templateData
const templateIds =
templateData?.map((template) => template.showcase_templates_id) ?? []
// Fetch template files using the extracted templateIds
- const templateFiles = await fetchTemplateFiles(supabaseClient, templateIds)
+ const templateFiles = await fetchTemplateFiles(
+ SupabaseClient as SupabaseClient,
+ templateIds,
+ )
return new Response(
JSON.stringify({
@@ -82,20 +103,31 @@ async function fetchWorkData(
supabase: SupabaseClient,
workSlug: string,
): Promise {
- const response = await supabase
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ // Start building the query
+ let query = supabase
.from('work')
.select(
`
- *,project(logo(filename_disk),name,slug),primary_image(filename_disk)
- )
- `,
+ *,project(logo(filename_disk),name,slug),primary_image(filename_disk)
+ `,
)
- .neq('status', 'draft')
.eq('slug', workSlug)
- if (response.error === null && response.data !== null) {
- return response.data as unknown as Work[]
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ // console.log('Excluding drafts from query.')
+ query = query.neq('status', 'draft')
+ }
+
+ const response = await query
+
+ if (response.error === null) {
+ return response.data
}
+
console.error(response.error)
return null
}
@@ -111,19 +143,31 @@ async function fetchTechnologyData(
supabase: SupabaseClient,
workId: string | undefined,
): Promise {
- const response = await supabase
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ // Start building the query
+ let query = supabase
.from('work_technology')
.select(
`
- *,work_id,technology_id(name,logo(filename_disk))
- )
- `,
+ *,work_id,technology_id(name,logo(filename_disk))
+ `,
)
.eq('work_id', workId)
- if (response.error === null && response.data !== null) {
- return response.data as unknown as Technology[]
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ console.log('Excluding drafts from query.')
+ query = query.neq('status', 'draft')
+ }
+
+ const response = await query
+
+ if (response.error === null) {
+ return response.data
}
+
console.error(response.error)
return null
}
@@ -138,19 +182,31 @@ async function fetchTemplateData(
supabase: SupabaseClient,
workId: string | undefined,
): Promise {
- const response = await supabase
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ // Start building the query
+ let query = supabase
.from('work_showcase_templates')
.select(
`
- *
- )
- `,
+ *
+ `,
)
.eq('work_id', workId)
- if (response.error === null && response.data !== null) {
- return response.data as unknown as Template[]
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ console.log('Excluding drafts from query.')
+ query = query.neq('status', 'draft')
+ }
+
+ const response = await query
+
+ if (response.error === null) {
+ return response.data
}
+
console.error(response.error)
return null
}
@@ -164,28 +220,33 @@ async function fetchTemplateData(
async function fetchTemplateFiles(
supabase: SupabaseClient,
templateIds: (string | null | undefined)[],
-): Promise {
- // Filter out null or undefined IDs
+): Promise {
const validTemplateIds = templateIds.filter((id): id is string => !!id)
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
- if (validTemplateIds.length === 0) {
- console.error('No valid templateIds provided')
- return null
- }
-
- const response = await supabase
+ // Start building the query
+ let query = supabase
.from('showcase_templates_files')
.select(
`
- template:showcase_templates_id(title,type),directus_files_id(filename_disk)
- )
- `,
+ template:showcase_templates_id(title,type),directus_files_id(filename_disk)
+ `,
)
.in('showcase_templates_id', validTemplateIds)
- if (response.error === null && response.data !== null) {
- return response.data as unknown as TemplateFiles[]
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ console.log('Excluding drafts from query.')
+ query = query.neq('status', 'draft')
}
+
+ const response = await query
+
+ if (response.error === null) {
+ return response.data
+ }
+
console.error(response.error)
return null
}
diff --git a/apps/marketing/src/pages/projects/[projectSlug]/index.astro b/apps/marketing/src/pages/projects/[projectSlug]/index.astro
index 18f6886..c3132ca 100644
--- a/apps/marketing/src/pages/projects/[projectSlug]/index.astro
+++ b/apps/marketing/src/pages/projects/[projectSlug]/index.astro
@@ -13,21 +13,18 @@ import { GET } from './index.json'
type Roadmap = Database['public']['Tables']['roadmaps']['Row']
type Project = Database['public']['Tables']['projects']['Row']
type Files = Database['public']['Tables']['directus_files']['Row']
-type Issue = Database['public']['Tables']['issues']['Row']
-type Status = Database['public']['Tables']['status']['Row'] & { tasks: Issue[] } // Ensure Status includes tasks
-type Column = {
- id: string
- color: string
- label: string
- value: string
- tasks: Issue[]
+type Issue = Database['public']['Tables']['issues']['Row'] & {
+ status: Status
}
+type Status = Database['public']['Tables']['status']['Row'] & { tasks: Issue[] } // Ensure Status includes tasks
+
interface ProjectData {
projectSlug?: string
roadmapSlug?: string
roadmapData?: Roadmap[]
projectData: Project[]
issueData: Issue[]
+ tasks: Issue[]
projectListing: ProjectList[]
projectTitle: string | null
logo: Files['filename_disk']
@@ -38,36 +35,36 @@ interface ProjectData {
const response = await GET(Astro)
const data = (await response.json()) as ProjectData
-// Group tasks by their status label
-const columnsData = data.issueData.reduce>(
- (acc, task) => {
- const status = task.status // Ensure status is correctly typed
- // @ts-ignore
- const columnKey = status.label || 'Unknown' // Group by status label
-
- if (!acc[columnKey]) {
- acc[columnKey] = []
- }
+const issueData = data.issueData // Access your issue data from the data object
- acc[columnKey].push(task)
- return acc
- },
- {},
-)
+// Group issues by their status label
+const columnsData = issueData.reduce>((acc, issue) => {
+ const statusLabel = issue.status?.label ?? 'Unknown' // Use the status label for grouping, default to 'Unknown'
+ if (!acc[statusLabel]) {
+ acc[statusLabel] = []
+ }
+ acc[statusLabel].push(issue)
+ return acc
+}, {})
// Transform grouped tasks into the format for BoardColumn
-const columns: Column[] = Object.entries(columnsData).map(([label, tasks]) => {
- // @ts-ignore
- const exampleStatus = tasks[0]?.status as Status
-
+const columns = Object.entries(columnsData).map(([label, tasks]) => {
return {
- id: exampleStatus?.id || `unknown-${label}`,
- color: exampleStatus?.color || 'default-color',
- label: exampleStatus?.label || 'No Label',
- value: exampleStatus?.value || 'no-value',
+ id: tasks[0]?.status.id || `unknown-${label}`, // Use the first task's status id
+ color: tasks[0]?.status.color ?? 'default-color', // Use the first task's status color
+ label, // The label is the status label (e.g., "Backlog", "Todo")
tasks, // Pass the tasks to the column object
+ value: label,
}
})
+
+// Define the desired order of the columns
+const desiredOrder = ['Backlog', 'Todo', 'In Progress', 'Done']
+
+// Sort the columns based on the desired order
+const orderedColumns = columns.sort((a, b) => {
+ return desiredOrder.indexOf(a.value) - desiredOrder.indexOf(b.value)
+})
---
@@ -88,10 +85,10 @@ const columns: Column[] = Object.entries(columnsData).map(([label, tasks]) => {
client:only='react'
>
{
- columns.map((column) => (
+ orderedColumns.map((column) => (
diff --git a/apps/marketing/src/pages/projects/[projectSlug]/index.json.ts b/apps/marketing/src/pages/projects/[projectSlug]/index.json.ts
index c81de70..28ef359 100644
--- a/apps/marketing/src/pages/projects/[projectSlug]/index.json.ts
+++ b/apps/marketing/src/pages/projects/[projectSlug]/index.json.ts
@@ -4,17 +4,20 @@ import type { APIContext } from 'astro'
import { supabase } from '@/supabase'
-const supabaseClient: SupabaseClient = supabase
type Project = Database['public']['Tables']['projects']['Row']
type ProjectIssues = Database['public']['Tables']['issues']['Row']
/**
*
* @param root0 The API context.
* @param root0.params The parameters object.
+ * @param context
* @returns The response object.
*/
-export async function GET({ params }: APIContext) {
- const { projectSlug } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+
+ const { supabase: SupabaseClient } = supabaseResult
+ const { projectSlug } = context.params
if (typeof projectSlug !== 'string') {
return new Response(
@@ -28,7 +31,7 @@ export async function GET({ params }: APIContext) {
)
}
- const projectData = await fetchProjectData(supabaseClient, projectSlug)
+ const projectData = await fetchProjectData(SupabaseClient, projectSlug)
if (!projectData || projectData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
@@ -41,24 +44,13 @@ export async function GET({ params }: APIContext) {
const projectId = projectData[0]?.id
- // const roadmapData = await fetchRoadmapData(supabaseClient, projectId)
-
- const projectListing = await fetchAllProjects(supabaseClient)
- const issueData = await fetchIssueData(supabaseClient, projectId)
-
- // if (!roadmapData || roadmapData.length === 0) {
- // // console.error('Data is empty or undefined')
- // return new Response(JSON.stringify({ error: 'No data found.' }), {
- // status: 200,
- // headers: {
- // 'Content-Type': 'application/json',
- // },
- // })
- // }
+ const projectListing = await fetchAllProjects(SupabaseClient)
+ const issueData = await fetchIssueData(SupabaseClient, projectId)
return new Response(
JSON.stringify({
- params,
+ context,
+ projectSlug,
projectData,
issueData,
projectListing,
@@ -129,29 +121,6 @@ async function fetchIssueData(
return null
}
-/**
- *
- * @param supabase The Supabase client.
- * @param projectId The project ID.
- * @returns The flow data.
- */
-// async function fetchRoadmapData(
-// supabase: SupabaseClient,
-// projectId: string | undefined,
-// ): Promise {
-// const response = await supabase
-// .from('roadmaps')
-// .select('*,projects_id,slug,title,status')
-// .neq('status', 'draft')
-// .eq('projects_id', projectId)
-
-// if (response.error === null) {
-// return response.data as unknown as Roadmap[]
-// }
-// console.error(response.error)
-// return null
-// }
-
/**
*
* @param supabase The Supabase client.
diff --git a/apps/marketing/src/pages/projects/index.astro b/apps/marketing/src/pages/projects/index.astro
index 457f7d8..9abf487 100644
--- a/apps/marketing/src/pages/projects/index.astro
+++ b/apps/marketing/src/pages/projects/index.astro
@@ -16,37 +16,44 @@ interface ProjectData {
projectData: Project[]
}
-const response = await GET()
+const response = await GET(Astro)
const data = (await response.json()) as ProjectData
---
-
-
- {
- data ? (
- data.projectData.map((item: any) => (
-
- ))
- ) : (
-
Loading...
- )
- }
+
+
+
+ {
+ data ? (
+ data.projectData.map((item: any) => (
+
+ ))
+ ) : (
+
Loading...
+ )
+ }
+
diff --git a/apps/marketing/src/pages/projects/index.json.ts b/apps/marketing/src/pages/projects/index.json.ts
index 5b285a5..746b3e0 100644
--- a/apps/marketing/src/pages/projects/index.json.ts
+++ b/apps/marketing/src/pages/projects/index.json.ts
@@ -1,12 +1,13 @@
import type { Database } from '@/database.types'
-import type { PostgrestResponse, SupabaseClient } from '@supabase/supabase-js'
+import type { SupabaseClient } from '@supabase/supabase-js'
+import type { APIContext } from 'astro'
+
+import { getSecret } from 'astro:env/server'
import { supabase } from '@/supabase'
type Project = Database['public']['Tables']['projects']['Row']
-const supabaseClient: SupabaseClient
= supabase
-
/**
* Fetch flow data from the database.
* @param supabase The Supabase client.
@@ -15,16 +16,32 @@ const supabaseClient: SupabaseClient = supabase
async function fetchProjectData(
supabase: SupabaseClient,
): Promise {
- const response: PostgrestResponse = await supabase
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ // console.log('isDevMode:', isDevMode)
+
+ // Start building the query
+ let query = supabase
.from('projects')
.select(
- '*,primary_image(filename_disk),slug,workspace(*),brand_color_primary',
+ '*,primary_image(filename_disk),slug,workspace(*),brand_color_primary,icon:logos!inner(logomark_backgroundFill!inner(filename_disk))',
)
- .neq('status', 'draft')
- // Type guard to check if response.error exists
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ // console.log('Excluding drafts from query.')
+ query = query.neq('status', 'draft')
+ }
+
+ const response = await query
+
+ // Log the response to see what is returned
+ // console.log('Response received:', response)
+
+ // Check for errors
if (response.error) {
- console.error(response.error)
+ console.error('Error fetching articles:', response.error)
return null
}
@@ -33,11 +50,25 @@ async function fetchProjectData(
/**
* Handle GET request.
+ * @param context
* @returns The response object.
*/
-export async function GET() {
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
try {
- const projectData = await fetchProjectData(supabaseClient)
+ const projectData = await fetchProjectData(
+ SupabaseClient as SupabaseClient,
+ )
if (!projectData || projectData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
diff --git a/apps/marketing/src/pages/repos/[namespace]/[path]/index.astro b/apps/marketing/src/pages/repos/[namespace]/[path]/index.astro
index dc16d6d..a83bd27 100644
--- a/apps/marketing/src/pages/repos/[namespace]/[path]/index.astro
+++ b/apps/marketing/src/pages/repos/[namespace]/[path]/index.astro
@@ -25,7 +25,9 @@ const data = (await response.json()) as RepoData
bullet3='Visuals'
bullet4='Concepts'
/>
-
+
{data.repo.repoData[0]?.title}
diff --git a/apps/marketing/src/pages/repos/[namespace]/[path]/index.json.ts b/apps/marketing/src/pages/repos/[namespace]/[path]/index.json.ts
index 1860083..8e67a22 100644
--- a/apps/marketing/src/pages/repos/[namespace]/[path]/index.json.ts
+++ b/apps/marketing/src/pages/repos/[namespace]/[path]/index.json.ts
@@ -6,19 +6,31 @@ import { supabase } from '@/supabase'
type Repos = Database['public']['Tables']['repos']['Row']
-const supabaseClient: SupabaseClient
= supabase
-
/**
*
* @param root0
* @param root0.params
+ * @param context
*/
-export async function GET({ params }: APIContext) {
- const { namespace, path } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
+ const { namespace, path } = context.params
try {
// Fetch all repos from Supabase
- const repoData = await fetchRepoData(supabaseClient)
+ const repoData = await fetchRepoData(
+ SupabaseClient as SupabaseClient,
+ )
if (!repoData || repoData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
@@ -42,7 +54,7 @@ export async function GET({ params }: APIContext) {
// Return the matched repo along with the GitLab data
return new Response(
JSON.stringify({
- params,
+ params: context.params,
repo: { gitLabRepo, repoData },
status: 200,
}),
diff --git a/apps/marketing/src/pages/repos/[namespace]/index.astro b/apps/marketing/src/pages/repos/[namespace]/index.astro
index 234e735..3aa6b70 100644
--- a/apps/marketing/src/pages/repos/[namespace]/index.astro
+++ b/apps/marketing/src/pages/repos/[namespace]/index.astro
@@ -26,7 +26,9 @@ const data = (await response.json()) as RepoData
bullet3='Visuals'
bullet4='Concepts'
/>
-
+
{
data ? (
data.repos.map((repo: any) => (
diff --git a/apps/marketing/src/pages/repos/[namespace]/index.json.ts b/apps/marketing/src/pages/repos/[namespace]/index.json.ts
index 2a9449e..0e382a9 100644
--- a/apps/marketing/src/pages/repos/[namespace]/index.json.ts
+++ b/apps/marketing/src/pages/repos/[namespace]/index.json.ts
@@ -1,3 +1,8 @@
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+/* eslint-disable jsdoc/require-returns */
+/* eslint-disable jsdoc/check-param-names */
+/* eslint-disable jsdoc/require-param-description */
+
import type { Database } from '@/database.types'
import type { PostgrestResponse, SupabaseClient } from '@supabase/supabase-js'
import type { APIContext } from 'astro'
@@ -6,18 +11,22 @@ import { supabase } from '@/supabase'
type Repos = Database['public']['Tables']['repos']['Row']
-const supabaseClient: SupabaseClient
= supabase
-
/**
*
* @param root0
* @param root0.params
+ * @param context
*/
-export async function GET({ params }: APIContext) {
- // const { namespace } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+
+ const { supabase: SupabaseClient } = supabaseResult
+ // const { namespace } = context.params
try {
- const repoData = await fetchRepoData(supabaseClient)
+ const repoData = await fetchRepoData(
+ SupabaseClient as SupabaseClient,
+ )
if (!repoData || repoData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
@@ -44,7 +53,7 @@ export async function GET({ params }: APIContext) {
return new Response(
JSON.stringify({
- params,
+ params: context.params,
repos,
status: 200,
}),
diff --git a/apps/marketing/src/pages/repos/index.astro b/apps/marketing/src/pages/repos/index.astro
index 0469225..23065ff 100644
--- a/apps/marketing/src/pages/repos/index.astro
+++ b/apps/marketing/src/pages/repos/index.astro
@@ -19,32 +19,39 @@ const data = (await response.json()) as RepoData
---
-
-
- {
- data ? (
- data.repos.map((repo: any) => (
-
- ))
- ) : (
-
Loading...
- )
- }
+
+
+
+ {
+ data ? (
+ data.repos.map((repo: any) => (
+
+ ))
+ ) : (
+
Loading...
+ )
+ }
+
diff --git a/apps/marketing/src/pages/repos/index.json.ts b/apps/marketing/src/pages/repos/index.json.ts
index 17fb9ca..98282a8 100644
--- a/apps/marketing/src/pages/repos/index.json.ts
+++ b/apps/marketing/src/pages/repos/index.json.ts
@@ -6,16 +6,28 @@ import { supabase } from '@/supabase'
type Repos = Database['public']['Tables']['repos']['Row']
-const supabaseClient: SupabaseClient
= supabase
-
/**
*
* @param root0
* @param root0.params
+ * @param context
*/
-export async function GET({ params }: APIContext) {
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
try {
- const repoData = await fetchRepoData(supabaseClient)
+ const repoData = await fetchRepoData(
+ SupabaseClient as SupabaseClient,
+ )
if (!repoData || repoData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
@@ -40,7 +52,7 @@ export async function GET({ params }: APIContext) {
}
})
- const { namespace } = params
+ const { namespace } = context.params
return new Response(
JSON.stringify({
diff --git a/apps/marketing/src/pages/signup.astro b/apps/marketing/src/pages/signup.astro
new file mode 100644
index 0000000..fb4c9e3
--- /dev/null
+++ b/apps/marketing/src/pages/signup.astro
@@ -0,0 +1,8 @@
+---
+import { RegisterSection } from '@/components/signup'
+import Layout from '@/layouts/PublicLayout.astro'
+---
+
+
+
+
diff --git a/apps/marketing/src/pages/work-history/index.astro b/apps/marketing/src/pages/work-history/index.astro
new file mode 100644
index 0000000..1ecc8ab
--- /dev/null
+++ b/apps/marketing/src/pages/work-history/index.astro
@@ -0,0 +1,13 @@
+---
+import { BryanFunkSection } from '@prodkt/ui/prodkt-components/about-bryan'
+
+import ResumeSection from '@/components/download-resume'
+import { WorkHistory } from '@/components/work-history'
+import Layout from '@/layouts/PublicLayout.astro'
+---
+
+
+
+
+
+
diff --git a/apps/marketing/src/pages/work/[projectSlug]/[workSlug]/index.astro b/apps/marketing/src/pages/work/[projectSlug]/[workSlug]/index.astro
index 608be82..9b9a86e 100644
--- a/apps/marketing/src/pages/work/[projectSlug]/[workSlug]/index.astro
+++ b/apps/marketing/src/pages/work/[projectSlug]/[workSlug]/index.astro
@@ -16,10 +16,6 @@ import Layout from '@/layouts/PublicLayout.astro'
import { GET } from './index.json'
-// type DiskFiles = {
-// filename_disk?: string
-// }
-
type TechnologyTypes = Database['public']['Tables']['technology']['Row'] & {
logo: {
filename_disk: string
@@ -34,338 +30,249 @@ type TechnologyTypes = Database['public']['Tables']['technology']['Row'] & {
// other properties...
id: string
name: string | undefined
- 'client:only'?: string // Optional if applicable
+ // 'client:only'?: string // Optional if applicable
}
id: string | undefined
name: string
}
}
-// interface LogoTypes {
-// date_created: string | null
-// date_updated: string | null
-// id: string
-// logo: TechnologyTypes['logo']
-// logo_onDark: TechnologyTypes['logo']
-// logomark: string | null
-// logomark_3dWireframe: string | null
-// logomark_3dWireframe_onDark: string | null
-// logomark_backgroundFill: string | null
-// logomark_backgroundFill_onDark: string | null
-// logomark_onDark: string | null
-// logotype: string | null
-// logotype_onDark: string | null
-// sort: number | null
-// title: string | null
-// user_created: string | null
-// user_updated: string | null
-// }
-
-// interface ProjectTypes {
-// base_type: string | null
-// base_type_sample: DiskFiles
-// brand_color_primary: string | null
-// code_type: string | null
-// code_type_sample: DiskFiles
-// component_animatedLogo_stroked: string | null
-// componentPath_animatedLogo_stroked: string | null
-// content_block: string | null
-// date_created: string | null
-// date_updated: string | null
-// excerpt: string | null
-// expressive_type: string | null
-// expressive_type_sample: DiskFiles
-// icon_radius: string | null
-// id: string
-// link_behance: string | null
-// link_dribbble: string | null
-// link_github: string | null
-// link_gitlab: string | null
-// link_instagram: string | null
-// logo: DiskFiles
-// logo_3d: DiskFiles
-// logo_creative: DiskFiles
-// logo_type: string | null
-// logo_type_sample: DiskFiles
-// logo_wireframe: DiskFiles
-// og_image: string | null
-// primary_image: string | null
-// public: boolean | null
-// slug: string
-// sort: number | null
-// status: string | null
-// title: string | null
-// user_created: string | null
-// user_updated: string | null
-// workspace: string | null
-// logos: LogoTypes
-// }
-// type Work = Database['public']['Tables']['work']['Row']
-// interface Project {
-// project: ProjectTypes
-// }
-// type TemplateFiles =
-// Database['public']['Tables']['showcase_templates_files']['Row']
-// // type WorkWithProjects = QueryData
-
-// interface WorkData {
-// projectSlug: string
-// workSlug: string
-// link_behance: ProjectTypes[]
-// link_dribbble: ProjectTypes[]
-// link_instagram: ProjectTypes[]
-// logos: ProjectTypes['logos']
-// workData: Work[] & Project[]
-// technologyData: TechnologyTypes[]
-// templateFiles: TemplateFiles
-// projectData: Project
-// ProjectDesignTokens: Token[]
-// is_brand_showcase?: boolean
-// }
-// ;[]
const response = await GET(Astro)
-const data = await response.json()
-const workWithProjects = data as unknown as any
-console.log(workWithProjects)
-const ProjectLogo =
- workWithProjects.workData[0]?.project?.logos.logo?.filename_disk
-const ProjectLogoOnDark =
- workWithProjects.workData[0]?.project?.logos.logo_onDark?.filename_disk
+// biome-ignore lint/suspicious/noExplicitAny:
+const workData = (await response.json()) as any
+
+// const ProjectLogo = workData.project?.logos?.logo.filename_disk
+// const ProjectLogoOnDark = workData.project?.logo_onDark?.filename_disk
// console.log(ProjectLogo)
-const link_behance = workWithProjects.workData[0]?.link_behance
-const link_dribbble = workWithProjects.workData[0]?.link_dribbble
-const link_instagram = workWithProjects.workData[0]?.link_instagram
+const link_behance = workData?.link_behance
+const link_dribbble = workData?.link_dribbble
+const link_instagram = workData?.link_instagram
-const brandingShowcase =
- workWithProjects.workData[0]?.is_brand_showcase === true
+const brandingShowcase = workData?.workData[0].is_brand_showcase === true
-const WorkProject = workWithProjects.workData[0]?.project.title
-// const ProjectLogo = workWithProjects.workData?.logo?.filename_disk
+const WorkProject = workData?.workData[0].project?.title
const ProjectLogoWireframe =
- workWithProjects.workData[0]?.project.logo_wireframe?.filename_disk
-const ProjectLogo3d =
- workWithProjects.workData[0]?.project.logo_3d?.filename_disk
+ workData?.workData[0].project?.logo_wireframe?.filename_disk
+const ProjectLogo3d = workData?.workData[0].project?.logo_3d?.filename_disk
const ProjectLogoCreative =
- workWithProjects.workData[0]?.project.logo_creative?.filename_disk
+ workData?.workData[0].project?.logo_creative?.filename_disk
const ProjectAnimatedLogo =
- workWithProjects.workData[0]?.project.component_animatedLogo_stroked
-const ProjectLogoType = workWithProjects.workData[0]?.project.logo_type
-const ProjectBaseType = workWithProjects.workData[0]?.project.base_type
-const ProjectExpressiveType =
- workWithProjects.workData[0]?.project.expressive_type
-const ProjectCodeType = workWithProjects.workData[0]?.project.code_type
+ workData?.workData[0].project?.component_animatedLogo_stroked
+const ProjectLogoType = workData?.workData[0].project?.logo_type
+const ProjectBaseType = workData?.workData[0].project?.base_type
+const ProjectExpressiveType = workData?.workData[0].project?.expressive_type
+const ProjectCodeType = workData?.workData[0].project?.code_type
const ProjectLogoTypeSample =
- workWithProjects.workData[0]?.project.logo_type_sample?.filename_disk
+ workData?.workData[0].project?.logo_type_sample?.filename_disk
const ProjectBaseTypeSample =
- workWithProjects.workData[0]?.project.base_type_sample?.filename_disk
+ workData?.workData[0].project?.base_type_sample?.filename_disk
const ProjectExpressiveTypeSample =
- workWithProjects.workData[0]?.project.expressive_type_sample?.filename_disk
+ workData?.workData[0].project?.expressive_type_sample?.filename_disk
const ProjectCodeTypeSample =
- workWithProjects.workData[0]?.project.code_type_sample?.filename_disk
+ workData?.workData[0].project?.code_type_sample?.filename_disk
---
-
- {
- brandingShowcase ? (
- <>
- {/* @ts-ignore */}
-
-
-
- >
- ) : null
- }
- {
- workWithProjects.templateFiles && brandingShowcase === false ? (
- <>
- {/* @ts-ignore */}
-
- >
- ) : null
- }
-
+
+
+ {
+ brandingShowcase ? (
+ <>
+ {/* @ts-ignore */}
+
+
+
+ >
+ ) : null
+ }
+ {
+ workData?.templateFiles && brandingShowcase === false ? (
+ <>
+ {/* @ts-ignore */}
+
+ >
+ ) : null
+ }
-

-

-
-
-
-
- {workWithProjects.workData[0]?.title}
-
-
-
-
-
- Technology
-
-
- {
- workWithProjects.technologyData.map(
- (techItem: TechnologyTypes) => {
- // const logo = techItem.technology_id?.logo
- // const logo = techItem.technology_id;
- if (techItem) {
- return (
-
- )
- } else {
- console.warn(
- 'Missing technology or logo in item:',
- techItem,
- )
- return null
- }
- },
- )
- }
+
+
+ {workData?.workData[0].title}
+
-
-
- {
- (link_behance ?? link_dribbble ?? link_instagram) ? (
- <>
-
- External Showcase
-
-
-
-
- {link_dribbble ? (
-
-
-
- ) : null}
- {link_behance ? (
-
-
-
- ) : null}
- {link_instagram ? (
-
-
-
- ) : null}
+
+
+
+
+ Technology
+
+
+ {
+ workData?.technologyData?.map(
+ (techItem: TechnologyTypes) => {
+ if (techItem) {
+ return (
+
+ )
+ } else {
+ console.warn(
+ 'Missing technology or logo in item:',
+ techItem,
+ )
+ return null
+ }
+ },
+ )
+ }
+
+
+
+ {
+ (link_behance ?? link_dribbble ?? link_instagram) ? (
+ <>
+
+ External Showcase
+
+
+
+
+ {link_dribbble ? (
+
+
+
+ ) : null}
+ {link_behance ? (
+
+
+
+ ) : null}
+ {link_instagram ? (
+
+
+
+ ) : null}
+
+
-
-
- >
- ) : null
- }
-
-
-
+ ) : null
+ }
+
+
+
- Description
-
-
-
+
+ Description
+
+
+
+
diff --git a/apps/marketing/src/pages/work/[projectSlug]/[workSlug]/index.json.ts b/apps/marketing/src/pages/work/[projectSlug]/[workSlug]/index.json.ts
index 241997c..2a480f9 100644
--- a/apps/marketing/src/pages/work/[projectSlug]/[workSlug]/index.json.ts
+++ b/apps/marketing/src/pages/work/[projectSlug]/[workSlug]/index.json.ts
@@ -1,27 +1,36 @@
+/* eslint-disable jsdoc/check-param-names */
+/* eslint-disable jsdoc/require-returns */
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
/* eslint-disable jsdoc/require-param-description */
import type { Database } from '@/database.types'
-import type { QueryData, SupabaseClient } from '@supabase/supabase-js'
+import type { SupabaseClient } from '@supabase/supabase-js'
import type { APIContext } from 'astro'
-import { supabase } from '@/supabase'
+import { getSecret } from 'astro:env/server'
-// import { type WorkShowcaseProps } from '@/types.d'
+import { supabase } from '@/supabase'
-const supabaseClient: SupabaseClient = supabase
-type Work = Database['public']['Tables']['work']['Row']
-type Technology = Database['public']['Tables']['work_technology']['Row']
-type Template = Database['public']['Tables']['work_showcase_templates']['Row']
-type TemplateFiles =
- Database['public']['Tables']['showcase_templates_files']['Row']
/**
*
* @param root0 The API context.
* @param root0.params The parameters object.
+ * @param context
* @returns The response object.
*/
-export async function GET({ params }: APIContext) {
- const { projectSlug, workSlug } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
+ const { projectSlug, workSlug } = context.params
if (typeof workSlug !== 'string') {
return new Response(
@@ -35,7 +44,10 @@ export async function GET({ params }: APIContext) {
)
}
- const workData = await fetchWorkData(supabaseClient, workSlug)
+ const workData = await fetchWorkData(
+ SupabaseClient as SupabaseClient
,
+ workSlug,
+ )
if (!workData || workData.length === 0) {
console.error('Data is empty or undefined')
@@ -46,37 +58,32 @@ export async function GET({ params }: APIContext) {
},
})
}
-
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-expect-error
const workId = workData[0]?.id
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const ProjectId = workData[0]?.project?.id
- // const tokenData = await fetchTokenData(supabaseClient)
- // if (!tokenData || tokenData.length === 0) {
- // console.error('Design Tokens are empty or undefined')
- // return new Response(JSON.stringify({ error: 'No design tokens found.' }), {
- // status: 404,
- // headers: {
- // 'Content-Type': 'application/json',
- // },
- // })
- // }
-
- const technologyData = await fetchTechnologyData(supabaseClient, workId)
- const templateData = await fetchTemplateData(supabaseClient, workId)
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
+ const technologyData = await fetchTechnologyData(SupabaseClient, workId)
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
+ const templateData = await fetchTemplateData(SupabaseClient, workId)
// Extract all templateIds from templateData
const templateIds =
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-expect-error
templateData?.map((template) => template.showcase_templates_id) ?? []
// Fetch template files using the extracted templateIds
- const templateFiles = await fetchTemplateFiles(supabaseClient, templateIds)
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
+ const templateFiles = await fetchTemplateFiles(SupabaseClient, templateIds)
- const { data: FilteredTokens, error: tokensError } = await supabase
- .from('projects_design_tokens')
- .select('projects_id,design_tokens_id!inner(*,id,title,palettes_json)')
- .eq('projects_id', ProjectId)
+ const { data: FilteredTokens, error: tokensError } =
+ await SupabaseClient.from('projects_design_tokens')
+ .select('projects_id,design_tokens_id!inner(*,id,title,palettes_json)')
+ .eq('projects_id', ProjectId)
// type ProjectDesignTokenTypes = QueryData['design_tokens_id'];
// type DesignTokenTypes = QueryData['palettes_json'];
@@ -86,7 +93,7 @@ export async function GET({ params }: APIContext) {
)
}
- console.log(FilteredTokens)
+ // console.log(FilteredTokens)
const ProjectDesignTokens = FilteredTokens.map(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -113,30 +120,44 @@ export async function GET({ params }: APIContext) {
/**
*
- * @param supabase The Supabase client.
- * @param workSlug The work slug.
- * @returns A promise that resolves to an array of work data or null.
+ * @param supabaseClient
+ * @param workSlug
*/
async function fetchWorkData(
- supabase: SupabaseClient,
+ supabaseClient: SupabaseClient,
workSlug: string,
-): Promise {
- const response = await supabase
+) {
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ let query = supabaseClient
.from('work')
.select(
`
- *,content_block,project(*,id,logos(logo(filename_disk),logo_onDark(filename_disk)),logo_3d(filename_disk),logo_wireframe(filename_disk),logo_creative(filename_disk),base_type,base_type_sample(filename_disk),code_type,code_type_sample(filename_disk),logo_type,logo_type_sample(filename_disk),expressive_type,expressive_type_sample(filename_disk))
- )
- `,
+*,content_block,project(*,id,logos(logo(filename_disk),logo_onDark(filename_disk)),logo_3d(filename_disk),logo_wireframe(filename_disk),logo_creative(filename_disk),base_type,base_type_sample(filename_disk),code_type,code_type_sample(filename_disk),logo_type,logo_type_sample(filename_disk),expressive_type,expressive_type_sample(filename_disk))
+)
+`,
)
- .neq('status', 'draft')
.eq('slug', workSlug)
- type WorkTypes = QueryData
- if (response.error === null) {
- return response.data as unknown as WorkTypes[]
+
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ // console.log('Excluding drafts from query.')
+ query = query.neq('status', 'draft')
}
- console.error(response.error)
- return null
+
+ const response = await query
+
+ // Log the response to see what is returned
+ // console.log('Response received:', response)
+
+ // Check for errors
+ if (response.error) {
+ console.error('Error fetching articles:', response.error)
+ return null
+ }
+
+ return response.data
}
/**
@@ -148,8 +169,8 @@ async function fetchWorkData(
*/
async function fetchTechnologyData(
supabase: SupabaseClient,
- workId: string | undefined,
-): Promise {
+ workId: string | null,
+) {
const response = await supabase
.from('work_technology')
.select(
@@ -159,10 +180,9 @@ async function fetchTechnologyData(
`,
)
.eq('work_id', workId)
- type TechnologyTypes = QueryData
if (response.error === null) {
- return response.data as TechnologyTypes[]
+ return response.data
}
console.error(response.error)
return null
@@ -177,7 +197,7 @@ async function fetchTechnologyData(
async function fetchTemplateData(
supabase: SupabaseClient,
workId: string | undefined,
-): Promise {
+) {
const response = await supabase
.from('work_showcase_templates')
.select(
@@ -187,10 +207,9 @@ async function fetchTemplateData(
`,
)
.eq('work_id', workId)
- type TemplateTypes = QueryData
if (response.error === null) {
- return response.data as unknown as TemplateTypes[]
+ return response.data
}
console.error(response.error)
return null
@@ -205,7 +224,7 @@ async function fetchTemplateData(
async function fetchTemplateFiles(
supabase: SupabaseClient,
templateIds: (string | null | undefined)[],
-): Promise {
+) {
// Filter out null or undefined IDs
const validTemplateIds = templateIds.filter((id): id is string => !!id)
@@ -223,43 +242,10 @@ async function fetchTemplateFiles(
`,
)
.in('showcase_templates_id', validTemplateIds)
- type TemplateFileTypes = QueryData
if (response.error === null) {
- return response.data as unknown as TemplateFileTypes[]
+ return response.data
}
console.error(response.error)
return null
}
-
-/* START DESIGN TOKENS */
-/**
- *
- * @param supabase
- */
-// async function fetchTokenData(supabase: SupabaseClient) {
-// const response = await supabase.from('design_tokens').select(`
-// *, title, palettes_json
-// `)
-// type TokenTypes = QueryData
-
-// if (response.error === null) {
-// return response.data as unknown as TokenTypes
-// } else {
-// console.error(response.error)
-// return null
-// }
-// }
-
-/**
- *
- * @param supabase
- */
-// async function useTokenData(supabase: SupabaseClient) {
-// const tokenData = await fetchTokenData(supabase)
-// if (tokenData) {
-// console.log(tokenData)
-// } else {
-// console.log('Failed to fetch token data')
-// }
-// }
diff --git a/apps/marketing/src/pages/work/[projectSlug]/index.json.ts b/apps/marketing/src/pages/work/[projectSlug]/index.json.ts
index 7024cff..2bfa736 100644
--- a/apps/marketing/src/pages/work/[projectSlug]/index.json.ts
+++ b/apps/marketing/src/pages/work/[projectSlug]/index.json.ts
@@ -4,17 +4,28 @@ import type { APIContext } from 'astro'
import { supabase } from '@/supabase'
-const supabaseClient: SupabaseClient = supabase
type Work = Database['public']['Tables']['work']['Row']
type Project = Database['public']['Tables']['projects']['Row']
/**
*
* @param root0 The API context.
* @param root0.params The parameters object.
+ * @param context
* @returns The response object.
*/
-export async function GET({ params }: APIContext) {
- const { projectSlug, workSlug } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+ const { supabase: SupabaseClient } = supabaseResult
+ const { projectSlug } = context.params
if (typeof projectSlug !== 'string') {
return new Response(
@@ -28,7 +39,7 @@ export async function GET({ params }: APIContext) {
)
}
- const projectData = await fetchProjectData(supabaseClient, projectSlug)
+ const projectData = await fetchProjectData(SupabaseClient, projectSlug)
if (!projectData || projectData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
@@ -41,7 +52,10 @@ export async function GET({ params }: APIContext) {
const projectId = projectData[0]?.id
- const workData = await fetchWorkData(supabaseClient, projectId)
+ const workData = await fetchWorkData(
+ SupabaseClient as SupabaseClient,
+ projectId,
+ )
if (!workData || workData.length === 0) {
console.error('Data is empty or undefined')
@@ -56,7 +70,6 @@ export async function GET({ params }: APIContext) {
return new Response(
JSON.stringify({
projectSlug,
- workSlug,
projectData,
workData,
status: 200,
diff --git a/apps/marketing/src/pages/work/index.astro b/apps/marketing/src/pages/work/index.astro
index d81abae..4e54163 100644
--- a/apps/marketing/src/pages/work/index.astro
+++ b/apps/marketing/src/pages/work/index.astro
@@ -19,37 +19,44 @@ interface WorkData {
projectData: Project[]
}
-const response = await GET()
+const response = await GET(Astro)
const data = (await response.json()) as WorkData
---
-
-
- {
- data ? (
- data.workData.map((item: any) => (
-
- ))
- ) : (
-
Loading...
- )
- }
+
+
+
+ {
+ data ? (
+ data.workData.map((item: any) => (
+
+ ))
+ ) : (
+
Loading...
+ )
+ }
+
diff --git a/apps/marketing/src/pages/work/index.json.ts b/apps/marketing/src/pages/work/index.json.ts
index 56b4ad5..5953b59 100644
--- a/apps/marketing/src/pages/work/index.json.ts
+++ b/apps/marketing/src/pages/work/index.json.ts
@@ -1,12 +1,13 @@
import type { Database } from '@/database.types'
-import type { PostgrestResponse, SupabaseClient } from '@supabase/supabase-js'
+import type { SupabaseClient } from '@supabase/supabase-js'
+import type { APIContext } from 'astro'
+
+import { getSecret } from 'astro:env/server'
import { supabase } from '@/supabase'
type Work = Database['public']['Tables']['work']['Row']
-const supabaseClient: SupabaseClient = supabase
-
/**
* Fetch flow data from the database.
* @param supabase The Supabase client.
@@ -14,18 +15,32 @@ const supabaseClient: SupabaseClient = supabase
* @returns A promise that resolves to an array of Nodes or null.
*/
async function fetchWorkData(supabase: SupabaseClient): Promise
{
- const response: PostgrestResponse = await supabase
- .from('work')
- .select(
- `
- *,primary_image(filename_disk),project(slug)
- `,
- )
- .neq('status', 'draft')
+ const SUPABASE_DEV_MODE = getSecret('SUPABASE_DEV_MODE')
+ const isDevMode = SUPABASE_DEV_MODE === 'true'
+
+ // console.log('isDevMode:', isDevMode)
+
+ // Start building the query
+ let query = supabase.from('work').select(
+ `
+ *,primary_image(filename_disk),project(slug)
+`,
+ )
+
+ // Conditionally apply the filter based on isDevMode
+ if (!isDevMode) {
+ // console.log('Excluding drafts from query.')
+ query = query.neq('status', 'draft')
+ }
+
+ const response = await query
- // Type guard to check if response.error exists
+ // Log the response to see what is returned
+ // console.log('Response received:', response)
+
+ // Check for errors
if (response.error) {
- console.error(response.error)
+ console.error('Error fetching articles:', response.error)
return null
}
@@ -34,11 +49,24 @@ async function fetchWorkData(supabase: SupabaseClient): Promise {
/**
* Handle GET request.
+ * @param context
* @returns The response object.
*/
-export async function GET() {
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+
+ const { supabase: SupabaseClient } = supabaseResult
try {
- const workData = await fetchWorkData(supabaseClient)
+ const workData = await fetchWorkData(SupabaseClient)
if (!workData || workData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
diff --git a/apps/marketing/src/pages/workspace/[slug]/index.json.ts b/apps/marketing/src/pages/workspace/[slug]/index.json.ts
index 9ebbceb..44d0d06 100644
--- a/apps/marketing/src/pages/workspace/[slug]/index.json.ts
+++ b/apps/marketing/src/pages/workspace/[slug]/index.json.ts
@@ -7,16 +7,28 @@ import type { APIContext } from 'astro'
import { supabase } from '@/supabase'
-const supabaseClient: SupabaseClient = supabase
type Workspace = Database['public']['Tables']['workspaces']['Row']
/**
*
* @param root0 The API context.
* @param root0.params The parameters object.
+ * @param context
* @returns The response object.
*/
-export async function GET({ params }: APIContext) {
- const { slug } = params
+export async function GET(context: APIContext) {
+ const supabaseResult = await supabase(context)
+ if (!supabaseResult?.supabase) {
+ console.error('Failed to initialize Supabase client')
+ return new Response(JSON.stringify({ error: 'Internal server error' }), {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ })
+ }
+
+ const { supabase: SupabaseClient } = supabaseResult
+ const { slug } = context.params
if (typeof slug !== 'string') {
return new Response(
@@ -30,7 +42,7 @@ export async function GET({ params }: APIContext) {
)
}
- const workspaceData = await fetchWorkspaceData(supabaseClient, slug)
+ const workspaceData = await fetchWorkspaceData(SupabaseClient, slug)
if (!workspaceData || workspaceData.length === 0) {
console.error('Data is empty or undefined')
return new Response(JSON.stringify({ error: 'No data found.' }), {
@@ -43,7 +55,7 @@ export async function GET({ params }: APIContext) {
return new Response(
JSON.stringify({
- params,
+ params: context.params,
workspaceData,
// roadmapData,
status: 200,
diff --git a/apps/marketing/src/styles/codeblock.scss b/apps/marketing/src/styles/codeblock.scss
index 4953e56..985aadb 100644
--- a/apps/marketing/src/styles/codeblock.scss
+++ b/apps/marketing/src/styles/codeblock.scss
@@ -46,101 +46,6 @@
--sp-syntax-color-string: #977cdc;
}
-/* :root {
- --sp-space-1: 4px;
- --sp-space-2: 8px;
- --sp-space-3: 12px;
- --sp-space-4: 16px;
- --sp-space-5: 20px;
- --sp-space-6: 24px;
- --sp-space-7: 28px;
- --sp-space-8: 32px;
- --sp-space-9: 36px;
- --sp-space-10: 40px;
- --sp-space-11: 44px;
- --sp-border-radius: 12px;
- --sp-layout-height: 300px;
- --sp-layout-headerHeight: 28px;
- --sp-transitions-default: 150ms ease;
- --sp-zIndices-base: 1;
- --sp-zIndices-overlay: 2;
- --sp-zIndices-top: 3;
- --sp-colors-surface1: var(--grayA1);
- --sp-colors-surface2: var(--grayA1);
- --sp-colors-surface3: var(--grayA1);
- --sp-colors-disabled: var(--grayA1);
- --sp-colors-base: var(--grayA1);
- --sp-colors-clickable: var(--gray7);
- --sp-colors-hover: var(--gray8);
- --sp-colors-accent: var(--gray10);
- --sp-colors-error: #FFB4A6;
- --sp-colors-errorSurface: #690000;
- --sp-colors-warning: #E7C400;
- --sp-colors-warningSurface: #3A3000;
- --sp-font-body: 'Labil Grotesk Variable';
- --sp-font-mono: 'IBM Plex Mono';
- --sp-font-size: 12px;
- --sp-font-lineHeight: 20px;
- --sp-syntax-color-plain: var(--gray10);
- --sp-syntax-color-comment: #757575;
- --sp-syntax-fontStyle-comment: italic;
- --sp-syntax-color-keyword: #77B7D7;
- --sp-syntax-color-tag: #DFAB5C;
- --sp-syntax-color-punctuation: var(--gray10);
- --sp-syntax-color-definition: #86D9CA;
- --sp-syntax-color-property: #77B7D7;
- --sp-syntax-color-static: #C64640;
- --sp-syntax-color-string: #977CDC;
-
-
- .dark, .dark-theme {
- --sp-space-1: 4px;
- --sp-space-2: 8px;
- --sp-space-3: 12px;
- --sp-space-4: 16px;
- --sp-space-5: 20px;
- --sp-space-6: 24px;
- --sp-space-7: 28px;
- --sp-space-8: 32px;
- --sp-space-9: 36px;
- --sp-space-10: 40px;
- --sp-space-11: 44px;
- --sp-border-radius: 12px;
- --sp-layout-height: 300px;
- --sp-layout-headerHeight: 28px;
- --sp-transitions-default: 150ms ease;
- --sp-zIndices-base: 1;
- --sp-zIndices-overlay: 2;
- --sp-zIndices-top: 3;
- --sp-colors-surface1: var(--grayA1);
- --sp-colors-surface2: var(--grayA1);
- --sp-colors-surface3: var(--grayA1);
- --sp-colors-disabled: var(--grayA1);
- --sp-colors-base: var(--grayA1);
- --sp-colors-clickable: var(--gray7);
- --sp-colors-hover: var(--gray8);
- --sp-colors-accent: var(--gray10);
- --sp-colors-error: #FFB4A6;
- --sp-colors-errorSurface: #690000;
- --sp-colors-warning: #E7C400;
- --sp-colors-warningSurface: #3A3000;
- --sp-font-body: 'Labil Grotesk Variable';
- --sp-font-mono: 'IBM Plex Mono';
- --sp-font-size: 12px;
- --sp-font-lineHeight: 20px;
- --sp-syntax-color-plain: var(--gray10);
- --sp-syntax-color-comment: #757575;
- --sp-syntax-fontStyle-comment: italic;
- --sp-syntax-color-keyword: #77B7D7;
- --sp-syntax-color-tag: #DFAB5C;
- --sp-syntax-color-punctuation: var(--gray10);
- --sp-syntax-color-definition: #86D9CA;
- --sp-syntax-color-property: #77B7D7;
- --sp-syntax-color-static: #C64640;
- --sp-syntax-color-string: #977CDC;
- }
-} */
-
@tailwind base;
@layer {
.prodkt-codeblock-wrapper,
@@ -170,15 +75,6 @@ a.prodkt-codepreview-actions {
max-height: calc(100dvh - 110px);
}
-/* sp-editor */
-// .prodkt-codeblock-editor,
-// .sp-editor {
-// --sp-layout-height: calc(100dvh - 32px - 57px - 16px);
-// overflow-y: auto;
-// @apply bg-transparent;
-// }
-/* sp-tabs */
-/* sp-tab */
.prodkt-codeblock-tab-button,
.sp-tab-button,
.prodkt-codeblock-tab-button,
@@ -188,7 +84,7 @@ a.prodkt-codepreview-actions {
aria-selected:prodkt-codeblock-tab-button,
aria-selected:sp-tab-button,
aria-selected:prodkt-codeblock-tab-button {
- @apply rounded-lg shadow-none border border-transparent outline-0 ring-0 border-none ring-transparent pt-1 pb-0.5 text-xs bg-transparent !important;
+ @apply shadow-none border border-transparent outline-0 ring-0 border-none ring-transparent pt-1 pb-0.5 text-xs bg-transparent !important;
min-height: auto !important;
padding-left: 12px !important;
padding-right: 12px !important;
@@ -205,9 +101,6 @@ aria-selected:prodkt-codeblock-tab-button {
.prodkt-codeblock-tab-button[data-active='true'],
data-active:prodkt-codeblock-tab-button,
.sp-tab-button .prodkt-codeblock-tab-button[data-active='true'] {
- /* @apply bg-transparent border-transparent ring-[var(--gray10)] !important; */
- // @apply bg-[var(--grayA4)] dark:bg-[var(--gray12)] !important;
- @apply rounded-lg !important;
@apply outline-none outline-0 aria-selected:border-none ring-0 border-none !important;
}
@@ -229,56 +122,17 @@ aria-selected:prodkt-codeblock-tab-container {
@apply border-none ring-0 outline-none !important;
@apply outline-none aria-selected:outline-none aria-selected:outline-[var(--grayA1)] aria-selected:ring-[var(--grayA1)] aria-selected:border-[var(--grayA1)] !important;
}
-/* cm-editor */
-// .prodkt-codemirror-editor {
-// --codeblocksPageHeight: calc(100dvh - 32px - 57px - 16px);
-// max-height: var(--codeblocksPageHeight);
-// width: 100%;
-// @apply bg-transparent;
-// }
-/* cm-scroller */
-// .prodkt-codemirror-scroller,
-// .cm-scroller {
-// --codeblocksPageHeight: calc(100dvh - 32px - 57px - 57px);
-// max-height: var(--codeblocksPageHeight);
-// width: 100%;
-// overflow-y: auto;
-// }
-/* sp-pre-placeholder */
+
.sp-pre-placeholder,
.prodkt-codeblock-pre-placeholder {
- // --codeblocksPageHeight: calc(100dvh - 32px - 57px);
width: 100%;
- // max-height: var(--codeblocksPageHeight);
@apply bg-transparent;
}
-// .cm-editor {
-// padding: 0 0 0 0 !important;
-// margin: 0 0 0 0 !important;
-// }
-/* cm-gutters */
.prodkt-codemirror-gutters,
.cm-gutters {
@apply pr-1 rounded-lg bg-transparent !important;
}
-.sp-tabs-scrollable-container,
-.prodkt-tabs-scrollable-container {
- // @apply pt-2 pb-2 !important;
- // @apply border-none border-transparent dark:border-transparent !important;
-}
-
-.sp-tabs,
-.prodkt-codeblock-tabs,
-.sp-tabs-scrollable-container,
-.prodkt-tabs-scrollable-container {
- // @apply h-auto !important;
- // min-height: auto !important;
- // @apply bg-transparent !important;
- // @apply text-xs !important;
-}
-/* cm-content */
-/* sp-read-only */
.prodkt-codeblock-read-only {
@apply bg-transparent;
}
@@ -346,10 +200,6 @@ div.cm-comment {
@apply text-xs !important;
}
-// .sp-syntax-definition {
-// @apply text-[var(--green-10)] dark:text-[var(--green-7)] !important;
-// }
-
.prodkt-codeblock-tabs {
@apply absolute px-1.5 pt-1 pb-1 top-0 bottom-auto mt-0 z-10 min-h-[48px] w-full flex flex-row items-center !justify-start !gap-0 !bg-[var(--gray1)] ring-inset ring-1 ring-[var(--grayA4)] text-xs overflow-hidden rounded-2xl border-none !border-b-0;
}
@@ -375,8 +225,9 @@ div.cm-comment {
padding: 0 0 0 0 !important;
margin: 0;
}
-.prodkt-codeblock-tab-container button {
- @apply bg-[var(--grayA1)] mx-0 mr-[-20px] text-[var(--gray12)] hover:text-[var(--accent11)] pl-3 pr-3 py-2 rounded-2xl border border-[var(--grayA3)] !important;
+.prodkt-codeblock-tab-container button,
+.prodkt-codeblock-tabs-scrollable-container button[data-active='false'] {
+ @apply bg-[var(--grayA1)] mx-0 mr-[-20px] text-[var(--gray12)] hover:text-[var(--accent11)] font-sans pl-3 pr-3 py-2 rounded-xl border border-[var(--grayA3)] !important;
}
.prodkt-codeblock-tabs-scrollable-container button[data-active='true'] {
@@ -384,7 +235,7 @@ div.cm-comment {
}
.prodkt-codeblock-tab-container button[data-active='true'] {
- @apply bg-[var(--gray5)] border border-[var(--grayA1)] ring-1 ring-[var(--gray6)] ring-inset dark:ring-[var(--gray6)] rounded-xl !important;
+ @apply bg-[var(--gray5)] border border-[var(--grayA1)] ring-1 ring-[var(--gray6)] ring-inset dark:ring-[var(--gray6)] !important;
}
.prodkt-codeblock-tabs-scrollable-container::-webkit-resizer {
@@ -426,19 +277,9 @@ div.cm-comment {
border-radius: 9999px;
}
-// .cm-focused {
-// top: 0px;
-// overflow: hidden;
-// bottom: 0;
-// height: 100%;
-// position: relative;
-// border: 0 solid transparent;
-// }
-
.prodkt-codeblock-editor {
@apply rounded-lg h-full shadow-none border border-transparent outline-0 ring-0 border-none ring-transparent pt-1 mb-0 pb-0 text-xs bg-transparent !important;
}
-// .sp-editor,
.sp-stack {
@apply flex flex-col h-full flex-nowrap border-none mt-auto mb-0 bottom-0 top-auto overflow-hidden;
}
diff --git a/apps/marketing/src/styles/flow-board.css b/apps/marketing/src/styles/flow-board.css
index 1e701fc..6ac648d 100644
--- a/apps/marketing/src/styles/flow-board.css
+++ b/apps/marketing/src/styles/flow-board.css
@@ -29,16 +29,11 @@
--controls-box-shadow-default: 0 0 2px 1px rgba(0, 0, 0, 0.08);
}
-.react-flow__attribution {
- visibility: hidden;
- display: none;
-}
/* The outermost container */
.react-flow {
}
/* The inner container */
.react-flow__renderer {
- @apply bg-gradient-to-br from-[var(--grayA1)] to-[var(--gray1)];
}
/* Zoom & pan pane */
.react-flow__zoompane {
@@ -55,18 +50,24 @@
/* Applied to each Edge in the flow */
.react-flow__edge {
}
-/* .selected Added to an Edge when selected */
-.react-flow__edge {
-}
-/* .animated Added to an Edge when its animated prop is true */
-.react-flow__edge {
-}
-/* .updating Added to an Edge while it gets updated via onReconnect */
-.react-flow__edge {
-}
+
/* The SVG element of an Edge */
.react-flow__edge-path {
- @apply stroke-[var(--grayA9)] stroke-1 ease-in-out;
+ stroke: url(#edge-gradient);
+ stroke-linecap: round;
+ stroke-width: 1.5;
+ stroke-dasharray: 1 3;
+ stroke-linejoin: round;
+ marker-end: none;
+}
+
+.react-flow__edge .react-flow__edge-path {
+ stroke-opacity: 0.75;
+}
+
+.react-flow__edgelabel-renderer button {
+ @apply size-6 flex items-center content-center place-content-center place-items-center pb-0.5 justify-center leading-[100%] rounded-full bg-radial-gradient from-[var(--grayA6)] backdrop-blur-[2px] to-[var(--grayA1)] text-lg text-[var(--ghost-a12)];
+ border: 0px solid transparent;
}
/* The SVG element of an Edge label */
.react-flow__edge-text {
@@ -76,6 +77,7 @@
}
/* Applied to the current connection line */
.react-flow__connection {
+ /* @apply bg-gradient-to-t from-[var(--gray12)] to-[var(--gray1)]; */
}
/* The SVG of a connection line */
.react-flow__connection-path {
@@ -85,7 +87,7 @@
}
/* Applied to each Node in the flow */
.react-flow__node {
- @apply bg-[var(--grayA4)] backdrop-blur border-[var(--grayA4)] rounded-2xl px-8 py-4;
+ @apply bg-[var(--gray1)] backdrop-blur border-[var(--grayA4)] rounded-2xl px-8 py-4;
@apply drop-shadow-2xl shadow-[var(--grayA2)];
& .selected {
@@ -93,7 +95,7 @@
}
/* .selected Added to a Node when selected. */
.react-flow__node {
- @apply after:bg-gradient-to-br after:from-[var(--grayA1)] after:to-[var(--grayA1)] after:blur-3xl after:w-full after:h-full after:top-0 after:bottom-0 after:left-0 after:right-0 after:z-[10] after:absolute;
+ @apply after:bg-gradient-to-br after:from-[var(--grayA1)] after:to-[var(--ghost-aa4)] after:blur-3xl after:w-full after:h-full after:top-0 after:bottom-0 after:left-0 after:right-0 after:z-[10] after:absolute;
}
/* Added when Node type is "default" */
.react-flow__node-default {
@@ -112,50 +114,53 @@
}
/* Applied to each component */
.react-flow__handle {
+ @apply size-4 bg-[var(--grayA9)] border border-[var(--grayA12)] rounded-full shadow-[var(--ghost-aa12)] shadow-xl ring-1 ring-inset ring-[var(--grayA9)];
+ @apply transition-all ease-in-out duration-500;
+}
+
+.react-flow__handle.source {
+ right: -20px;
+}
+
+.react-flow__handle.target {
+ left: -20px;
+}
+
+.react-flow__node:focus {
}
+
/* Applied when a handle's Position is set to "top" */
.react-flow__handle-top {
}
/* Applied when a handle's Position is set to "right" */
.react-flow__handle-right {
+ /* @apply right-[-12px]; */
}
/* Applied when a handle's Position is set to "bottom" */
.react-flow__handle-bottom {
}
/* Applied when a handle's Position is set to "left" */
.react-flow__handle-left {
+ /* @apply left-[-12px]; */
}
/* Added to a Handle when a connection line is above a handle. */
.connectingfrom {
+ @apply size-8 transition-all ease-in-out duration-1000;
}
/* Added to a Handle when a connection line is above a handle. */
.connectingto {
+ @apply size-8 transition-all ease-in-out duration-1000;
}
/* */
-.valid
- Added
- to
- a
- Handle
- when
- a
- connection
- line
- is
- above
- and
- the
- connection
- is
- valid {
+.valid {
}
/* Applied to the component */
.react-flow__background {
- @apply bg-[var(--gray2)];
+ @apply bg-gradient-to-br from-[var(--gray6)] to-[var(--gray5)] dark:from-[var(--gray2)] dark:to-[var(--gray1)];
}
/* Applied to the component */
.react-flow__minimap {
- @apply bg-[var(--grayA1)] rounded-2xl border overflow-clip backdrop-blur before:opacity-0 after:opacity-0;
+ @apply bg-[var(--ghost-aa7)] rounded-2xl border border-[var(--grayA3)] overflow-clip backdrop-blur before:opacity-0 after:opacity-0;
}
/* Applied to the component */
.react-flow__controls {
@@ -163,7 +168,12 @@
}
.react-flow__panel {
- @apply bg-[var(--grayA1)] backdrop-blur;
+ @apply bg-[var(--ghost-aa8)] dark:bg-[var(--grayA3)] ring-1 ring-[var(--grayA2)] backdrop-blur border-none;
+}
+
+.react-flow__attribution {
+ visibility: hidden;
+ display: none;
}
.react-flow__minimap::before {
diff --git a/apps/marketing/src/styles/globals.css b/apps/marketing/src/styles/globals.css
index 02a8679..24eb830 100644
--- a/apps/marketing/src/styles/globals.css
+++ b/apps/marketing/src/styles/globals.css
@@ -1,825 +1,31 @@
@import './codeblock.scss';
+/* @import '@prodkt/tailwind/color'; */
@import '@prodkt/tailwind/color';
+@import '@prodkt/tailwind/typography';
+@import '@prodkt/assets/fonts/index.css';
@import './flow-board.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
-
-body[data-scroll-locked] {
- @apply !p-4;
-}
-
-[data-accent-color='amber'] {
- --accent1: var(--amber1);
- --accent2: var(--amber2);
- --accent3: var(--amber3);
- --accent4: var(--amber4);
- --accent5: var(--amber5);
- --accent6: var(--amber6);
- --accent7: var(--amber7);
- --accent8: var(--amber8);
- --accent9: var(--amber9);
- --accent10: var(--amber10);
- --accent11: var(--amber11);
- --accent12: var(--amber12);
- --accentA1: var(--amberA1);
- --accentA2: var(--amberA2);
- --accentA3: var(--amberA3);
- --accentA4: var(--amberA4);
- --accentA5: var(--amberA5);
- --accentA6: var(--amberA6);
- --accentA7: var(--amberA7);
- --accentA8: var(--amberA8);
- --accentA9: var(--amberA9);
- --accentA10: var(--amberA10);
- --accentA11: var(--amberA11);
- --accentA12: var(--amberA12);
-}
-[data-accent-color='blue'] {
- --accent1: var(--blue1);
- --accent2: var(--blue2);
- --accent3: var(--blue3);
- --accent4: var(--blue4);
- --accent5: var(--blue5);
- --accent6: var(--blue6);
- --accent7: var(--blue7);
- --accent8: var(--blue8);
- --accent9: var(--blue9);
- --accent10: var(--blue10);
- --accent11: var(--blue11);
- --accent12: var(--blue12);
- --accentA1: var(--blueA1);
- --accentA2: var(--blueA2);
- --accentA3: var(--blueA3);
- --accentA4: var(--blueA4);
- --accentA5: var(--blueA5);
- --accentA6: var(--blueA6);
- --accentA7: var(--blueA7);
- --accentA8: var(--blueA8);
- --accentA9: var(--blueA9);
- --accentA10: var(--blueA10);
- --accentA11: var(--blueA11);
- --accentA12: var(--blueA12);
-}
-[data-accent-color='bronze'] {
- --accent1: var(--bronze1);
- --accent2: var(--bronze2);
- --accent3: var(--bronze3);
- --accent4: var(--bronze4);
- --accent5: var(--bronze5);
- --accent6: var(--bronze6);
- --accent7: var(--bronze7);
- --accent8: var(--bronze8);
- --accent9: var(--bronze9);
- --accent10: var(--bronze10);
- --accent11: var(--bronze11);
- --accent12: var(--bronze12);
- --accentA1: var(--bronzeA1);
- --accentA2: var(--bronzeA2);
- --accentA3: var(--bronzeA3);
- --accentA4: var(--bronzeA4);
- --accentA5: var(--bronzeA5);
- --accentA6: var(--bronzeA6);
- --accentA7: var(--bronzeA7);
- --accentA8: var(--bronzeA8);
- --accentA9: var(--bronzeA9);
- --accentA10: var(--bronzeA10);
- --accentA11: var(--bronzeA11);
- --accentA12: var(--bronzeA12);
-}
-[data-accent-color='brown'] {
- --accent1: var(--brown1);
- --accent2: var(--brown2);
- --accent3: var(--brown3);
- --accent4: var(--brown4);
- --accent5: var(--brown5);
- --accent6: var(--brown6);
- --accent7: var(--brown7);
- --accent8: var(--brown8);
- --accent9: var(--brown9);
- --accent10: var(--brown10);
- --accent11: var(--brown11);
- --accent12: var(--brown12);
- --accentA1: var(--brownA1);
- --accentA2: var(--brownA2);
- --accentA3: var(--brownA3);
- --accentA4: var(--brownA4);
- --accentA5: var(--brownA5);
- --accentA6: var(--brownA6);
- --accentA7: var(--brownA7);
- --accentA8: var(--brownA8);
- --accentA9: var(--brownA9);
- --accentA10: var(--brownA10);
- --accentA11: var(--brownA11);
- --accentA12: var(--brownA12);
-}
-[data-accent-color='crimson'] {
- --accent1: var(--crimson1);
- --accent2: var(--crimson2);
- --accent3: var(--crimson3);
- --accent4: var(--crimson4);
- --accent5: var(--crimson5);
- --accent6: var(--crimson6);
- --accent7: var(--crimson7);
- --accent8: var(--crimson8);
- --accent9: var(--crimson9);
- --accent10: var(--crimson10);
- --accent11: var(--crimson11);
- --accent12: var(--crimson12);
- --accentA1: var(--crimsonA1);
- --accentA2: var(--crimsonA2);
- --accentA3: var(--crimsonA3);
- --accentA4: var(--crimsonA4);
- --accentA5: var(--crimsonA5);
- --accentA6: var(--crimsonA6);
- --accentA7: var(--crimsonA7);
- --accentA8: var(--crimsonA8);
- --accentA9: var(--crimsonA9);
- --accentA10: var(--crimsonA10);
- --accentA11: var(--crimsonA11);
- --accentA12: var(--crimsonA12);
-}
-[data-accent-color='cyan'] {
- --accent1: var(--cyan1);
- --accent2: var(--cyan2);
- --accent3: var(--cyan3);
- --accent4: var(--cyan4);
- --accent5: var(--cyan5);
- --accent6: var(--cyan6);
- --accent7: var(--cyan7);
- --accent8: var(--cyan8);
- --accent9: var(--cyan9);
- --accent10: var(--cyan10);
- --accent11: var(--cyan11);
- --accent12: var(--cyan12);
- --accentA1: var(--cyanA1);
- --accentA2: var(--cyanA2);
- --accentA3: var(--cyanA3);
- --accentA4: var(--cyanA4);
- --accentA5: var(--cyanA5);
- --accentA6: var(--cyanA6);
- --accentA7: var(--cyanA7);
- --accentA8: var(--cyanA8);
- --accentA9: var(--cyanA9);
- --accentA10: var(--cyanA10);
- --accentA11: var(--cyanA11);
- --accentA12: var(--cyanA12);
-}
-[data-accent-color='gold'] {
- --accent1: var(--gold1);
- --accent2: var(--gold2);
- --accent3: var(--gold3);
- --accent4: var(--gold4);
- --accent5: var(--gold5);
- --accent6: var(--gold6);
- --accent7: var(--gold7);
- --accent8: var(--gold8);
- --accent9: var(--gold9);
- --accent10: var(--gold10);
- --accent11: var(--gold11);
- --accent12: var(--gold12);
- --accentA1: var(--goldA1);
- --accentA2: var(--goldA2);
- --accentA3: var(--goldA3);
- --accentA4: var(--goldA4);
- --accentA5: var(--goldA5);
- --accentA6: var(--goldA6);
- --accentA7: var(--goldA7);
- --accentA8: var(--goldA8);
- --accentA9: var(--goldA9);
- --accentA10: var(--goldA10);
- --accentA11: var(--goldA11);
- --accentA12: var(--goldA12);
-}
-[data-accent-color='grass'] {
- --accent1: var(--grass1);
- --accent2: var(--grass2);
- --accent3: var(--grass3);
- --accent4: var(--grass4);
- --accent5: var(--grass5);
- --accent6: var(--grass6);
- --accent7: var(--grass7);
- --accent8: var(--grass8);
- --accent9: var(--grass9);
- --accent10: var(--grass10);
- --accent11: var(--grass11);
- --accent12: var(--grass12);
- --accentA1: var(--grassA1);
- --accentA2: var(--grassA2);
- --accentA3: var(--grassA3);
- --accentA4: var(--grassA4);
- --accentA5: var(--grassA5);
- --accentA6: var(--grassA6);
- --accentA7: var(--grassA7);
- --accentA8: var(--grassA8);
- --accentA9: var(--grassA9);
- --accentA10: var(--grassA10);
- --accentA11: var(--grassA11);
- --accentA12: var(--grassA12);
-}
-[data-accent-color='gray'] {
- --accent1: var(--gray1);
- --accent2: var(--gray2);
- --accent3: var(--gray3);
- --accent4: var(--gray4);
- --accent5: var(--gray5);
- --accent6: var(--gray6);
- --accent7: var(--gray7);
- --accent8: var(--gray8);
- --accent9: var(--gray9);
- --accent10: var(--gray10);
- --accent11: var(--gray11);
- --accent12: var(--gray12);
- --accentA1: var(--grayA1);
- --accentA2: var(--grayA2);
- --accentA3: var(--grayA3);
- --accentA4: var(--grayA4);
- --accentA5: var(--grayA5);
- --accentA6: var(--grayA6);
- --accentA7: var(--grayA7);
- --accentA8: var(--grayA8);
- --accentA9: var(--grayA9);
- --accentA10: var(--grayA10);
- --accentA11: var(--grayA11);
- --accentA12: var(--grayA12);
-}
-[data-accent-color='green'] {
- --accent1: var(--green1);
- --accent2: var(--green2);
- --accent3: var(--green3);
- --accent4: var(--green4);
- --accent5: var(--green5);
- --accent6: var(--green6);
- --accent7: var(--green7);
- --accent8: var(--green8);
- --accent9: var(--green9);
- --accent10: var(--green10);
- --accent11: var(--green11);
- --accent12: var(--green12);
- --accentA1: var(--greenA1);
- --accentA2: var(--greenA2);
- --accentA3: var(--greenA3);
- --accentA4: var(--greenA4);
- --accentA5: var(--greenA5);
- --accentA6: var(--greenA6);
- --accentA7: var(--greenA7);
- --accentA8: var(--greenA8);
- --accentA9: var(--greenA9);
- --accentA10: var(--greenA10);
- --accentA11: var(--greenA11);
- --accentA12: var(--greenA12);
-}
-[data-accent-color='indigo'] {
- --accent1: var(--indigo1);
- --accent2: var(--indigo2);
- --accent3: var(--indigo3);
- --accent4: var(--indigo4);
- --accent5: var(--indigo5);
- --accent6: var(--indigo6);
- --accent7: var(--indigo7);
- --accent8: var(--indigo8);
- --accent9: var(--indigo9);
- --accent10: var(--indigo10);
- --accent11: var(--indigo11);
- --accent12: var(--indigo12);
- --accentA1: var(--indigoA1);
- --accentA2: var(--indigoA2);
- --accentA3: var(--indigoA3);
- --accentA4: var(--indigoA4);
- --accentA5: var(--indigoA5);
- --accentA6: var(--indigoA6);
- --accentA7: var(--indigoA7);
- --accentA8: var(--indigoA8);
- --accentA9: var(--indigoA9);
- --accentA10: var(--indigoA10);
- --accentA11: var(--indigoA11);
- --accentA12: var(--indigoA12);
-}
-[data-accent-color='iris'] {
- --accent1: var(--iris1);
- --accent2: var(--iris2);
- --accent3: var(--iris3);
- --accent4: var(--iris4);
- --accent5: var(--iris5);
- --accent6: var(--iris6);
- --accent7: var(--iris7);
- --accent8: var(--iris8);
- --accent9: var(--iris9);
- --accent10: var(--iris10);
- --accent11: var(--iris11);
- --accent12: var(--iris12);
- --accentA1: var(--irisA1);
- --accentA2: var(--irisA2);
- --accentA3: var(--irisA3);
- --accentA4: var(--irisA4);
- --accentA5: var(--irisA5);
- --accentA6: var(--irisA6);
- --accentA7: var(--irisA7);
- --accentA8: var(--irisA8);
- --accentA9: var(--irisA9);
- --accentA10: var(--irisA10);
- --accentA11: var(--irisA11);
- --accentA12: var(--irisA12);
-}
-[data-accent-color='jade'] {
- --accent1: var(--jade1);
- --accent2: var(--jade2);
- --accent3: var(--jade3);
- --accent4: var(--jade4);
- --accent5: var(--jade5);
- --accent6: var(--jade6);
- --accent7: var(--jade7);
- --accent8: var(--jade8);
- --accent9: var(--jade9);
- --accent10: var(--jade10);
- --accent11: var(--jade11);
- --accent12: var(--jade12);
- --accentA1: var(--jadeA1);
- --accentA2: var(--jadeA2);
- --accentA3: var(--jadeA3);
- --accentA4: var(--jadeA4);
- --accentA5: var(--jadeA5);
- --accentA6: var(--jadeA6);
- --accentA7: var(--jadeA7);
- --accentA8: var(--jadeA8);
- --accentA9: var(--jadeA9);
- --accentA10: var(--jadeA10);
- --accentA11: var(--jadeA11);
- --accentA12: var(--jadeA12);
-}
-[data-accent-color='lime'] {
- --accent1: var(--lime1);
- --accent2: var(--lime2);
- --accent3: var(--lime3);
- --accent4: var(--lime4);
- --accent5: var(--lime5);
- --accent6: var(--lime6);
- --accent7: var(--lime7);
- --accent8: var(--lime8);
- --accent9: var(--lime9);
- --accent10: var(--lime10);
- --accent11: var(--lime11);
- --accent12: var(--lime12);
- --accentA1: var(--limeA1);
- --accentA2: var(--limeA2);
- --accentA3: var(--limeA3);
- --accentA4: var(--limeA4);
- --accentA5: var(--limeA5);
- --accentA6: var(--limeA6);
- --accentA7: var(--limeA7);
- --accentA8: var(--limeA8);
- --accentA9: var(--limeA9);
- --accentA10: var(--limeA10);
- --accentA11: var(--limeA11);
- --accentA12: var(--limeA12);
-}
-[data-accent-color='mint'] {
- --accent1: var(--mint1);
- --accent2: var(--mint2);
- --accent3: var(--mint3);
- --accent4: var(--mint4);
- --accent5: var(--mint5);
- --accent6: var(--mint6);
- --accent7: var(--mint7);
- --accent8: var(--mint8);
- --accent9: var(--mint9);
- --accent10: var(--mint10);
- --accent11: var(--mint11);
- --accent12: var(--mint12);
- --accentA1: var(--mintA1);
- --accentA2: var(--mintA2);
- --accentA3: var(--mintA3);
- --accentA4: var(--mintA4);
- --accentA5: var(--mintA5);
- --accentA6: var(--mintA6);
- --accentA7: var(--mintA7);
- --accentA8: var(--mintA8);
- --accentA9: var(--mintA9);
- --accentA10: var(--mintA10);
- --accentA11: var(--mintA11);
- --accentA12: var(--mintA12);
+body {
+ @apply transition-all duration-500 will-change-auto;
}
-[data-accent-color='orange'] {
- --accent1: var(--orange1);
- --accent2: var(--orange2);
- --accent3: var(--orange3);
- --accent4: var(--orange4);
- --accent5: var(--orange5);
- --accent6: var(--orange6);
- --accent7: var(--orange7);
- --accent8: var(--orange8);
- --accent9: var(--orange9);
- --accent10: var(--orange10);
- --accent11: var(--orange11);
- --accent12: var(--orange12);
- --accentA1: var(--orangeA1);
- --accentA2: var(--orangeA2);
- --accentA3: var(--orangeA3);
- --accentA4: var(--orangeA4);
- --accentA5: var(--orangeA5);
- --accentA6: var(--orangeA6);
- --accentA7: var(--orangeA7);
- --accentA8: var(--orangeA8);
- --accentA9: var(--orangeA9);
- --accentA10: var(--orangeA10);
- --accentA11: var(--orangeA11);
- --accentA12: var(--orangeA12);
-}
-[data-accent-color='pink'] {
- --accent1: var(--pink1);
- --accent2: var(--pink2);
- --accent3: var(--pink3);
- --accent4: var(--pink4);
- --accent5: var(--pink5);
- --accent6: var(--pink6);
- --accent7: var(--pink7);
- --accent8: var(--pink8);
- --accent9: var(--pink9);
- --accent10: var(--pink10);
- --accent11: var(--pink11);
- --accent12: var(--pink12);
- --accentA1: var(--pinkA1);
- --accentA2: var(--pinkA2);
- --accentA3: var(--pinkA3);
- --accentA4: var(--pinkA4);
- --accentA5: var(--pinkA5);
- --accentA6: var(--pinkA6);
- --accentA7: var(--pinkA7);
- --accentA8: var(--pinkA8);
- --accentA9: var(--pinkA9);
- --accentA10: var(--pinkA10);
- --accentA11: var(--pinkA11);
- --accentA12: var(--pinkA12);
-}
-[data-accent-color='plum'] {
- --accent1: var(--plum1);
- --accent2: var(--plum2);
- --accent3: var(--plum3);
- --accent4: var(--plum4);
- --accent5: var(--plum5);
- --accent6: var(--plum6);
- --accent7: var(--plum7);
- --accent8: var(--plum8);
- --accent9: var(--plum9);
- --accent10: var(--plum10);
- --accent11: var(--plum11);
- --accent12: var(--plum12);
- --accentA1: var(--plumA1);
- --accentA2: var(--plumA2);
- --accentA3: var(--plumA3);
- --accentA4: var(--plumA4);
- --accentA5: var(--plumA5);
- --accentA6: var(--plumA6);
- --accentA7: var(--plumA7);
- --accentA8: var(--plumA8);
- --accentA9: var(--plumA9);
- --accentA10: var(--plumA10);
- --accentA11: var(--plumA11);
- --accentA12: var(--plumA12);
-}
-[data-accent-color='purple'] {
- --accent1: var(--purple1);
- --accent2: var(--purple2);
- --accent3: var(--purple3);
- --accent4: var(--purple4);
- --accent5: var(--purple5);
- --accent6: var(--purple6);
- --accent7: var(--purple7);
- --accent8: var(--purple8);
- --accent9: var(--purple9);
- --accent10: var(--purple10);
- --accent11: var(--purple11);
- --accent12: var(--purple12);
- --accentA1: var(--purpleA1);
- --accentA2: var(--purpleA2);
- --accentA3: var(--purpleA3);
- --accentA4: var(--purpleA4);
- --accentA5: var(--purpleA5);
- --accentA6: var(--purpleA6);
- --accentA7: var(--purpleA7);
- --accentA8: var(--purpleA8);
- --accentA9: var(--purpleA9);
- --accentA10: var(--purpleA10);
- --accentA11: var(--purpleA11);
- --accentA12: var(--purpleA12);
-}
-[data-accent-color='red'] {
- --accent1: var(--red1);
- --accent2: var(--red2);
- --accent3: var(--red3);
- --accent4: var(--red4);
- --accent5: var(--red5);
- --accent6: var(--red6);
- --accent7: var(--red7);
- --accent8: var(--red8);
- --accent9: var(--red9);
- --accent10: var(--red10);
- --accent11: var(--red11);
- --accent12: var(--red12);
- --accentA1: var(--redA1);
- --accentA2: var(--redA2);
- --accentA3: var(--redA3);
- --accentA4: var(--redA4);
- --accentA5: var(--redA5);
- --accentA6: var(--redA6);
- --accentA7: var(--redA7);
- --accentA8: var(--redA8);
- --accentA9: var(--redA9);
- --accentA10: var(--redA10);
- --accentA11: var(--redA11);
- --accentA12: var(--redA12);
-}
-[data-accent-color='ruby'] {
- --accent1: var(--ruby1);
- --accent2: var(--ruby2);
- --accent3: var(--ruby3);
- --accent4: var(--ruby4);
- --accent5: var(--ruby5);
- --accent6: var(--ruby6);
- --accent7: var(--ruby7);
- --accent8: var(--ruby8);
- --accent9: var(--ruby9);
- --accent10: var(--ruby10);
- --accent11: var(--ruby11);
- --accent12: var(--ruby12);
- --accentA1: var(--rubyA1);
- --accentA2: var(--rubyA2);
- --accentA3: var(--rubyA3);
- --accentA4: var(--rubyA4);
- --accentA5: var(--rubyA5);
- --accentA6: var(--rubyA6);
- --accentA7: var(--rubyA7);
- --accentA8: var(--rubyA8);
- --accentA9: var(--rubyA9);
- --accentA10: var(--rubyA10);
- --accentA11: var(--rubyA11);
- --accentA12: var(--rubyA12);
-}
-[data-accent-color='sky'] {
- --accent1: var(--sky1);
- --accent2: var(--sky2);
- --accent3: var(--sky3);
- --accent4: var(--sky4);
- --accent5: var(--sky5);
- --accent6: var(--sky6);
- --accent7: var(--sky7);
- --accent8: var(--sky8);
- --accent9: var(--sky9);
- --accent10: var(--sky10);
- --accent11: var(--sky11);
- --accent12: var(--sky12);
- --accentA1: var(--skyA1);
- --accentA2: var(--skyA2);
- --accentA3: var(--skyA3);
- --accentA4: var(--skyA4);
- --accentA5: var(--skyA5);
- --accentA6: var(--skyA6);
- --accentA7: var(--skyA7);
- --accentA8: var(--skyA8);
- --accentA9: var(--skyA9);
- --accentA10: var(--skyA10);
- --accentA11: var(--skyA11);
- --accentA12: var(--skyA12);
-}
-[data-accent-color='teal'] {
- --accent1: var(--teal1);
- --accent2: var(--teal2);
- --accent3: var(--teal3);
- --accent4: var(--teal4);
- --accent5: var(--teal5);
- --accent6: var(--teal6);
- --accent7: var(--teal7);
- --accent8: var(--teal8);
- --accent9: var(--teal9);
- --accent10: var(--teal10);
- --accent11: var(--teal11);
- --accent12: var(--teal12);
- --accentA1: var(--tealA1);
- --accentA2: var(--tealA2);
- --accentA3: var(--tealA3);
- --accentA4: var(--tealA4);
- --accentA5: var(--tealA5);
- --accentA6: var(--tealA6);
- --accentA7: var(--tealA7);
- --accentA8: var(--tealA8);
- --accentA9: var(--tealA9);
- --accentA10: var(--tealA10);
- --accentA11: var(--tealA11);
- --accentA12: var(--tealA12);
-}
-[data-accent-color='tomato'] {
- --accent1: var(--tomato1);
- --accent2: var(--tomato2);
- --accent3: var(--tomato3);
- --accent4: var(--tomato4);
- --accent5: var(--tomato5);
- --accent6: var(--tomato6);
- --accent7: var(--tomato7);
- --accent8: var(--tomato8);
- --accent9: var(--tomato9);
- --accent10: var(--tomato10);
- --accent11: var(--tomato11);
- --accent12: var(--tomato12);
- --accentA1: var(--tomatoA1);
- --accentA2: var(--tomatoA2);
- --accentA3: var(--tomatoA3);
- --accentA4: var(--tomatoA4);
- --accentA5: var(--tomatoA5);
- --accentA6: var(--tomatoA6);
- --accentA7: var(--tomatoA7);
- --accentA8: var(--tomatoA8);
- --accentA9: var(--tomatoA9);
- --accentA10: var(--tomatoA10);
- --accentA11: var(--tomatoA11);
- --accentA12: var(--tomatoA12);
-}
-[data-accent-color='violet'] {
- --accent1: var(--violet1);
- --accent2: var(--violet2);
- --accent3: var(--violet3);
- --accent4: var(--violet4);
- --accent5: var(--violet5);
- --accent6: var(--violet6);
- --accent7: var(--violet7);
- --accent8: var(--violet8);
- --accent9: var(--violet9);
- --accent10: var(--violet10);
- --accent11: var(--violet11);
- --accent12: var(--violet12);
- --accentA1: var(--violetA1);
- --accentA2: var(--violetA2);
- --accentA3: var(--violetA3);
- --accentA4: var(--violetA4);
- --accentA5: var(--violetA5);
- --accentA6: var(--violetA6);
- --accentA7: var(--violetA7);
- --accentA8: var(--violetA8);
- --accentA9: var(--violetA9);
- --accentA10: var(--violetA10);
- --accentA11: var(--violetA11);
- --accentA12: var(--violetA12);
-}
-[data-accent-color='yellow'] {
- --accent1: var(--yellow1);
- --accent2: var(--yellow2);
- --accent3: var(--yellow3);
- --accent4: var(--yellow4);
- --accent5: var(--yellow5);
- --accent6: var(--yellow6);
- --accent7: var(--yellow7);
- --accent8: var(--yellow8);
- --accent9: var(--yellow9);
- --accent10: var(--yellow10);
- --accent11: var(--yellow11);
- --accent12: var(--yellow12);
- --accentA1: var(--yellowA1);
- --accentA2: var(--yellowA2);
- --accentA3: var(--yellowA3);
- --accentA4: var(--yellowA4);
- --accentA5: var(--yellowA5);
- --accentA6: var(--yellowA6);
- --accentA7: var(--yellowA7);
- --accentA8: var(--yellowA8);
- --accentA9: var(--yellowA9);
- --accentA10: var(--yellowA10);
- --accentA11: var(--yellowA11);
- --accentA12: var(--yellowA12);
-}
-[data-gray-color='mauve'],
-.radix-themes:where([data-gray-color='mauve']) {
- --gray-1: var(--mauve1);
- --gray-2: var(--mauve2);
- --gray-3: var(--mauve3);
- --gray-4: var(--mauve4);
- --gray-5: var(--mauve5);
- --gray-6: var(--mauve6);
- --gray-7: var(--mauve7);
- --gray-8: var(--mauve8);
- --gray-9: var(--mauve9);
- --gray-10: var(--mauve10);
- --gray-11: var(--mauve11);
- --gray-12: var(--mauve12);
- --grayA1: var(--mauveA1);
- --grayA2: var(--mauveA2);
- --grayA3: var(--mauveA3);
- --grayA4: var(--mauveA4);
- --grayA5: var(--mauveA5);
- --grayA6: var(--mauveA6);
- --grayA7: var(--mauveA7);
- --grayA8: var(--mauveA8);
- --grayA9: var(--mauveA9);
- --grayA10: var(--mauveA10);
- --grayA11: var(--mauveA11);
- --grayA12: var(--mauveA12);
-}
-[data-gray-color='olive'],
-.radix-themes:where([data-gray-color='olive']) {
- --gray-1: var(--olive1);
- --gray-2: var(--olive2);
- --gray-3: var(--olive3);
- --gray-4: var(--olive4);
- --gray-5: var(--olive5);
- --gray-6: var(--olive6);
- --gray-7: var(--olive7);
- --gray-8: var(--olive8);
- --gray-9: var(--olive9);
- --gray-10: var(--olive10);
- --gray-11: var(--olive11);
- --gray-12: var(--olive12);
- --grayA1: var(--oliveA1);
- --grayA2: var(--oliveA2);
- --grayA3: var(--oliveA3);
- --grayA4: var(--oliveA4);
- --grayA5: var(--oliveA5);
- --grayA6: var(--oliveA6);
- --grayA7: var(--oliveA7);
- --grayA8: var(--oliveA8);
- --grayA9: var(--oliveA9);
- --grayA10: var(--oliveA10);
- --grayA11: var(--oliveA11);
- --grayA12: var(--oliveA12);
+body[data-scroll-locked] {
+ @apply !p-4 transition-all duration-300 h-[calc(100dvh_-_32px)];
}
-[data-gray-color='sage'],
-.radix-themes:where([data-gray-color='sage']) {
- --gray-1: var(--sage1);
- --gray-2: var(--sage2);
- --gray-3: var(--sage3);
- --gray-4: var(--sage4);
- --gray-5: var(--sage5);
- --gray-6: var(--sage6);
- --gray-7: var(--sage7);
- --gray-8: var(--sage8);
- --gray-9: var(--sage9);
- --gray-10: var(--sage10);
- --gray-11: var(--sage11);
- --gray-12: var(--sage12);
- --grayA1: var(--sageA1);
- --grayA2: var(--sageA2);
- --grayA3: var(--sageA3);
- --grayA4: var(--sageA4);
- --grayA5: var(--sageA5);
- --grayA6: var(--sageA6);
- --grayA7: var(--sageA7);
- --grayA8: var(--sageA8);
- --grayA9: var(--sageA9);
- --grayA10: var(--sageA10);
- --grayA11: var(--sageA11);
- --grayA12: var(--sageA12);
+body[data-scroll-locked] .prodkt-provider {
+ @apply rounded-3xl transition-all duration-300 blur-sm sm:blur-none h-[calc(100dvh_-_32px)];
}
-[data-gray-color='sand'],
-.radix-themes:where([data-gray-color='sand']) {
- --gray-1: var(--sand1);
- --gray-2: var(--sand2);
- --gray-3: var(--sand3);
- --gray-4: var(--sand4);
- --gray-5: var(--sand5);
- --gray-6: var(--sand6);
- --gray-7: var(--sand7);
- --gray-8: var(--sand8);
- --gray-9: var(--sand9);
- --gray-10: var(--sand10);
- --gray-11: var(--sand11);
- --gray-12: var(--sand12);
- --grayA1: var(--sandA1);
- --grayA2: var(--sandA2);
- --grayA3: var(--sandA3);
- --grayA4: var(--sandA4);
- --grayA5: var(--sandA5);
- --grayA6: var(--sandA6);
- --grayA7: var(--sandA7);
- --grayA8: var(--sandA8);
- --grayA9: var(--sandA9);
- --grayA10: var(--sandA10);
- --grayA11: var(--sandA11);
- --grayA12: var(--sandA12);
+
+body[data-scroll-locked] div:has(.fixed, [role='dialog']),
+body[data-scroll-locked]
+ [data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-direction='bottom'][data-state='open'] {
+ @apply !inset-x-[16px] rounded-3xl bottom-[16px] overflow-hidden;
}
-[data-gray-color='slate'],
-.radix-themes:where([data-gray-color='slate']) {
- --gray-1: var(--slate1);
- --gray-2: var(--slate2);
- --gray-3: var(--slate3);
- --gray-4: var(--slate4);
- --gray-5: var(--slate5);
- --gray-6: var(--slate6);
- --gray-7: var(--slate7);
- --gray-8: var(--slate8);
- --gray-9: var(--slate9);
- --gray-10: var(--slate10);
- --gray-11: var(--slate11);
- --gray-12: var(--slate12);
- --grayA1: var(--slateA1);
- --grayA2: var(--slateA2);
- --grayA3: var(--slateA3);
- --grayA4: var(--slateA4);
- --grayA5: var(--slateA5);
- --grayA6: var(--slateA6);
- --grayA7: var(--slateA7);
- --grayA8: var(--slateA8);
- --grayA9: var(--slateA9);
- --grayA10: var(--slateA10);
- --grayA11: var(--slateA11);
- --grayA12: var(--slateA12);
+
+[data-vaul-drawer][data-vaul-snap-points='false'][data-vaul-drawer-direction='bottom'][data-state='closed'] {
+ @apply !inset-x-[16px] rounded-3xl bottom-[0px] overflow-hidden;
}
@layer base {
@@ -829,7 +35,7 @@ body[data-scroll-locked] {
html,
body {
- @apply bg-[var(--gray1)] text-foreground font-sans;
+ @apply text-foreground font-sans;
}
}
@@ -1011,6 +217,10 @@ body[data-scroll-locked] {
}
}
+.prodkt-blog-content a {
+ @apply text-[var(--accent10)] font-normal underline underline-offset-4 !important;
+}
+
.prodkt-changelog-accordion {
& h3 {
@apply !mb-0;
diff --git a/apps/marketing/src/supabase/index.tsx b/apps/marketing/src/supabase/index.tsx
index dd2a12b..85a18f2 100644
--- a/apps/marketing/src/supabase/index.tsx
+++ b/apps/marketing/src/supabase/index.tsx
@@ -1,6 +1,23 @@
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+/* eslint-disable jsdoc/require-returns */
+/* eslint-disable jsdoc/require-param-description */
+
+// import type { Database } from '@/database.types'
+// import type { CookieOptions } from '@supabase/ssr'
+
import type { Database } from '@/database.types'
-import type { SupabaseClientOptions } from '@supabase/supabase-js'
+import type {
+ ApiResponse,
+ ErrorProps,
+ FeedbackProps,
+ ProfileProps,
+ ProjectProps,
+} from '@/lib/types'
+import type { CookieOptions } from '@supabase/ssr'
+import type { SupabaseClient, UserMetadata } from '@supabase/supabase-js'
+import type { APIContext, AstroGlobal } from 'astro'
+import { createServerClient, parseCookieHeader } from '@supabase/ssr'
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = import.meta.env.PUBLIC_SUPABASE_URL
@@ -10,28 +27,412 @@ if (!supabaseUrl || !supabaseAnonKey) {
throw new Error('Missing Supabase URL or Anonymous Key')
}
-const options: SupabaseClientOptions<'public'> = {
- db: {},
- auth: {
- flowType: 'pkce',
- autoRefreshToken: false,
- detectSessionInUrl: false,
- persistSession: true,
- },
- global: {
- headers: {
- 'x-prodkt-cloud': 'Prodkt from Bryan Funk',
- // cookies: {
- // get: (name: string) => string;
- // set: (name: string, value: string, options: Partial) => void;
- // remove: (name: string, options: Partial) => void;
- // };
+// const options: SupabaseClientOptions<'public'> = {
+// db: {},
+// auth: {
+// flowType: 'pkce',
+// autoRefreshToken: false,
+// detectSessionInUrl: false,
+// persistSession: true,
+// },
+// global: {
+// headers: {
+// 'x-prodkt-cloud': 'Prodkt from Bryan Funk',
+// // cookies: {
+// // get: (name: string) => string;
+// // set: (name: string, value: string, options: Partial) => void;
+// // remove: (name: string, options: Partial) => void;
+// // };
+// },
+// },
+// }
+
+export interface ClientCookiesConfig {
+ cookies: {
+ get?: (name: string) => string | undefined
+ set?: (name: string, value: string, options: CookieOptions) => void
+ remove?: (name: string, options: CookieOptions) => void
+ }
+}
+
+/**
+ *
+ * @param cookieStore
+ * @param operations
+ */
+function createCookiesConfig(
+ cookieStore: APIContext['cookies'],
+ operations: ('get' | 'set' | 'remove')[],
+): ClientCookiesConfig {
+ const config: ClientCookiesConfig = {
+ cookies: {},
+ }
+
+ operations.forEach((operation) => {
+ switch (operation) {
+ case 'get':
+ config.cookies.get = (name: string) => cookieStore.get(name)?.value
+ break
+ case 'set':
+ config.cookies.set = (
+ name: string,
+ value: string,
+ options: CookieOptions,
+ ) => {
+ cookieStore.set(name, value, options)
+ }
+ break
+ case 'remove':
+ config.cookies.remove = (name: string, options: CookieOptions) => {
+ cookieStore.set(name, '', { ...options })
+ }
+ break
+ default:
+ throw new Error(`Invalid operation: ${operation as string}`)
+ }
+ })
+
+ return config
+}
+
+/**
+ *
+ * @param context
+ * @param isPublic
+ */
+export async function GET(context: APIContext | AstroGlobal, isPublic = false) {
+ const headerStore = context.request.headers
+ const cookieStore = context.cookies
+ // let headerStore: Headers
+
+ // if (context?.request.headers) {
+ // // This covers both APIContext and AstroGlobal
+ // headerStore = context.request.headers
+ // cookieStore = context.cookies
+ // } else if (context?.url) {
+ // // This is likely an Astro.props context
+ // headerStore = context.request.headers
+ // cookieStore = context.cookies
+ // }
+
+ // If we can't get headers or cookies, we'll return early
+ // const assertedHeaderStore = headerStore;
+
+ const authHeader = headerStore.get('authorization')
+
+ const supabase = createServerClient(
+ import.meta.env.PUBLIC_SUPABASE_URL,
+ import.meta.env.PUBLIC_SUPABASE_ANON_KEY,
+ {
+ cookies: {
+ ...createCookiesConfig(cookieStore, ['get', 'set', 'remove']),
+ getAll() {
+ return parseCookieHeader(context.request.headers.get('Cookie') ?? '')
+ },
+ setAll(cookiesToSet) {
+ cookiesToSet.forEach(({ name, value, options }) => {
+ cookieStore.set(name, value, options)
+ })
+ },
+ },
+ auth: {
+ flowType: 'pkce',
+ autoRefreshToken: false,
+ detectSessionInUrl: false,
+ persistSession: true,
+ },
+ global: {
+ headers: {
+ lumkey: headerStore.get('lumkey') ?? '',
+ },
+ },
},
- },
+ )
+
+ // If auth header exists, validate api key
+ if (authHeader) {
+ // Get api key from auth header
+ const apiKey = authHeader.split(' ')[1]
+
+ // Fetch api key
+ const { data, error } = (await supabase
+ .from('project_api_keys')
+ .select('project_id, permission, creator:creator_id (*)')
+ .eq('token', apiKey)
+ .single()) as unknown as {
+ data: {
+ permission: 'full_access' | 'public_access'
+ creator: ProfileProps['Row']
+ project_id: string
+ }
+ error: ErrorProps
+ }
+
+ // If error is not null, then the api key is invalid
+ if (error.message) {
+ return {
+ supabase,
+ user: { data: null, error },
+ }
+ }
+
+ // TODO: Expand this further, also supporting public access for feedback etc.
+ if (data.permission === 'public_access' && !isPublic) {
+ return {
+ supabase,
+ user: {
+ data: null,
+ error: { message: 'unauthorized, missing permissions.', status: 403 },
+ },
+ }
+ }
+
+ return {
+ supabase,
+ user: { data: { user: data.creator }, error: null },
+ apiKey: data,
+ }
+ }
+
+ const user = await supabase.auth.getUser()
+
+ return { supabase, user, apiKey: null }
+}
+
+export const supabase = GET
+
+type WithProjectAuthHandler = (
+ user: UserMetadata | null,
+ supabase: SupabaseClient,
+ project: ProjectProps['Row'] | null,
+ error: ErrorProps | null,
+ allowPublic?: boolean,
+) => ApiResponse
+
+// withProjectAuth is a helper function that can be used to wrap API routes
+// Ensures that the user is logged in and is a member of the project with the given slug
+// allowAnonAccess = true bypasses complete user auth and project auth checks
+// requireLogin = true requires the user to be logged in, even if allowAnonAccess is true
+export const withProjectAuth = (handler: WithProjectAuthHandler) => {
+ return async (
+ context: APIContext,
+ slug: string,
+ allowAnonAccess = false,
+ requireLogin = true,
+ ) => {
+ // Get the user from the session
+ const result = await GET(context, allowAnonAccess)
+ const { supabase, user, apiKey } = result
+
+ // If user.error is not null, then the user is likely not logged in
+ if ((user.error !== null && requireLogin) || user.data === null) {
+ return handler(null, supabase as SupabaseClient, null, {
+ message:
+ user.error.message === 'invalid claim: missing sub claim'
+ ? 'unauthorized, login required.'
+ : user.error.message || 'Unauthorized',
+ status: user.error.status ?? 401,
+ })
+ }
+ const getSupabaseData = supabase as SupabaseClient
+ // Get project from database
+ const { data: project, error } = await getSupabaseData
+ .from('projects')
+ .select()
+ .eq('slug', slug)
+ .single()
+
+ // If error is not null, then the project does not exist
+ if (error) {
+ return handler(
+ user.data.user ?? null,
+ supabase as SupabaseClient,
+ project,
+ {
+ message: 'project not found.',
+ status: 404,
+ },
+ )
+ }
+
+ // If api key exists, check if the api key has access to the project
+ if (apiKey && apiKey.project_id !== project.id) {
+ return handler(
+ user.data.user,
+ supabase as SupabaseClient,
+ project as ProjectProps['Row'],
+ {
+ message: 'unauthorized, invalid api key.',
+ status: 401,
+ },
+ )
+ }
+
+ // Check if user is a member of the project
+ if (!allowAnonAccess) {
+ const { error: projectMemberError } = await getSupabaseData
+ .from('project_members')
+ .select()
+ .eq('project_id', project.id)
+ .eq('member_id', user.data.user?.id ?? '')
+ .single()
+
+ // If not null, user is not a member of the project and should not be able to access it
+ if (projectMemberError) {
+ return handler(
+ user.data.user ?? null,
+ supabase as SupabaseClient,
+ project as ProjectProps['Row'],
+ {
+ message: 'project not found.',
+ status: 404,
+ },
+ )
+ }
+ }
+
+ return handler(
+ user.data.user ?? null,
+ supabase as SupabaseClient,
+ project as ProjectProps['Row'],
+ null,
+ allowAnonAccess,
+ )
+ }
+}
+
+type WithFeedbackAuthHandler = (
+ user: UserMetadata | null,
+ supabase: SupabaseClient,
+ feedback: FeedbackProps['Row'] | null,
+ project: ProjectProps['Row'] | null,
+ error: ErrorProps | null,
+) => ApiResponse
+
+// withFeedbackAuth is a helper function that can be used to wrap API routes
+// Ensures that the user is logged in and is authorized to access the feedback post with the given id
+
+export const withFeedbackAuth = (handler: WithFeedbackAuthHandler) => {
+ return async (
+ id: string,
+ slug: string,
+ requireLogin = true,
+ context: APIContext,
+ allowAnonAccess = false,
+ ) => {
+ // Get the user from the session
+ const result = await GET(context, allowAnonAccess)
+ const { supabase, user } = result
+
+ // If user.error is not null, then the user is likely not logged in
+ if ((user.error !== null && requireLogin) || user.data === null) {
+ return handler(null, supabase as SupabaseClient, null, null, {
+ message:
+ user.error.message === 'invalid claim: missing sub claim'
+ ? 'unauthorized, login required.'
+ : 'An error occurred',
+ status: user.error.status ?? 401,
+ })
+ }
+
+ const getSupabaseData = supabase as SupabaseClient
+ // Get project from database
+ const { data: project, error } = await getSupabaseData
+ .from('projects')
+ .select()
+ .eq('slug', slug)
+ .single()
+
+ // If error is not null, then the project does not exist
+ if (error) {
+ return handler(
+ user.data.user ?? null,
+ supabase as SupabaseClient,
+ null,
+ project,
+ {
+ message: 'project not found.',
+ status: 404,
+ },
+ )
+ }
+
+ // Check if feedback exists
+ const { data: feedback, error: feedbackError } = await getSupabaseData
+ .from('feedback')
+ .select('*, user:user_id (*)')
+ .eq('id', id)
+ .eq('project_id', project.id)
+ .single()
+
+ // If not null, feedback does not exist
+ if (feedbackError) {
+ return handler(
+ user.data.user ?? null,
+ supabase as SupabaseClient,
+ null,
+ project as ProjectProps['Row'],
+ {
+ message: 'feedback not found.',
+ status: 404,
+ },
+ )
+ }
+
+ // Return feedback
+ return handler(
+ user.data.user ?? null,
+ supabase as SupabaseClient,
+ feedback as FeedbackProps['Row'],
+ project as ProjectProps['Row'],
+ null,
+ )
+ }
}
-const supabase = createClient(supabaseUrl, supabaseAnonKey, options)
+type WithUserAuthHandler = (
+ user: UserMetadata | null,
+ supabase: SupabaseClient,
+ error: ErrorProps | null,
+) => ApiResponse
+
+// withUserAuth is a helper function that can be used to wrap API routes
+// Ensures that the user is logged in
+export const withUserAuth = (handler: WithUserAuthHandler) => {
+ return async (context: APIContext, requireLogin = true) => {
+ // Get the user from the session
+ const result = await GET(context)
+ const { supabase, user } = result
+ // If user.error is not null, then the user is likely not logged in
+ if (user.error !== null && requireLogin) {
+ return handler(null, supabase as SupabaseClient, {
+ message:
+ user.error.message === 'invalid claim: missing sub claim'
+ ? 'unauthorized, login required.'
+ : user.error.message,
+ status: user.error.status ?? 401,
+ })
+ }
-// export const { data: getSession, error } = await supabase.auth.getSession()
+ return handler(
+ user.data?.user ?? null,
+ supabase as SupabaseClient,
+ null,
+ )
+ }
+}
-export { supabase }
+export const createClientSupabaseClient = () => {
+ return createClient(
+ import.meta.env.PUBLIC_SUPABASE_URL,
+ import.meta.env.PUBLIC_SUPABASE_ANON_KEY,
+ {
+ auth: {
+ storage: globalThis.localStorage,
+ autoRefreshToken: true,
+ persistSession: true,
+ detectSessionInUrl: true,
+ },
+ },
+ )
+}
diff --git a/apps/marketing/src/supabase/server.astro b/apps/marketing/src/supabase/server.astro
new file mode 100644
index 0000000..14f3c51
--- /dev/null
+++ b/apps/marketing/src/supabase/server.astro
@@ -0,0 +1,27 @@
+
diff --git a/apps/marketing/tsconfig.json b/apps/marketing/tsconfig.json
index 78897a7..750628e 100644
--- a/apps/marketing/tsconfig.json
+++ b/apps/marketing/tsconfig.json
@@ -1,10 +1,12 @@
{
"extends": ["astro/tsconfigs/strictest", "@prodkt/tsconfig/react.json"],
"compilerOptions": {
+ "jsx": "react-jsx",
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@/supabase/*": ["src/supabase/*"]
}
- }
+ },
+ "exclude": ["public/posthog.js", "dist", "_*", "**/_*", "**/_*/**/*"]
}
diff --git a/apps/marketing/turbo.json b/apps/marketing/turbo.json
index 2682e4e..3a40263 100644
--- a/apps/marketing/turbo.json
+++ b/apps/marketing/turbo.json
@@ -9,25 +9,31 @@
"outputs": [".astro/**", "dist/**"],
"passThroughEnv": [
"PUBLIC_SUPABASE_URL",
+ "PUBLIC_VERCEL_ENV",
"PUBLIC_SUPABASE_ANON_KEY",
"PUBLIC_POSTHOG_KEY",
"PUBLIC_POSTHOG_HOST",
"PUBLIC_SENTRY_DSN",
"SENTRY_ORG",
"SENTRY_PROJECT",
- "SENTRY_AUTH_TOKEN"
+ "SENTRY_AUTH_TOKEN",
+ "TINYBIRD_API_URL",
+ "TINYBIRD_API_KEY"
]
},
"test:e2e": {
"passThroughEnv": [
"PUBLIC_SUPABASE_URL",
+ "PUBLIC_VERCEL_ENV",
"PUBLIC_SUPABASE_ANON_KEY",
"PUBLIC_POSTHOG_KEY",
"PUBLIC_POSTHOG_HOST",
"PUBLIC_SENTRY_DSN",
"SENTRY_ORG",
"SENTRY_PROJECT",
- "SENTRY_AUTH_TOKEN"
+ "SENTRY_AUTH_TOKEN",
+ "TINYBIRD_API_URL",
+ "TINYBIRD_API_KEY"
]
}
}
diff --git a/apps/web/package.json b/apps/web/package.json
index eea6a1b..ee60141 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -7,7 +7,7 @@
"author": "Bryan Funk",
"type": "module",
"scripts": {
- "build": "next build",
+ "build:temp": "next build",
"clean": "bun run rm -rf .next *.tsbuildinfo playwright-report test-results",
"dev": "next dev",
"lint": "eslint . --max-warnings 0",
@@ -22,9 +22,17 @@
"@prodkt/env": "workspace:*",
"@prodkt/ui": "workspace:*",
"@prodkt/utils": "workspace:*",
- "@sentry/nextjs": "^8.18.0",
+ "@sentry/nextjs": "^8.31.0",
"@t3-oss/env-nextjs": "^0.10.1",
"@tanstack/react-query": "^5.51.4",
+ "@tiptap/extension-character-count": "^2.1.12",
+ "@tiptap/extension-highlight": "^2.1.11",
+ "@tiptap/extension-link": "^2.2.4",
+ "@tiptap/extension-placeholder": "^2.1.11",
+ "@tiptap/extension-typography": "^2.1.11",
+ "@tiptap/pm": "^2.1.11",
+ "@tiptap/react": "^2.1.11",
+ "@tiptap/starter-kit": "^2.1.11",
"@total-typescript/ts-reset": "^0.5.1",
"@trpc/client": "next",
"@trpc/react-query": "next",
@@ -32,10 +40,10 @@
"@unkey/ratelimit": "^0.3.1",
"@uploadthing/react": "^6.7.2",
"geist": "^1.3.1",
- "next": "14.2.5",
+ "next": "14.2.13",
"next-themes": "^0.3.0",
- "posthog-js": "^1.148.0",
- "posthog-node": "^4.0.1",
+ "posthog-js": "^1.164.1",
+ "posthog-node": "^4.2.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"server-only": "^0.0.1",
@@ -49,12 +57,12 @@
"@prodkt/eslint": "workspace:*",
"@prodkt/tailwind": "workspace:*",
"@prodkt/tsconfig": "workspace:*",
- "@types/react": "^18.3.5",
+ "@types/react": "^18.3.8",
"@types/react-dom": "^18.3.0",
- "autoprefixer": "^10.4.19",
+ "autoprefixer": "^10.4.20",
"dotenv": "^16.4.5",
"jiti": "^1.21.6",
- "postcss": "^8.4.39",
- "tailwindcss": "^3.4.6"
+ "postcss": "^8.4.47",
+ "tailwindcss": "^3.4.13"
}
}
diff --git a/bun.lockb b/bun.lockb
old mode 100644
new mode 100755
index 915cd68..7c24d42
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/cspell.config.yaml b/cspell.config.yaml
index 7aaf35a..c3b0c7f 100644
--- a/cspell.config.yaml
+++ b/cspell.config.yaml
@@ -11,88 +11,174 @@ ignorePaths:
- drizzle
- '**/*.svg'
words:
+ - Aaiun
+ - Ababa
+ - abcdefghijklmopqrstuvwxyz
- acst
+ - actionables
+ - Adak
+ - Addis
- aest
- akst
+ - aliqua
+ - amet
+ - Amet
+ - Anadyr
- Anson
- apitoken
- - Concepting
+ - Aqtau
+ - Aqtobe
+ - Araguaina
+ - Asmera
- astro
- astrojs
+ - astrolib
+ - Atikokan
+ - Atka
+ - Atyrau
- autodocs
+ - automations
+ - Automations
- autoplay
+ - autoset
+ - AVATARBOX
- awst
- backgroun
- backgroundfill
+ - Baja
+ - Banderas
+ - Barthelemy
- basemaps
+ - Bator
- Beamer
- behance
- Bento
- Binni
+ - Blocke
+ - Blockquotes
+ - blueprintjs
- boxshadow
- branchname
+ - Branco
- bunx
+ - burndown
+ - burndowns
+ - Busingen
- bvaughn
- Byrom
- callees
- camdynn
- Camdynn
+ - Catamarca
+ - chartjs
+ - Choibalsan
+ - Chuuk
+ - Ciudad
- cjsx
- classname
- clsx
+ - cmax
- cmdk
+ - cmin
- codebl
- codefence
+ - codemark
- codemirror
- codepreview
- codesandbox
- codespace
- codespaces
+ - collab
- Colm
- colorwheel
+ - colwidth
+ - commitish
- commitlint
- commitlintrc
+ - Comod
+ - Comonent
- compat
+ - Concepting
- connectingfrom
- connectingto
+ - connectionindicator
- connectionline
+ - consequat
- Consolas
- consts
- Consulty
- coverflow
- cpath
+ - Creston
- crossorigin
+ - ÇŞĞIİÖÜA
- csvg
- ctsx
+ - Cuiaba
+ - customkeymap
+ - Dacca
+ - Danmarkshavn
+ - dashdraw
- datetime
- dbaeumer
+ - decos
- degit
+ - deserunt
- Designboise
+ - Dili
- directus
+ - doctag
- docummentation
- dotenv
+ - dotlottie
+ - downlaods
- dribbble
+ - dropcursor
- dropmenu
- dsznajder
- Duarte
+ - duis
+ - Dumont
+ - duplicable
- dwireframe
+ - edgelabel
+ - edgeupdater
+ - Efate
+ - Eirunepe
- Elsakaan
- Embla
+ - encapsulte
+ - Enderbury
+ - enim
+ - Ensenada
- esbenp
- eslintcache
+ - Eucla
- evenodd
+ - exitable
- explor
- Explor
- Extralight
+ - Fakaofo
+ - favorited
+ - FAVORITED
- Figtree
- filesize
- fkey
+ - flipbehavior
- floatingedges
- focusable
+ - fromnow
- frontmatter
+ - gantt
+ - Gantt
+ - gapcursor
+ - Gapcursor
+ - giest
- Gitbook
- Gloock
- googleanalytics
+ - gradia
- grotesk
- grouphover
- haspopup
@@ -100,51 +186,109 @@ words:
- hellsangels
- heroicons
- highlightjs
+ - hightlights
+ - hitbox
- hljs
- hookform
+ - Hovd
+ - Hoverable
+ - Hubspot
+ - HYWE
- ianvs
- Ideanote
+ - iefix
- Ifwg
+ - indexeddb
+ - Indexeddb
+ - Inuvik
+ - Issuefields
- jiti
- jscoverage
- jspm
+ - JTBD
+ - Jujuy
- Kanban
+ - Kanton
+ - keymap
+ - Keymap
+ - Khandyga
+ - Kiritimati
+ - Kitts
- kohler
+ - Kolkata
+ - Kosrae
+ - Kralendijk
+ - Kuala
- labil
+ - laquo
- Leveln
+ - Lindeman
- linecap
- linejoin
- Lnan
- lockb
- Logomark
+ - Longyearbyen
+ - lottiefiles
+ - lowlight
+ - Lowlight
- lucide
+ - lumkey
+ - Lumpur
+ - machine
+ - Magadan
+ - Mahe
- Malyavko
+ - Manaus
- mapbox
+ - marching
+ - Marigot
+ - Marino
+ - matching
+ - Mayen
+ - measurables
- Memoji
- Menlo
+ - MENUBOX
+ - Metlakatla
- microbundle
- mikestead
+ - Minh
- minimise
- Mintlify
- mjsx
+ - mollit
- monokai
- monorepoing
+ - Moresby
- mousewheel
- mtsx
+ - Murdo
- neonctl
- neondatabase
+ - Nera
- nesw
- Neue
- nextjs
+ - Nipigon
+ - nivo
+ - nocheck
- nodesselection
- nodrag
+ - noopener
- nopan
+ - noreferrer
+ - Noronha
+ - Norte
- Noto
- nowrap
- nums
+ - Nuuk
- nuxt
- nzst
- odzdpcvclydcqawdagdt
+ - officia
+ - Ojinaga
- ondark
- onwarn
- optimisations
@@ -153,14 +297,26 @@ words:
- packagejson
- pacocoursey
- pageview
+ - Pago
+ - Pandang
+ - Pangnirtung
- pannable
+ - passowrd
+ - pathline
- peduarte
+ - Pendo
- pids
- Pinterest
- pkce
+ - Planfoundry
+ - plutio
+ - Pohnpei
+ - popperjs
- Postgrest
- posthog
- posx
+ - powerlines
+ - Preconfigured
- preconnect
- prerender
- Presstek
@@ -168,29 +324,53 @@ words:
- prodkthero
- progressbar
- proptected
+ - prosemirror
+ - Prosemirror
- Psnhw
+ - Punta
+ - Qostanay
- quickstart
+ - Qyzylorda
+ - raquo
- Ratelimit
- reactflow
+ - reparent
- resizer
- revolutionvodka
- rgba
+ - Rica
+ - Rioja
- Ritalic
+ - Rivadavia
- Roadmaps
- rotatex
+ - Rothera
+ - rowspan
+ - Sablon
- sandpack
+ - Santarem
+ - Santo
+ - scatterplot
+ - Scoresbysund
- scroller
- Segoe
+ - selectednode
- selectionpane
+ - seperator
+ - servicemark
- shadcn
+ - Shiprock
- signin
+ - signup
- slidek
- sonner
- Squircle
- squoosh
- srcdoc
+ - Srednekolymsk
- sslmode
- Stabil
+ - Starke
- starterkit
- starterkits
- styledictionary
@@ -199,23 +379,37 @@ words:
- stylesheet
- subgrid
- subline
+ - sublist
+ - Sublist
- supabase
- superjson
- SVGR
- Swiper
+ - Syowa
- tada
- tailwindcss
- tamasfe
- tanstack
- textareas
- textbg
+ - textblock
+ - Textblock
- textnodes
+ - textwrapper
- Themeing
- thollander
- tiktok
+ - timebox
+ - timeboxed
+ - TINYBIRD
+ - tippyjs
+ - tiptap
+ - Tiptap
+ - Tiraspol
- todos
- tokensstudent
- tokentype
+ - Tongatapu
- topbar
- tovuti
- transitionall
@@ -227,30 +421,55 @@ words:
- tsconfigs
- tseslint
- tsup
+ - tubro
- Tuite
- turborepo
- typecheck
- typeof
- typesafe
+ - Ujung
+ - Ulaanbaatar
+ - Ulan
+ - ullamco
+ - unfavorited
+ - UNFAVORITED
- unifiedjs
- Uniforma
- unkey
+ - unstarted
+ - Unstarted
- uploadthing
+ - upvoted
- upvoters
- upvotes
- upvoting
+ - Urville
+ - Ushuaia
+ - uuidv
+ - Uzhgorod
- vaul
+ - Velho
+ - Velit
- vercel
+ - Vevay
- viewports
- vuepress
- waitlist
+ - webp
- wght
+ - Winamac
- wireframe
- wireframes
- WITA
- wscript
- xyflow
+ - Yada
+ - Yakutat
+ - Yancowinna
- yoav
+ - zipball
- zoomable
- zoompane
- ZUEP
+ - zustand
+ - zxcvbn
diff --git a/package.json b/package.json
index 74d26dd..9f193c4 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,8 @@
"workspaces": [
"apps/*",
"packages/*",
- "packages/config/*"
+ "packages/config/*",
+ "packages/editor/*"
],
"scripts": {
"commit": "git-cz",
@@ -43,7 +44,7 @@
}
},
"dependencies": {
- "supabase": "^1.192.5"
+ "supabase": "^1.200.3"
},
"devDependencies": {
"@changesets/cli": "^2.27.7",
@@ -56,8 +57,8 @@
"@prodkt/tsconfig": "workspace:*",
"@types/bun": "latest",
"@types/eslint": "^9.6.1",
- "@types/node": "^22.5.5",
- "@types/yargs": "^17.0.32",
+ "@types/node": "^22.6.1",
+ "@types/yargs": "^17.0.33",
"commitizen": "^4.3.0",
"cspell": "^8.11.0",
"eslint": "^9.7.0",
@@ -69,7 +70,7 @@
"prettier": "^3.3.3",
"prettier-plugin-astro": "^0.14.1",
"prettier-plugin-packagejson": "^2.5.1",
- "turbo": "^2.0.7",
+ "turbo": "^2.1.3",
"typescript": "^5.5.4",
"yargs": "^17.7.2"
},
diff --git a/packages/assets/ampersand/ampersand-pattern.svg b/packages/assets/ampersand/ampersand-pattern.svg
new file mode 100644
index 0000000..b8f2cf9
--- /dev/null
+++ b/packages/assets/ampersand/ampersand-pattern.svg
@@ -0,0 +1,23 @@
+
diff --git a/packages/assets/ampersand/appCircles_lg_opt.avif b/packages/assets/ampersand/appCircles_lg_opt.avif
new file mode 100644
index 0000000..6e974b2
Binary files /dev/null and b/packages/assets/ampersand/appCircles_lg_opt.avif differ
diff --git a/packages/assets/ampersand/connectionLines.svg b/packages/assets/ampersand/connectionLines.svg
new file mode 100644
index 0000000..7517f93
--- /dev/null
+++ b/packages/assets/ampersand/connectionLines.svg
@@ -0,0 +1,10 @@
+
diff --git a/packages/assets/ampersand/figmaCircle1680w_md_opt.avif b/packages/assets/ampersand/figmaCircle1680w_md_opt.avif
new file mode 100644
index 0000000..bdc34b6
Binary files /dev/null and b/packages/assets/ampersand/figmaCircle1680w_md_opt.avif differ
diff --git a/packages/assets/ampersand/lockSwiper_md_opt.avif b/packages/assets/ampersand/lockSwiper_md_opt.avif
new file mode 100644
index 0000000..506cbaf
Binary files /dev/null and b/packages/assets/ampersand/lockSwiper_md_opt.avif differ
diff --git a/packages/assets/ampersand/logoOnlyMock_sm_opt.avif b/packages/assets/ampersand/logoOnlyMock_sm_opt.avif
new file mode 100644
index 0000000..a1e6261
Binary files /dev/null and b/packages/assets/ampersand/logoOnlyMock_sm_opt.avif differ
diff --git a/packages/assets/ampersand/menu-example.webp b/packages/assets/ampersand/menu-example.webp
new file mode 100644
index 0000000..972e4a5
Binary files /dev/null and b/packages/assets/ampersand/menu-example.webp differ
diff --git a/packages/assets/avatars/bryan-funk-portrait-xl.avif b/packages/assets/avatars/bryan-funk-portrait-xl.avif
new file mode 100644
index 0000000..19bc599
Binary files /dev/null and b/packages/assets/avatars/bryan-funk-portrait-xl.avif differ
diff --git a/packages/assets/bryan-funk/bryan-funk-portrait-xl.avif b/packages/assets/bryan-funk/bryan-funk-portrait-xl.avif
new file mode 100644
index 0000000..f4de095
Binary files /dev/null and b/packages/assets/bryan-funk/bryan-funk-portrait-xl.avif differ
diff --git a/packages/assets/features/radial1.svg b/packages/assets/features/radial1.svg
new file mode 100644
index 0000000..6f44686
--- /dev/null
+++ b/packages/assets/features/radial1.svg
@@ -0,0 +1,19 @@
+
diff --git a/packages/assets/features/radial2.svg b/packages/assets/features/radial2.svg
new file mode 100644
index 0000000..74eb850
--- /dev/null
+++ b/packages/assets/features/radial2.svg
@@ -0,0 +1,19 @@
+
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.eot b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.eot
new file mode 100644
index 0000000..08c07ed
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.eot differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.ttf b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.ttf
new file mode 100644
index 0000000..163426b
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.ttf differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.woff b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.woff
new file mode 100644
index 0000000..59e30a6
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.woff differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.woff2 b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.woff2
new file mode 100644
index 0000000..5d172f7
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Bold.woff2 differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.eot b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.eot
new file mode 100644
index 0000000..b4173a2
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.eot differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.ttf b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.ttf
new file mode 100644
index 0000000..fd6a66f
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.ttf differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.woff b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.woff
new file mode 100644
index 0000000..444f43e
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.woff differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.woff2 b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.woff2
new file mode 100644
index 0000000..9be909d
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Light.woff2 differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.eot b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.eot
new file mode 100644
index 0000000..ac9cf05
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.eot differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.ttf b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.ttf
new file mode 100644
index 0000000..d2829b2
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.ttf differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.woff b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.woff
new file mode 100644
index 0000000..952da1b
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.woff differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.woff2 b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.woff2
new file mode 100644
index 0000000..9f58460
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Medium.woff2 differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.eot b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.eot
new file mode 100644
index 0000000..96bb316
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.eot differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.ttf b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.ttf
new file mode 100644
index 0000000..f8aa7a8
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.ttf differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.woff b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.woff
new file mode 100644
index 0000000..3575e8b
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.woff differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.woff2 b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.woff2
new file mode 100644
index 0000000..6f651da
Binary files /dev/null and b/packages/assets/fonts/010-LabilGrotesk/LabilGrotesk-Regular.woff2 differ
diff --git a/packages/assets/fonts/010-LabilGrotesk/stylesheet.css b/packages/assets/fonts/010-LabilGrotesk/stylesheet.css
new file mode 100644
index 0000000..e213e29
--- /dev/null
+++ b/packages/assets/fonts/010-LabilGrotesk/stylesheet.css
@@ -0,0 +1,51 @@
+@font-face {
+ font-family: 'Labil Grotesk';
+ src: url('LabilGrotesk-Medium.eot');
+ src:
+ url('LabilGrotesk-Medium.eot?#iefix') format('embedded-opentype'),
+ url('LabilGrotesk-Medium.woff2') format('woff2'),
+ url('LabilGrotesk-Medium.woff') format('woff'),
+ url('LabilGrotesk-Medium.ttf') format('truetype');
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+ src: url('LabilGrotesk-Light.eot');
+ src:
+ url('LabilGrotesk-Light.eot?#iefix') format('embedded-opentype'),
+ url('LabilGrotesk-Light.woff2') format('woff2'),
+ url('LabilGrotesk-Light.woff') format('woff'),
+ url('LabilGrotesk-Light.ttf') format('truetype');
+ font-weight: 300;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+ src: url('LabilGrotesk-Bold.eot');
+ src:
+ url('LabilGrotesk-Bold.eot?#iefix') format('embedded-opentype'),
+ url('LabilGrotesk-Bold.woff2') format('woff2'),
+ url('LabilGrotesk-Bold.woff') format('woff'),
+ url('LabilGrotesk-Bold.ttf') format('truetype');
+ font-weight: bold;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Labil Grotesk';
+ src: url('LabilGrotesk-Regular.eot');
+ src:
+ url('LabilGrotesk-Regular.eot?#iefix') format('embedded-opentype'),
+ url('LabilGrotesk-Regular.woff2') format('woff2'),
+ url('LabilGrotesk-Regular.woff') format('woff'),
+ url('LabilGrotesk-Regular.ttf') format('truetype');
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+}
diff --git a/packages/assets/fonts/index.css b/packages/assets/fonts/index.css
new file mode 100644
index 0000000..6d7e605
--- /dev/null
+++ b/packages/assets/fonts/index.css
@@ -0,0 +1,24 @@
+@import './stylesheet.css';
+
+:root {
+ --font-geist-mono: 'Geist Mono';
+ --font-geist-sans: 'Geist Sans';
+ --font-ibm-plex-mono: 'IBM Plex Mono';
+ --font-labil-grotesk: 'Labil Grotesk';
+ --font-dm-sans-variable: 'DM Sans Variable';
+ --font-dm-mono: 'DM Mono';
+ --font-jetbrains-mono-variable: 'JetBrains Mono Variable';
+ --font-figtree-variable: 'Figtree Variable';
+ --font-labil-grotesk-variable: 'Labil Grotesk Variable';
+ --font-stabil-grotesk: 'Stabil Grotesk';
+ --font-attila-sans-classic: 'Attila Sans Classic';
+ --font-attila-sans-sharp: 'Attila Sans Sharp';
+ --font-victor-narrow: 'Victor Narrow';
+ --font-victor-sans: 'Victor Sans';
+ --font-victor-serif: 'Victor Serif';
+ --font-victor-serif-variable: 'Victor Serif Variable';
+ --font-uniforma: 'Uniforma';
+ --font-uniforma-variable: 'Uniforma Variable';
+ --font-space-grotesk-variable: 'Space Grotesk Variable';
+ --font-space-grotesk: 'Space Grotesk';
+}
diff --git a/packages/assets/fonts/stylesheet.css b/packages/assets/fonts/stylesheet.css
index 8724bb6..e98b9bd 100644
--- a/packages/assets/fonts/stylesheet.css
+++ b/packages/assets/fonts/stylesheet.css
@@ -1,3 +1,58 @@
+/* dm-sans-latin-wght-normal */
+@font-face {
+ font-family: 'DM Sans Variable';
+ font-style: normal;
+ font-display: swap;
+ font-weight: 100 1000;
+ src: url(https://cdn.jsdelivr.net/fontsource/fonts/dm-sans:vf@latest/latin-wght-normal.woff2)
+ format('woff2-variations');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* dm-mono-latin-400-normal */
+@font-face {
+ font-family: 'DM Mono';
+ font-style: normal;
+ font-display: swap;
+ font-weight: 400;
+ src:
+ url(https://cdn.jsdelivr.net/fontsource/fonts/dm-mono@latest/latin-400-normal.woff2)
+ format('woff2'),
+ url(https://cdn.jsdelivr.net/fontsource/fonts/dm-mono@latest/latin-400-normal.woff)
+ format('woff');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* jetbrains-mono-latin-wght-normal */
+@font-face {
+ font-family: 'JetBrains Mono Variable';
+ font-style: normal;
+ font-display: swap;
+ font-weight: 100 800;
+ src: url(https://cdn.jsdelivr.net/fontsource/fonts/jetbrains-mono:vf@latest/latin-wght-normal.woff2)
+ format('woff2-variations');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+/* figtree-latin-wght-normal */
+@font-face {
+ font-family: 'Figtree Variable';
+ font-style: normal;
+ font-display: swap;
+ font-weight: 300 900;
+ src: url(https://cdn.jsdelivr.net/fontsource/fonts/figtree:vf@latest/latin-wght-normal.woff2)
+ format('woff2-variations');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
+ U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
+ U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
@font-face {
font-family: 'Geist Sans';
src: url('./GeistVariable.ttf') format('truetype');
diff --git a/packages/assets/olio/olio/OlioCard.avif b/packages/assets/olio/olio/OlioCard.avif
new file mode 100644
index 0000000..c48b5f2
Binary files /dev/null and b/packages/assets/olio/olio/OlioCard.avif differ
diff --git a/packages/assets/olio/olio/olio_bg_1-2k.avif b/packages/assets/olio/olio/olio_bg_1-2k.avif
new file mode 100644
index 0000000..310f610
Binary files /dev/null and b/packages/assets/olio/olio/olio_bg_1-2k.avif differ
diff --git a/packages/assets/olio/olio/olio_ipad_1_opt.avif b/packages/assets/olio/olio/olio_ipad_1_opt.avif
new file mode 100644
index 0000000..e3b25d4
Binary files /dev/null and b/packages/assets/olio/olio/olio_ipad_1_opt.avif differ
diff --git a/packages/assets/olio/olio/olio_logotype_monochrome_onDark.svg b/packages/assets/olio/olio/olio_logotype_monochrome_onDark.svg
new file mode 100644
index 0000000..1e1caf7
--- /dev/null
+++ b/packages/assets/olio/olio/olio_logotype_monochrome_onDark.svg
@@ -0,0 +1,24 @@
+
+
+
diff --git a/packages/assets/olio/olio_bg_1-2k.avif b/packages/assets/olio/olio_bg_1-2k.avif
new file mode 100644
index 0000000..310f610
Binary files /dev/null and b/packages/assets/olio/olio_bg_1-2k.avif differ
diff --git a/packages/assets/olio/olio_ipad_1_opt.avif b/packages/assets/olio/olio_ipad_1_opt.avif
new file mode 100644
index 0000000..e3b25d4
Binary files /dev/null and b/packages/assets/olio/olio_ipad_1_opt.avif differ
diff --git a/packages/assets/olio/olio_logotype_monochrome_onDark.svg b/packages/assets/olio/olio_logotype_monochrome_onDark.svg
new file mode 100644
index 0000000..1e1caf7
--- /dev/null
+++ b/packages/assets/olio/olio_logotype_monochrome_onDark.svg
@@ -0,0 +1,24 @@
+
+
+
diff --git a/packages/assets/remix/Deco1.svg b/packages/assets/remix/Deco1.svg
new file mode 100644
index 0000000..cb4cb09
--- /dev/null
+++ b/packages/assets/remix/Deco1.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/assets/remix/Remix-Screen--iPhone15ProMax---01.avif b/packages/assets/remix/Remix-Screen--iPhone15ProMax---01.avif
new file mode 100644
index 0000000..127ab7d
Binary files /dev/null and b/packages/assets/remix/Remix-Screen--iPhone15ProMax---01.avif differ
diff --git a/packages/assets/remix/Remix-Screen--iPhone15ProMax---02.avif b/packages/assets/remix/Remix-Screen--iPhone15ProMax---02.avif
new file mode 100644
index 0000000..03c9eaa
Binary files /dev/null and b/packages/assets/remix/Remix-Screen--iPhone15ProMax---02.avif differ
diff --git a/packages/assets/remix/Remix-Screen--iPhone15ProMax---03.avif b/packages/assets/remix/Remix-Screen--iPhone15ProMax---03.avif
new file mode 100644
index 0000000..2c113d6
Binary files /dev/null and b/packages/assets/remix/Remix-Screen--iPhone15ProMax---03.avif differ
diff --git a/packages/assets/remix/Remix-Screen--iPhone15ProMax---04.avif b/packages/assets/remix/Remix-Screen--iPhone15ProMax---04.avif
new file mode 100644
index 0000000..68785ac
Binary files /dev/null and b/packages/assets/remix/Remix-Screen--iPhone15ProMax---04.avif differ
diff --git a/packages/assets/remix/Remix-Screen--iPhone15ProMax---05.avif b/packages/assets/remix/Remix-Screen--iPhone15ProMax---05.avif
new file mode 100644
index 0000000..e63a691
Binary files /dev/null and b/packages/assets/remix/Remix-Screen--iPhone15ProMax---05.avif differ
diff --git a/packages/assets/remix/Remix-Screen--iPhone15ProMax---06.avif b/packages/assets/remix/Remix-Screen--iPhone15ProMax---06.avif
new file mode 100644
index 0000000..46c6f6e
Binary files /dev/null and b/packages/assets/remix/Remix-Screen--iPhone15ProMax---06.avif differ
diff --git a/packages/assets/remix/Remix-Screen--iPhone15ProMax---07.avif b/packages/assets/remix/Remix-Screen--iPhone15ProMax---07.avif
new file mode 100644
index 0000000..338ade5
Binary files /dev/null and b/packages/assets/remix/Remix-Screen--iPhone15ProMax---07.avif differ
diff --git a/packages/assets/remix/Remix-Screen--iPhone15ProMax---08.avif b/packages/assets/remix/Remix-Screen--iPhone15ProMax---08.avif
new file mode 100644
index 0000000..7fbfdfd
Binary files /dev/null and b/packages/assets/remix/Remix-Screen--iPhone15ProMax---08.avif differ
diff --git a/packages/assets/remix/Remix-Screen--iPhone15ProMax---09.avif b/packages/assets/remix/Remix-Screen--iPhone15ProMax---09.avif
new file mode 100644
index 0000000..b86694c
Binary files /dev/null and b/packages/assets/remix/Remix-Screen--iPhone15ProMax---09.avif differ
diff --git a/packages/assets/remix/iPhone15ProMax-DarkTitanium-96dpi-720h.avif b/packages/assets/remix/iPhone15ProMax-DarkTitanium-96dpi-720h.avif
new file mode 100644
index 0000000..1384c4e
Binary files /dev/null and b/packages/assets/remix/iPhone15ProMax-DarkTitanium-96dpi-720h.avif differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-1.png b/packages/assets/remix/isolated-elements/remixElement-1.png
new file mode 100644
index 0000000..33a5087
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-1.png differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-10.png b/packages/assets/remix/isolated-elements/remixElement-10.png
new file mode 100644
index 0000000..4ec408a
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-10.png differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-11.png b/packages/assets/remix/isolated-elements/remixElement-11.png
new file mode 100644
index 0000000..95658ea
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-11.png differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-2.png b/packages/assets/remix/isolated-elements/remixElement-2.png
new file mode 100644
index 0000000..7e23349
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-2.png differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-3.png b/packages/assets/remix/isolated-elements/remixElement-3.png
new file mode 100644
index 0000000..6168160
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-3.png differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-4.png b/packages/assets/remix/isolated-elements/remixElement-4.png
new file mode 100644
index 0000000..c8d9f14
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-4.png differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-5.png b/packages/assets/remix/isolated-elements/remixElement-5.png
new file mode 100644
index 0000000..f427f7b
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-5.png differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-6.png b/packages/assets/remix/isolated-elements/remixElement-6.png
new file mode 100644
index 0000000..3422186
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-6.png differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-7.png b/packages/assets/remix/isolated-elements/remixElement-7.png
new file mode 100644
index 0000000..c510442
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-7.png differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-8.png b/packages/assets/remix/isolated-elements/remixElement-8.png
new file mode 100644
index 0000000..5e3058b
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-8.png differ
diff --git a/packages/assets/remix/isolated-elements/remixElement-9.png b/packages/assets/remix/isolated-elements/remixElement-9.png
new file mode 100644
index 0000000..5ba220d
Binary files /dev/null and b/packages/assets/remix/isolated-elements/remixElement-9.png differ
diff --git a/packages/assets/remix/prodkt_card_13.avif b/packages/assets/remix/prodkt_card_13.avif
new file mode 100644
index 0000000..1787d63
Binary files /dev/null and b/packages/assets/remix/prodkt_card_13.avif differ
diff --git a/packages/assets/resume/BryanFunk_CV-Resume_v2_001_reduced.pdf b/packages/assets/resume/BryanFunk_CV-Resume_v2_001_reduced.pdf
new file mode 100644
index 0000000..2304be7
Binary files /dev/null and b/packages/assets/resume/BryanFunk_CV-Resume_v2_001_reduced.pdf differ
diff --git a/packages/assets/resume/bryan-funk-resume-promo.webp b/packages/assets/resume/bryan-funk-resume-promo.webp
new file mode 100644
index 0000000..d1b47c7
Binary files /dev/null and b/packages/assets/resume/bryan-funk-resume-promo.webp differ
diff --git a/packages/blocks/astro.config.mjs b/packages/blocks/astro.config.mjs
index 3a79d5d..cdb954c 100644
--- a/packages/blocks/astro.config.mjs
+++ b/packages/blocks/astro.config.mjs
@@ -10,7 +10,6 @@ import tailwind from '@astrojs/tailwind'
import { defineConfig } from 'astro/config'
import dotenv from 'dotenv'
-import postcss from './postcss.config.mjs'
import viteConfig from './vite.config.mjs'
dotenv.config()
@@ -22,18 +21,19 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url))
// https://astro.build/config
export default defineConfig({
- build: {
- rollupOptions: {
- output: {
- entryFileNames: 'client.js',
- chunkFileNames: 'client.js',
- assetFileNames: 'client.[ext]',
- },
- },
- },
+ // build: {
+ // rollupOptions: {
+ // output: {
+ // entryFileNames: 'client.js',
+ // chunkFileNames: 'client.js',
+ // assetFileNames: 'client.[ext]',
+ // },
+ // },
+ // },
integrations: [
react({
experimentalReactChildren: true,
+ include: ['**/react/*'],
}),
tailwind({
nesting: true,
@@ -41,15 +41,14 @@ export default defineConfig({
],
vite: {
...viteConfig,
- css: {
- postcss,
- },
+ // sourceMap: true,
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
ssr: {
+ // noExternal: ['swiper'],
external: ['image-size', 'tiny-glob'],
},
plugins: [],
diff --git a/packages/blocks/package.json b/packages/blocks/package.json
index 4676197..de74e20 100644
--- a/packages/blocks/package.json
+++ b/packages/blocks/package.json
@@ -30,21 +30,23 @@
"dependencies": {
"@astrojs/check": "0.9.3",
"@astrojs/react": "3.6.2",
- "@astrojs/tailwind": "^5.1.0",
+ "@astrojs/tailwind": "^5.1.1",
"@prodkt/ui": "workspace:*",
- "astro": "4.15.6",
+ "@vitejs/plugin-react": "^4.3.1",
+ "astro": "4.15.8",
"lucide-react": "^0.441.0",
"react": "18.3.1",
"react-dom": "18.3.1",
- "sass": "^1.78.0",
+ "sass": "^1.79.2",
"tailwind-merge": "^2.5.2",
- "tailwindcss": "^3.4.11",
- "tailwindcss-animate": "^1.0.7"
+ "tailwindcss": "^3.4.12",
+ "tailwindcss-animate": "^1.0.7",
+ "vite": "^5.4.7"
},
"devDependencies": {
"@prodkt/tailwind": "workspace:*",
"@types/node": "^22.5.5",
- "@types/react": "^18.3.6",
+ "@types/react": "^18.3.8",
"@types/react-dom": "^18.3.0",
"autoprefixer": "^9.0.0",
"postcss": "^8.4.47",
diff --git a/packages/blocks/postcss.config.mjs b/packages/blocks/postcss.config.mjs
index 579c095..67a1045 100644
--- a/packages/blocks/postcss.config.mjs
+++ b/packages/blocks/postcss.config.mjs
@@ -2,8 +2,8 @@ import tailwindConfigurations from './tailwindConfigurations.mjs'
export default {
'postcss-import': {},
- // 'tailwindcss/nesting': {},
- 'tailwind-css-nesting': {},
+ 'tailwindcss/nesting': {},
+ // 'tailwind-css-nesting': {},
tailwindUno: tailwindConfigurations,
autoprefixer: {},
}
diff --git a/packages/blocks/src/component-map.ts b/packages/blocks/src/component-map.ts
index 7789537..322e628 100644
--- a/packages/blocks/src/component-map.ts
+++ b/packages/blocks/src/component-map.ts
@@ -1,8 +1,6 @@
import TemplateTresLayout from './templates/tres/layouts/TresLayout.astro'
-import AmpersandHero from './templates/unique/components/ampersand-hero.astro'
import LevelnHero from './templates/unique/components/leveln-hero.astro'
import WarpLandingPage from './templates/unique/components/warp-landing-page.astro'
-import AmpersandLayout from './templates/unique/layouts/ampersand-hero-layout.astro'
import LevelnLayout from './templates/unique/layouts/leveln-hero-layout.astro'
import TemplateUnoAboutOne from './templates/uno/components/About_1.astro'
import TemplateUnoComponentTest from './templates/uno/components/ComponentTest.astro'
@@ -24,8 +22,6 @@ const componentMap: ComponentMap = {
WarpLandingPage,
TemplateUnoComponentTest,
LevelnLayout,
- AmpersandLayout,
- AmpersandHero,
LevelnHero,
}
diff --git a/packages/blocks/src/env.d.ts b/packages/blocks/src/env.d.ts
index e16c13c..c3727c5 100644
--- a/packages/blocks/src/env.d.ts
+++ b/packages/blocks/src/env.d.ts
@@ -1 +1,26 @@
///
+///
+
+declare module '*.avif' {
+ const src: string
+
+ export default src
+}
+
+declare module '*.svg' {
+ const src: string
+
+ export default src
+}
+
+declare module '*.webp' {
+ const src: string
+
+ export default src
+}
+
+declare module '*.png' {
+ const src: string
+
+ export default src
+}
diff --git a/packages/blocks/src/templates/dos/components/page-header-announcement.tsx b/packages/blocks/src/templates/dos/components/page-header-announcement.tsx
index 2ee9c9e..2459973 100644
--- a/packages/blocks/src/templates/dos/components/page-header-announcement.tsx
+++ b/packages/blocks/src/templates/dos/components/page-header-announcement.tsx
@@ -1,19 +1,12 @@
import { ArrowRight } from 'lucide-react'
-import { Separator } from '@prodkt/ui/primitives/separator'
-
export function DosAnnouncement() {
return (
- 🎉{' '}
- {' '}
- Introducing Blocks
+ 🎉 Introducing Blocks
Introducing Blocks
diff --git a/packages/blocks/src/templates/unique/assets/remix/Deco1.svg b/packages/blocks/src/templates/unique/assets/remix/Deco1.svg
new file mode 100644
index 0000000..cb4cb09
--- /dev/null
+++ b/packages/blocks/src/templates/unique/assets/remix/Deco1.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---01.avif b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---01.avif
new file mode 100644
index 0000000..127ab7d
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---01.avif differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---02.avif b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---02.avif
new file mode 100644
index 0000000..03c9eaa
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---02.avif differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---03.avif b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---03.avif
new file mode 100644
index 0000000..2c113d6
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---03.avif differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---04.avif b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---04.avif
new file mode 100644
index 0000000..68785ac
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---04.avif differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---05.avif b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---05.avif
new file mode 100644
index 0000000..e63a691
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---05.avif differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---06.avif b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---06.avif
new file mode 100644
index 0000000..46c6f6e
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---06.avif differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---07.avif b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---07.avif
new file mode 100644
index 0000000..338ade5
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---07.avif differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---08.avif b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---08.avif
new file mode 100644
index 0000000..7fbfdfd
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---08.avif differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---09.avif b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---09.avif
new file mode 100644
index 0000000..b86694c
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/Remix-Screen--iPhone15ProMax---09.avif differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/iPhone15ProMax-DarkTitanium-96dpi-720h.avif b/packages/blocks/src/templates/unique/assets/remix/iPhone15ProMax-DarkTitanium-96dpi-720h.avif
new file mode 100644
index 0000000..1384c4e
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/iPhone15ProMax-DarkTitanium-96dpi-720h.avif differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-1.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-1.png
new file mode 100644
index 0000000..33a5087
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-1.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-10.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-10.png
new file mode 100644
index 0000000..4ec408a
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-10.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-11.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-11.png
new file mode 100644
index 0000000..95658ea
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-11.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-2.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-2.png
new file mode 100644
index 0000000..7e23349
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-2.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-3.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-3.png
new file mode 100644
index 0000000..6168160
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-3.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-4.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-4.png
new file mode 100644
index 0000000..c8d9f14
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-4.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-5.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-5.png
new file mode 100644
index 0000000..f427f7b
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-5.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-6.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-6.png
new file mode 100644
index 0000000..3422186
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-6.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-7.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-7.png
new file mode 100644
index 0000000..c510442
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-7.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-8.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-8.png
new file mode 100644
index 0000000..5e3058b
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-8.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-9.png b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-9.png
new file mode 100644
index 0000000..5ba220d
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/isolated-elements/remixElement-9.png differ
diff --git a/packages/blocks/src/templates/unique/assets/remix/prodkt_card_13.avif b/packages/blocks/src/templates/unique/assets/remix/prodkt_card_13.avif
new file mode 100644
index 0000000..1787d63
Binary files /dev/null and b/packages/blocks/src/templates/unique/assets/remix/prodkt_card_13.avif differ
diff --git a/packages/blocks/src/templates/unique/components/ampersand-hero.astro b/packages/blocks/src/templates/unique/components/ampersand-hero.astro
deleted file mode 100644
index ff8387d..0000000
--- a/packages/blocks/src/templates/unique/components/ampersand-hero.astro
+++ /dev/null
@@ -1,350 +0,0 @@
----
-import '../tailwind/leveln.css'
-
-import { Image } from 'astro:assets'
-
-import BryanMemoji from '../assets/leveln-hero/bryanFunk_memoji_lg_opt.avif'
-import CamdynnMemoji from '../assets/leveln-hero/camdynn-test-memoji.avif'
-import LevelnMonochrome from '../assets/leveln-hero/leveln_logomark_pink.svg'
-import Background3 from '../assets/leveln-hero/levelnChartLine_fillBlur.svg'
-import Background2 from '../assets/leveln-hero/levelnChartLine_outline.svg'
-import MemojiGirlCelebrate_1 from '../assets/leveln-hero/memoji_girl_celebrate_1.png'
-import MemojiGirlHeartEyes_1 from '../assets/leveln-hero/memoji_girl_heart-eyes_1.png'
-import MemojiGirlHeartEyes_2 from '../assets/leveln-hero/memoji_girl_heart-eyes_2.png'
-import MemojiGirlPonder_1 from '../assets/leveln-hero/memoji_girl_ponder_1.png'
-import MemojiGirlQuiet_1 from '../assets/leveln-hero/memoji_girl_quiet_1.png'
-import MemojiGirlThumbsDown_1 from '../assets/leveln-hero/memoji_girl_thumbs-down_1.png'
-import MemojiGirlThumbsDown_2 from '../assets/leveln-hero/memoji_girl_thumbs-down_2.png'
-import MemojiGirlThumbsUp_1 from '../assets/leveln-hero/memoji_girl_thumbs-up_1.png'
-import MemojiGirlUgh_1 from '../assets/leveln-hero/memoji_girl_ugh_1.png'
-import PulseGreen from '../assets/leveln-hero/pulseCircle-green.svg'
-import PulseRed from '../assets/leveln-hero/pulseCircle-red.svg'
-import Layout from '../layouts/leveln-hero-layout.astro'
----
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/blocks/src/templates/unique/layouts/ampersand-hero-layout.astro b/packages/blocks/src/templates/unique/layouts/ampersand-hero-layout.astro
deleted file mode 100644
index a03a71f..0000000
--- a/packages/blocks/src/templates/unique/layouts/ampersand-hero-layout.astro
+++ /dev/null
@@ -1,77 +0,0 @@
----
-
----
-
-
-
-
-
-
-
-
-
-
-
- Prodkt
-
-
-
-
-
-
diff --git a/packages/blocks/tsconfig.json b/packages/blocks/tsconfig.json
index 6505c10..289f9ee 100644
--- a/packages/blocks/tsconfig.json
+++ b/packages/blocks/tsconfig.json
@@ -1,14 +1,17 @@
{
"extends": "astro/tsconfigs/strict",
"compilerOptions": {
- "jsx": "react-jsx",
- "jsxImportSource": "react",
- "verbatimModuleSyntax": false,
- "declarationMap": true,
- "declaration": true,
+ // "jsx": "react", // or "react-jsx" for React 17+
+ // "esModuleInterop": true,
+ // "allowSyntheticDefaultImports": true,
+ // "module": "ESNext",
+ // "target": "ESNext",
+ // "verbatimModuleSyntax": false,
+ // "declarationMap": true,
+ // "declaration": true,
"baseUrl": ".",
"paths": {
- "@/*": ["./src/*"]
+ "@/*": ["src/*"]
}
}
}
diff --git a/packages/blocks/vite.config.mjs b/packages/blocks/vite.config.mjs
index fcc9aec..7efb9e5 100644
--- a/packages/blocks/vite.config.mjs
+++ b/packages/blocks/vite.config.mjs
@@ -1,16 +1,16 @@
import { defineConfig } from 'vite'
export default defineConfig({
- build: {
- rollupOptions: {
- output: {
- // Set the main entry file to a fixed name
- entryFileNames: '_astro/client.js',
- // Keep chunk files with hashes to avoid conflicts with dynamic imports
- chunkFileNames: '_astro/client-dynamic.js',
- // Asset file names (for CSS, images, etc.) can also keep their hashed names
- assetFileNames: '_astro/client-[hash].[ext]',
- },
- },
- },
+ // build: {
+ // rollupOptions: {
+ // output: {
+ // // Set the main entry file to a fixed name
+ // entryFileNames: '_astro/client.js',
+ // // Keep chunk files with hashes to avoid conflicts with dynamic imports
+ // chunkFileNames: '_astro/client-dynamic.js',
+ // // Asset file names (for CSS, images, etc.) can also keep their hashed names
+ // assetFileNames: '_astro/client-[hash].[ext]',
+ // },
+ // },
+ // },
})
diff --git a/packages/config/eslint/package.json b/packages/config/eslint/package.json
index b9a8824..8ac2e4e 100644
--- a/packages/config/eslint/package.json
+++ b/packages/config/eslint/package.json
@@ -21,18 +21,18 @@
"@eslint-community/eslint-plugin-eslint-comments": "^4.3.0",
"@eslint/compat": "^1.1.1",
"@eslint/eslintrc": "^3.1.0",
- "@eslint/js": "^9.7.0",
+ "@eslint/js": "^9.11.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-jsdoc": "^48.7.0",
"eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-playwright": "^1.6.2",
- "eslint-plugin-react": "^7.34.4",
+ "eslint-plugin-react": "^7.36.1",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-regexp": "^2.6.0",
"eslint-plugin-security": "^3.0.1",
"eslint-plugin-tailwindcss": "^3.17.4",
"eslint-plugin-turbo": "^2.0.7",
- "globals": "^15.8.0",
+ "globals": "^15.9.0",
"typescript-eslint": "^7.16.1"
},
"devDependencies": {
diff --git a/packages/config/storybook/package.json b/packages/config/storybook/package.json
index 0401a4b..a561280 100644
--- a/packages/config/storybook/package.json
+++ b/packages/config/storybook/package.json
@@ -36,26 +36,26 @@
"@prodkt/assets": "workspace:*",
"@prodkt/utils": "workspace:*",
"@radix-ui/colors": "^3.0.0",
- "@storybook/addon-a11y": "^8.3.1",
- "@storybook/addon-essentials": "^8.3.1",
- "@storybook/addon-interactions": "^8.3.1",
- "@storybook/addon-links": "^8.3.1",
- "@storybook/addon-onboarding": "^8.3.1",
- "@storybook/addon-themes": "^8.3.1",
- "@storybook/addon-viewport": "^8.3.1",
- "@storybook/manager-api": "^8.3.1",
- "@storybook/react": "^8.3.1",
- "@storybook/react-vite": "^8.3.1",
- "@storybook/theming": "^8.3.1",
- "@storybook/types": "^8.3.1",
+ "@storybook/addon-a11y": "^8.3.2",
+ "@storybook/addon-essentials": "^8.3.2",
+ "@storybook/addon-interactions": "^8.3.2",
+ "@storybook/addon-links": "^8.3.2",
+ "@storybook/addon-onboarding": "^8.3.2",
+ "@storybook/addon-themes": "^8.3.2",
+ "@storybook/addon-viewport": "^8.3.2",
+ "@storybook/manager-api": "^8.3.2",
+ "@storybook/react": "^8.3.2",
+ "@storybook/react-vite": "^8.3.2",
+ "@storybook/theming": "^8.3.2",
+ "@storybook/types": "^8.3.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
- "storybook": "^8.3.1"
+ "storybook": "^8.3.2"
},
"devDependencies": {
"@prodkt/eslint": "workspace:*",
"@prodkt/tsconfig": "workspace:*",
- "@types/react": "^18.3.6",
+ "@types/react": "^18.3.8",
"@types/react-dom": "^18.3.0"
}
}
diff --git a/packages/config/storybook/src/configs/react-vite.ts b/packages/config/storybook/src/configs/react-vite.ts
index 861ecbc..3c6873d 100644
--- a/packages/config/storybook/src/configs/react-vite.ts
+++ b/packages/config/storybook/src/configs/react-vite.ts
@@ -1,32 +1,33 @@
import type { StorybookConfig } from '@storybook/react-vite'
-import { getAbsolutePath } from '@prodkt/utils/filesystem'
-
-const config = {
+const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
- getAbsolutePath('@storybook/addon-links'),
+ '@storybook/addon-links',
{
- name: getAbsolutePath('@storybook/addon-essentials'),
+ name: '@storybook/addon-essentials',
options: {
backgrounds: false,
},
},
- getAbsolutePath('@storybook/addon-onboarding'),
- getAbsolutePath('@storybook/addon-interactions'),
- getAbsolutePath('@storybook/addon-themes'),
- getAbsolutePath('@storybook/addon-a11y'),
+ '@storybook/addon-onboarding',
+ '@storybook/addon-interactions',
+ '@storybook/addon-themes',
+ '@storybook/addon-a11y',
],
framework: {
- name: getAbsolutePath('@storybook/react-vite') as '@storybook/react-vite',
+ name: '@storybook/react-vite',
options: {
strictMode: true,
},
},
- staticDirs: [getAbsolutePath('@prodkt/assets')],
+ staticDirs: ['../static'], // Ensure this is the correct path
docs: {
autodocs: 'tag',
},
-} satisfies StorybookConfig
+ core: {
+ builder: '@storybook/builder-vite',
+ },
+}
export default config
diff --git a/packages/config/storybook/src/theme.ts b/packages/config/storybook/src/theme.ts
index be46ef3..80b6d2b 100644
--- a/packages/config/storybook/src/theme.ts
+++ b/packages/config/storybook/src/theme.ts
@@ -1,28 +1,31 @@
-import { mauveDark, violetDark } from '@radix-ui/colors'
+import { grayDark, violetDark } from '@radix-ui/colors'
+
+import '@prodkt/assets/fonts/index.css'
+
import { create } from '@storybook/theming'
export default create({
base: 'dark',
- fontBase: 'var(--font-labil-grotesk)',
- fontCode: 'var(--font-ibm-plex-mono)',
- appContentBg: mauveDark.mauve1,
- appBg: mauveDark.mauve1,
- barBg: mauveDark.mauve1,
- inputBg: mauveDark.mauve3,
- buttonBg: mauveDark.mauve3,
- booleanBg: mauveDark.mauve3,
- appBorderColor: mauveDark.mauve2,
+ fontBase: 'var(--font-theme-sans), sans-serif',
+ fontCode: 'var(--font-theme-mono), monospace',
+ appContentBg: grayDark.gray3,
+ appBg: grayDark.gray1,
+ barBg: grayDark.gray3,
+ inputBg: grayDark.gray3,
+ buttonBg: grayDark.gray3,
+ booleanBg: grayDark.gray3,
+ appBorderColor: grayDark.gray4,
appBorderRadius: 8,
inputBorderRadius: 8,
- inputBorder: mauveDark.mauve6,
- buttonBorder: mauveDark.mauve6,
- textColor: mauveDark.mauve11,
+ inputBorder: grayDark.gray6,
+ buttonBorder: grayDark.gray6,
+ textColor: grayDark.gray11,
colorSecondary: violetDark.violet9,
colorPrimary: violetDark.violet9,
- barTextColor: mauveDark.mauve11,
+ barTextColor: grayDark.gray11,
barHoverColor: violetDark.violet9,
barSelectedColor: violetDark.violet9,
- inputTextColor: mauveDark.mauve11,
- textMutedColor: mauveDark.mauve10,
- textInverseColor: mauveDark.mauve1,
+ inputTextColor: grayDark.gray11,
+ textMutedColor: grayDark.gray10,
+ textInverseColor: grayDark.gray1,
})
diff --git a/packages/config/tailwind/package.json b/packages/config/tailwind/package.json
index 9070e09..d761514 100644
--- a/packages/config/tailwind/package.json
+++ b/packages/config/tailwind/package.json
@@ -8,7 +8,9 @@
"type": "module",
"exports": {
".": "./src/preset.ts",
- "./color": "./src/ghost.css"
+ "./color": "./src/color.css",
+ "./typography": "./src/typography.css",
+ "./ghost": "./src/ghost.css"
},
"scripts": {
"clean": "bun run rm -rf *.tsbuildinfo",
@@ -16,6 +18,7 @@
"typecheck": "tsc"
},
"dependencies": {
+ "@prodkt/assets": "workspace:*",
"@radix-ui/colors": "^3.0.0",
"@radix-ui/themes": "^3.1.3",
"@tailwindcss/aspect-ratio": "^0.4.2",
diff --git a/packages/config/tailwind/src/color.css b/packages/config/tailwind/src/color.css
index 2b42022..454c735 100644
--- a/packages/config/tailwind/src/color.css
+++ b/packages/config/tailwind/src/color.css
@@ -130,28 +130,6 @@
@tailwind components;
@tailwind utilities;
@tailwind base;
-:root {
- /* --background: 0 0% 100%;
- --foreground: 222.2 47.4% 11.2%;
- --muted: 210 40% 96.1%;
- --muted-foreground: 215.4 16.3% 46.9%;
- --card: 0 0% 100%;
- --card-foreground: 222.2 47.4% 11.2%;
- --popover: var(--red9);
- --popover-foreground: 222.2 47.4% 11.2%;
- --border: 214.3 31.8% 91.4%;
- --input: 214.3 31.8% 91.4%;
- --primary: 222.2 47.4% 11.2%;
- --primary-foreground: 210 40% 98%;
- --secondary: 210 40% 96.1%;
- --secondary-foreground: 222.2 47.4% 11.2%;
- --accent: 210 40% 96.1%;
- --accent-foreground: 222.2 47.4% 11.2%;
- --destructive: 0 100% 50%;
- --destructive-foreground: 210 40% 98%;
- --ring: 215 20.2% 65.1%;
- --radius: 0.5rem; */
-}
[data-accent-color='amber'] {
--accent1: var(--amber1);
@@ -965,6 +943,29 @@
--grayA12: var(--slateA12);
}
+:root {
+ --background: var(--gray2);
+ --foreground: var(--gray11);
+ --muted: var(--gray3);
+ --muted-foreground: var(--gray11);
+ --card: var(--gray2);
+ --card-foreground: var(--gray11);
+ --popover: var(--gray3);
+ --popover-foreground: var(--gray11);
+ --border: var(--grayA4);
+ --input: var(--gray4);
+ --primary: var(--accent9);
+ --primary-foreground: var(--accent2);
+ --secondary: var(--violet9);
+ --secondary-foreground: var(--violet12);
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
+ --destructive: 0 100% 50%;
+ --destructive-foreground: 210 40% 98%;
+ --ring: 215 20.2% 65.1%;
+ --radius: 0.5rem;
+}
+
@layer base {
:root {
--chart-1: 12 76% 61%;
diff --git a/packages/config/tailwind/src/ghost.css b/packages/config/tailwind/src/ghost.css
index 7d0d6c1..1e2588f 100644
--- a/packages/config/tailwind/src/ghost.css
+++ b/packages/config/tailwind/src/ghost.css
@@ -156,6 +156,20 @@ input:where([type='submit']) {
rgba(0, 0, 0, 0) 100%
);
}
+.gradientMask-to-t-50 {
+ mask-image: radial-gradient(
+ circle,
+ rgba(0, 0, 0, 1) 25%,
+ rgba(0, 0, 0, 0.5) 55%,
+ rgba(0, 0, 0, 0) 69%
+ );
+ -webkit-mask-image: radial-gradient(
+ circle,
+ rgba(0, 0, 0, 1) 25%,
+ rgba(0, 0, 0, 0.5) 55%,
+ rgba(0, 0, 0, 0) 69%
+ );
+}
.gradientMask-to-t-20 {
mask-image: linear-gradient(
180deg,
@@ -216,6 +230,18 @@ input:where([type='submit']) {
rgba(0, 0, 0, 1) 10%
);
}
+.gradientMask-to-b-40 {
+ mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(0, 0, 0, 1) 40%
+ );
+ -webkit-mask-image: linear-gradient(
+ 180deg,
+ rgba(255, 255, 255, 0) 0%,
+ rgba(0, 0, 0, 1) 40%
+ );
+}
.gradientMask-to-l {
mask-image: linear-gradient(
270deg,
@@ -255,7 +281,3 @@ input:where([type='submit']) {
rgba(0, 0, 0, 0) 80%
);
}
-
-.prodkt-blog-content a {
- @apply text-[var(--accent10)] font-normal underline underline-offset-4 !important;
-}
diff --git a/packages/config/tailwind/src/preset.ts b/packages/config/tailwind/src/preset.ts
index 3256b0e..eec58c4 100644
--- a/packages/config/tailwind/src/preset.ts
+++ b/packages/config/tailwind/src/preset.ts
@@ -1,3 +1,8 @@
+/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+
import type { Config } from 'tailwindcss'
import aspectRatio from '@tailwindcss/aspect-ratio'
@@ -5,13 +10,14 @@ import containerQueries from '@tailwindcss/container-queries'
import forms from '@tailwindcss/forms'
import typography from '@tailwindcss/typography'
import animate from 'tailwindcss-animate'
+import plugin from 'tailwindcss/plugin'
import { createPlugin } from 'windy-radix-palette'
import windyTypography from 'windy-radix-typography'
const colors = createPlugin()
export const prodktTailwindPreset: Config = {
- content: ['./src/**/*.{js,jsx,ts,tsx,mdx}'],
+ content: ['./src/**/*.{js,jsx,ts,tsx,mdx,astro}'],
presets: [windyTypography],
theme: {
extend: {
@@ -20,9 +26,820 @@ export const prodktTailwindPreset: Config = {
'radial-gradient(87.07% 87.07% at 52.38% 100%, var(--grayA1) 0%, var(--grayA6) 100%)',
'radial-gradient-2':
'radial-gradient(100.44% 141.42% at 0% 0%, var(--grayA1) 0%, var(--grayA6) 100%);',
+ 'radial-gradient': 'radial-gradient(var(--tw-gradient-stops));',
+ 'conic-gradient':
+ 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
},
colors: {
- background: 'var(--gray1)',
+ amber: {
+ 1: 'var(--amber1)',
+ 2: 'var(--amber2)',
+ 3: 'var(--amber3)',
+ 4: 'var(--amber4)',
+ 5: 'var(--amber5)',
+ 6: 'var(--amber6)',
+ 7: 'var(--amber7)',
+ 8: 'var(--amber8)',
+ 9: 'var(--amber9)',
+ 10: 'var(--amber10)',
+ 11: 'var(--amber11)',
+ 12: 'var(--amber12)',
+ a1: 'var(--amberA1)',
+ a2: 'var(--amberA2)',
+ a3: 'var(--amberA3)',
+ a4: 'var(--amberA4)',
+ a5: 'var(--amberA5)',
+ a6: 'var(--amberA6)',
+ a7: 'var(--amberA7)',
+ a8: 'var(--amberA8)',
+ a9: 'var(--amberA9)',
+ a10: 'var(--amberA10)',
+ a11: 'var(--amberA11)',
+ a12: 'var(--amberA12)',
+ },
+ blue: {
+ 1: 'var(--blue1)',
+ 2: 'var(--blue2)',
+ 3: 'var(--blue3)',
+ 4: 'var(--blue4)',
+ 5: 'var(--blue5)',
+ 6: 'var(--blue6)',
+ 7: 'var(--blue7)',
+ 8: 'var(--blue8)',
+ 9: 'var(--blue9)',
+ 10: 'var(--blue10)',
+ 11: 'var(--blue11)',
+ 12: 'var(--blue12)',
+ a1: 'var(--blueA1)',
+ a2: 'var(--blueA2)',
+ a3: 'var(--blueA3)',
+ a4: 'var(--blueA4)',
+ a5: 'var(--blueA5)',
+ a6: 'var(--blueA6)',
+ a7: 'var(--blueA7)',
+ a8: 'var(--blueA8)',
+ a9: 'var(--blueA9)',
+ a10: 'var(--blueA10)',
+ a11: 'var(--blueA11)',
+ a12: 'var(--blueA12)',
+ },
+ bronze: {
+ 1: 'var(--bronze1)',
+ 2: 'var(--bronze2)',
+ 3: 'var(--bronze3)',
+ 4: 'var(--bronze4)',
+ 5: 'var(--bronze5)',
+ 6: 'var(--bronze6)',
+ 7: 'var(--bronze7)',
+ 8: 'var(--bronze8)',
+ 9: 'var(--bronze9)',
+ 10: 'var(--bronze10)',
+ 11: 'var(--bronze11)',
+ 12: 'var(--bronze12)',
+ a1: 'var(--bronzeA1)',
+ a2: 'var(--bronzeA2)',
+ a3: 'var(--bronzeA3)',
+ a4: 'var(--bronzeA4)',
+ a5: 'var(--bronzeA5)',
+ a6: 'var(--bronzeA6)',
+ a7: 'var(--bronzeA7)',
+ a8: 'var(--bronzeA8)',
+ a9: 'var(--bronzeA9)',
+ a10: 'var(--bronzeA10)',
+ a11: 'var(--bronzeA11)',
+ a12: 'var(--bronzeA12)',
+ },
+ brown: {
+ 1: 'var(--brown1)',
+ 2: 'var(--brown2)',
+ 3: 'var(--brown3)',
+ 4: 'var(--brown4)',
+ 5: 'var(--brown5)',
+ 6: 'var(--brown6)',
+ 7: 'var(--brown7)',
+ 8: 'var(--brown8)',
+ 9: 'var(--brown9)',
+ 10: 'var(--brown10)',
+ 11: 'var(--brown11)',
+ 12: 'var(--brown12)',
+ a1: 'var(--brownA1)',
+ a2: 'var(--brownA2)',
+ a3: 'var(--brownA3)',
+ a4: 'var(--brownA4)',
+ a5: 'var(--brownA5)',
+ a6: 'var(--brownA6)',
+ a7: 'var(--brownA7)',
+ a8: 'var(--brownA8)',
+ a9: 'var(--brownA9)',
+ a10: 'var(--brownA10)',
+ a11: 'var(--brownA11)',
+ a12: 'var(--brownA12)',
+ },
+ crimson: {
+ 1: 'var(--crimson1)',
+ 2: 'var(--crimson2)',
+ 3: 'var(--crimson3)',
+ 4: 'var(--crimson4)',
+ 5: 'var(--crimson5)',
+ 6: 'var(--crimson6)',
+ 7: 'var(--crimson7)',
+ 8: 'var(--crimson8)',
+ 9: 'var(--crimson9)',
+ 10: 'var(--crimson10)',
+ 11: 'var(--crimson11)',
+ 12: 'var(--crimson12)',
+ a1: 'var(--crimsonA1)',
+ a2: 'var(--crimsonA2)',
+ a3: 'var(--crimsonA3)',
+ a4: 'var(--crimsonA4)',
+ a5: 'var(--crimsonA5)',
+ a6: 'var(--crimsonA6)',
+ a7: 'var(--crimsonA7)',
+ a8: 'var(--crimsonA8)',
+ a9: 'var(--crimsonA9)',
+ a10: 'var(--crimsonA10)',
+ a11: 'var(--crimsonA11)',
+ a12: 'var(--crimsonA12)',
+ },
+ cyan: {
+ 1: 'var(--cyan1)',
+ 2: 'var(--cyan2)',
+ 3: 'var(--cyan3)',
+ 4: 'var(--cyan4)',
+ 5: 'var(--cyan5)',
+ 6: 'var(--cyan6)',
+ 7: 'var(--cyan7)',
+ 8: 'var(--cyan8)',
+ 9: 'var(--cyan9)',
+ 10: 'var(--cyan10)',
+ 11: 'var(--cyan11)',
+ 12: 'var(--cyan12)',
+ a1: 'var(--cyanA1)',
+ a2: 'var(--cyanA2)',
+ a3: 'var(--cyanA3)',
+ a4: 'var(--cyanA4)',
+ a5: 'var(--cyanA5)',
+ a6: 'var(--cyanA6)',
+ a7: 'var(--cyanA7)',
+ a8: 'var(--cyanA8)',
+ a9: 'var(--cyanA9)',
+ a10: 'var(--cyanA10)',
+ a11: 'var(--cyanA11)',
+ a12: 'var(--cyanA12)',
+ },
+ gold: {
+ 1: 'var(--gold1)',
+ 2: 'var(--gold2)',
+ 3: 'var(--gold3)',
+ 4: 'var(--gold4)',
+ 5: 'var(--gold5)',
+ 6: 'var(--gold6)',
+ 7: 'var(--gold7)',
+ 8: 'var(--gold8)',
+ 9: 'var(--gold9)',
+ 10: 'var(--gold10)',
+ 11: 'var(--gold11)',
+ 12: 'var(--gold12)',
+ a1: 'var(--goldA1)',
+ a2: 'var(--goldA2)',
+ a3: 'var(--goldA3)',
+ a4: 'var(--goldA4)',
+ a5: 'var(--goldA5)',
+ a6: 'var(--goldA6)',
+ a7: 'var(--goldA7)',
+ a8: 'var(--goldA8)',
+ a9: 'var(--goldA9)',
+ a10: 'var(--goldA10)',
+ a11: 'var(--goldA11)',
+ a12: 'var(--goldA12)',
+ },
+ grass: {
+ 1: 'var(--grass1)',
+ 2: 'var(--grass2)',
+ 3: 'var(--grass3)',
+ 4: 'var(--grass4)',
+ 5: 'var(--grass5)',
+ 6: 'var(--grass6)',
+ 7: 'var(--grass7)',
+ 8: 'var(--grass8)',
+ 9: 'var(--grass9)',
+ 10: 'var(--grass10)',
+ 11: 'var(--grass11)',
+ 12: 'var(--grass12)',
+ a1: 'var(--grassA1)',
+ a2: 'var(--grassA2)',
+ a3: 'var(--grassA3)',
+ a4: 'var(--grassA4)',
+ a5: 'var(--grassA5)',
+ a6: 'var(--grassA6)',
+ a7: 'var(--grassA7)',
+ a8: 'var(--grassA8)',
+ a9: 'var(--grassA9)',
+ a10: 'var(--grassA10)',
+ a11: 'var(--grassA11)',
+ a12: 'var(--grassA12)',
+ },
+ green: {
+ 1: 'var(--green1)',
+ 2: 'var(--green2)',
+ 3: 'var(--green3)',
+ 4: 'var(--green4)',
+ 5: 'var(--green5)',
+ 6: 'var(--green6)',
+ 7: 'var(--green7)',
+ 8: 'var(--green8)',
+ 9: 'var(--green9)',
+ 10: 'var(--green10)',
+ 11: 'var(--green11)',
+ 12: 'var(--green12)',
+ a1: 'var(--greenA1)',
+ a2: 'var(--greenA2)',
+ a3: 'var(--greenA3)',
+ a4: 'var(--greenA4)',
+ a5: 'var(--greenA5)',
+ a6: 'var(--greenA6)',
+ a7: 'var(--greenA7)',
+ a8: 'var(--greenA8)',
+ a9: 'var(--greenA9)',
+ a10: 'var(--greenA10)',
+ a11: 'var(--greenA11)',
+ a12: 'var(--greenA12)',
+ },
+ indigo: {
+ 1: 'var(--indigo1)',
+ 2: 'var(--indigo2)',
+ 3: 'var(--indigo3)',
+ 4: 'var(--indigo4)',
+ 5: 'var(--indigo5)',
+ 6: 'var(--indigo6)',
+ 7: 'var(--indigo7)',
+ 8: 'var(--indigo8)',
+ 9: 'var(--indigo9)',
+ 10: 'var(--indigo10)',
+ 11: 'var(--indigo11)',
+ 12: 'var(--indigo12)',
+ a1: 'var(--indigoA1)',
+ a2: 'var(--indigoA2)',
+ a3: 'var(--indigoA3)',
+ a4: 'var(--indigoA4)',
+ a5: 'var(--indigoA5)',
+ a6: 'var(--indigoA6)',
+ a7: 'var(--indigoA7)',
+ a8: 'var(--indigoA8)',
+ a9: 'var(--indigoA9)',
+ a10: 'var(--indigoA10)',
+ a11: 'var(--indigoA11)',
+ a12: 'var(--indigoA12)',
+ },
+ iris: {
+ 1: 'var(--iris1)',
+ 2: 'var(--iris2)',
+ 3: 'var(--iris3)',
+ 4: 'var(--iris4)',
+ 5: 'var(--iris5)',
+ 6: 'var(--iris6)',
+ 7: 'var(--iris7)',
+ 8: 'var(--iris8)',
+ 9: 'var(--iris9)',
+ 10: 'var(--iris10)',
+ 11: 'var(--iris11)',
+ 12: 'var(--iris12)',
+ a1: 'var(--irisA1)',
+ a2: 'var(--irisA2)',
+ a3: 'var(--irisA3)',
+ a4: 'var(--irisA4)',
+ a5: 'var(--irisA5)',
+ a6: 'var(--irisA6)',
+ a7: 'var(--irisA7)',
+ a8: 'var(--irisA8)',
+ a9: 'var(--irisA9)',
+ a10: 'var(--irisA10)',
+ a11: 'var(--irisA11)',
+ a12: 'var(--irisA12)',
+ },
+ jade: {
+ 1: 'var(--jade1)',
+ 2: 'var(--jade2)',
+ 3: 'var(--jade3)',
+ 4: 'var(--jade4)',
+ 5: 'var(--jade5)',
+ 6: 'var(--jade6)',
+ 7: 'var(--jade7)',
+ 8: 'var(--jade8)',
+ 9: 'var(--jade9)',
+ 10: 'var(--jade10)',
+ 11: 'var(--jade11)',
+ 12: 'var(--jade12)',
+ a1: 'var(--jadeA1)',
+ a2: 'var(--jadeA2)',
+ a3: 'var(--jadeA3)',
+ a4: 'var(--jadeA4)',
+ a5: 'var(--jadeA5)',
+ a6: 'var(--jadeA6)',
+ a7: 'var(--jadeA7)',
+ a8: 'var(--jadeA8)',
+ a9: 'var(--jadeA9)',
+ a10: 'var(--jadeA10)',
+ a11: 'var(--jadeA11)',
+ a12: 'var(--jadeA12)',
+ },
+ lime: {
+ 1: 'var(--lime1)',
+ 2: 'var(--lime2)',
+ 3: 'var(--lime3)',
+ 4: 'var(--lime4)',
+ 5: 'var(--lime5)',
+ 6: 'var(--lime6)',
+ 7: 'var(--lime7)',
+ 8: 'var(--lime8)',
+ 9: 'var(--lime9)',
+ 10: 'var(--lime10)',
+ 11: 'var(--lime11)',
+ 12: 'var(--lime12)',
+ a1: 'var(--limeA1)',
+ a2: 'var(--limeA2)',
+ a3: 'var(--limeA3)',
+ a4: 'var(--limeA4)',
+ a5: 'var(--limeA5)',
+ a6: 'var(--limeA6)',
+ a7: 'var(--limeA7)',
+ a8: 'var(--limeA8)',
+ a9: 'var(--limeA9)',
+ a10: 'var(--limeA10)',
+ a11: 'var(--limeA11)',
+ a12: 'var(--limeA12)',
+ },
+ mauve: {
+ 1: 'var(--mauve1)',
+ 2: 'var(--mauve2)',
+ 3: 'var(--mauve3)',
+ 4: 'var(--mauve4)',
+ 5: 'var(--mauve5)',
+ 6: 'var(--mauve6)',
+ 7: 'var(--mauve7)',
+ 8: 'var(--mauve8)',
+ 9: 'var(--mauve9)',
+ 10: 'var(--mauve10)',
+ 11: 'var(--mauve11)',
+ 12: 'var(--mauve12)',
+ a1: 'var(--mauveA1)',
+ a2: 'var(--mauveA2)',
+ a3: 'var(--mauveA3)',
+ a4: 'var(--mauveA4)',
+ a5: 'var(--mauveA5)',
+ a6: 'var(--mauveA6)',
+ a7: 'var(--mauveA7)',
+ a8: 'var(--mauveA8)',
+ a9: 'var(--mauveA9)',
+ a10: 'var(--mauveA10)',
+ a11: 'var(--mauveA11)',
+ a12: 'var(--mauveA12)',
+ },
+ mint: {
+ 1: 'var(--mint1)',
+ 2: 'var(--mint2)',
+ 3: 'var(--mint3)',
+ 4: 'var(--mint4)',
+ 5: 'var(--mint5)',
+ 6: 'var(--mint6)',
+ 7: 'var(--mint7)',
+ 8: 'var(--mint8)',
+ 9: 'var(--mint9)',
+ 10: 'var(--mint10)',
+ 11: 'var(--mint11)',
+ 12: 'var(--mint12)',
+ a1: 'var(--mintA1)',
+ a2: 'var(--mintA2)',
+ a3: 'var(--mintA3)',
+ a4: 'var(--mintA4)',
+ a5: 'var(--mintA5)',
+ a6: 'var(--mintA6)',
+ a7: 'var(--mintA7)',
+ a8: 'var(--mintA8)',
+ a9: 'var(--mintA9)',
+ a10: 'var(--mintA10)',
+ a11: 'var(--mintA11)',
+ a12: 'var(--mintA12)',
+ },
+ olive: {
+ 1: 'var(--olive1)',
+ 2: 'var(--olive2)',
+ 3: 'var(--olive3)',
+ 4: 'var(--olive4)',
+ 5: 'var(--olive5)',
+ 6: 'var(--olive6)',
+ 7: 'var(--olive7)',
+ 8: 'var(--olive8)',
+ 9: 'var(--olive9)',
+ 10: 'var(--olive10)',
+ 11: 'var(--olive11)',
+ 12: 'var(--olive12)',
+ a1: 'var(--oliveA1)',
+ a2: 'var(--oliveA2)',
+ a3: 'var(--oliveA3)',
+ a4: 'var(--oliveA4)',
+ a5: 'var(--oliveA5)',
+ a6: 'var(--oliveA6)',
+ a7: 'var(--oliveA7)',
+ a8: 'var(--oliveA8)',
+ a9: 'var(--oliveA9)',
+ a10: 'var(--oliveA10)',
+ a11: 'var(--oliveA11)',
+ a12: 'var(--oliveA12)',
+ },
+ orange: {
+ 1: 'var(--orange1)',
+ 2: 'var(--orange2)',
+ 3: 'var(--orange3)',
+ 4: 'var(--orange4)',
+ 5: 'var(--orange5)',
+ 6: 'var(--orange6)',
+ 7: 'var(--orange7)',
+ 8: 'var(--orange8)',
+ 9: 'var(--orange9)',
+ 10: 'var(--orange10)',
+ 11: 'var(--orange11)',
+ 12: 'var(--orange12)',
+ a1: 'var(--orangeA1)',
+ a2: 'var(--orangeA2)',
+ a3: 'var(--orangeA3)',
+ a4: 'var(--orangeA4)',
+ a5: 'var(--orangeA5)',
+ a6: 'var(--orangeA6)',
+ a7: 'var(--orangeA7)',
+ a8: 'var(--orangeA8)',
+ a9: 'var(--orangeA9)',
+ a10: 'var(--orangeA10)',
+ a11: 'var(--orangeA11)',
+ a12: 'var(--orangeA12)',
+ },
+ pink: {
+ 1: 'var(--pink1)',
+ 2: 'var(--pink2)',
+ 3: 'var(--pink3)',
+ 4: 'var(--pink4)',
+ 5: 'var(--pink5)',
+ 6: 'var(--pink6)',
+ 7: 'var(--pink7)',
+ 8: 'var(--pink8)',
+ 9: 'var(--pink9)',
+ 10: 'var(--pink10)',
+ 11: 'var(--pink11)',
+ 12: 'var(--pink12)',
+ a1: 'var(--pinkA1)',
+ a2: 'var(--pinkA2)',
+ a3: 'var(--pinkA3)',
+ a4: 'var(--pinkA4)',
+ a5: 'var(--pinkA5)',
+ a6: 'var(--pinkA6)',
+ a7: 'var(--pinkA7)',
+ a8: 'var(--pinkA8)',
+ a9: 'var(--pinkA9)',
+ a10: 'var(--pinkA10)',
+ a11: 'var(--pinkA11)',
+ a12: 'var(--pinkA12)',
+ },
+ plum: {
+ 1: 'var(--plum1)',
+ 2: 'var(--plum2)',
+ 3: 'var(--plum3)',
+ 4: 'var(--plum4)',
+ 5: 'var(--plum5)',
+ 6: 'var(--plum6)',
+ 7: 'var(--plum7)',
+ 8: 'var(--plum8)',
+ 9: 'var(--plum9)',
+ 10: 'var(--plum10)',
+ 11: 'var(--plum11)',
+ 12: 'var(--plum12)',
+ a1: 'var(--plumA1)',
+ a2: 'var(--plumA2)',
+ a3: 'var(--plumA3)',
+ a4: 'var(--plumA4)',
+ a5: 'var(--plumA5)',
+ a6: 'var(--plumA6)',
+ a7: 'var(--plumA7)',
+ a8: 'var(--plumA8)',
+ a9: 'var(--plumA9)',
+ a10: 'var(--plumA10)',
+ a11: 'var(--plumA11)',
+ a12: 'var(--plumA12)',
+ },
+ purple: {
+ 1: 'var(--purple1)',
+ 2: 'var(--purple2)',
+ 3: 'var(--purple3)',
+ 4: 'var(--purple4)',
+ 5: 'var(--purple5)',
+ 6: 'var(--purple6)',
+ 7: 'var(--purple7)',
+ 8: 'var(--purple8)',
+ 9: 'var(--purple9)',
+ 10: 'var(--purple10)',
+ 11: 'var(--purple11)',
+ 12: 'var(--purple12)',
+ a1: 'var(--purpleA1)',
+ a2: 'var(--purpleA2)',
+ a3: 'var(--purpleA3)',
+ a4: 'var(--purpleA4)',
+ a5: 'var(--purpleA5)',
+ a6: 'var(--purpleA6)',
+ a7: 'var(--purpleA7)',
+ a8: 'var(--purpleA8)',
+ a9: 'var(--purpleA9)',
+ a10: 'var(--purpleA10)',
+ a11: 'var(--purpleA11)',
+ a12: 'var(--purpleA12)',
+ },
+ red: {
+ 1: 'var(--red1)',
+ 2: 'var(--red2)',
+ 3: 'var(--red3)',
+ 4: 'var(--red4)',
+ 5: 'var(--red5)',
+ 6: 'var(--red6)',
+ 7: 'var(--red7)',
+ 8: 'var(--red8)',
+ 9: 'var(--red9)',
+ 10: 'var(--red10)',
+ 11: 'var(--red11)',
+ 12: 'var(--red12)',
+ a1: 'var(--redA1)',
+ a2: 'var(--redA2)',
+ a3: 'var(--redA3)',
+ a4: 'var(--redA4)',
+ a5: 'var(--redA5)',
+ a6: 'var(--redA6)',
+ a7: 'var(--redA7)',
+ a8: 'var(--redA8)',
+ a9: 'var(--redA9)',
+ a10: 'var(--redA10)',
+ a11: 'var(--redA11)',
+ a12: 'var(--redA12)',
+ },
+ ruby: {
+ 1: 'var(--ruby1)',
+ 2: 'var(--ruby2)',
+ 3: 'var(--ruby3)',
+ 4: 'var(--ruby4)',
+ 5: 'var(--ruby5)',
+ 6: 'var(--ruby6)',
+ 7: 'var(--ruby7)',
+ 8: 'var(--ruby8)',
+ 9: 'var(--ruby9)',
+ 10: 'var(--ruby10)',
+ 11: 'var(--ruby11)',
+ 12: 'var(--ruby12)',
+ a1: 'var(--rubyA1)',
+ a2: 'var(--rubyA2)',
+ a3: 'var(--rubyA3)',
+ a4: 'var(--rubyA4)',
+ a5: 'var(--rubyA5)',
+ a6: 'var(--rubyA6)',
+ a7: 'var(--rubyA7)',
+ a8: 'var(--rubyA8)',
+ a9: 'var(--rubyA9)',
+ a10: 'var(--rubyA10)',
+ a11: 'var(--rubyA11)',
+ a12: 'var(--rubyA12)',
+ },
+ sage: {
+ 1: 'var(--sage1)',
+ 2: 'var(--sage2)',
+ 3: 'var(--sage3)',
+ 4: 'var(--sage4)',
+ 5: 'var(--sage5)',
+ 6: 'var(--sage6)',
+ 7: 'var(--sage7)',
+ 8: 'var(--sage8)',
+ 9: 'var(--sage9)',
+ 10: 'var(--sage10)',
+ 11: 'var(--sage11)',
+ 12: 'var(--sage12)',
+ a1: 'var(--sageA1)',
+ a2: 'var(--sageA2)',
+ a3: 'var(--sageA3)',
+ a4: 'var(--sageA4)',
+ a5: 'var(--sageA5)',
+ a6: 'var(--sageA6)',
+ a7: 'var(--sageA7)',
+ a8: 'var(--sageA8)',
+ a9: 'var(--sageA9)',
+ a10: 'var(--sageA10)',
+ a11: 'var(--sageA11)',
+ a12: 'var(--sageA12)',
+ },
+ sand: {
+ 1: 'var(--sand1)',
+ 2: 'var(--sand2)',
+ 3: 'var(--sand3)',
+ 4: 'var(--sand4)',
+ 5: 'var(--sand5)',
+ 6: 'var(--sand6)',
+ 7: 'var(--sand7)',
+ 8: 'var(--sand8)',
+ 9: 'var(--sand9)',
+ 10: 'var(--sand10)',
+ 11: 'var(--sand11)',
+ 12: 'var(--sand12)',
+ a1: 'var(--sandA1)',
+ a2: 'var(--sandA2)',
+ a3: 'var(--sandA3)',
+ a4: 'var(--sandA4)',
+ a5: 'var(--sandA5)',
+ a6: 'var(--sandA6)',
+ a7: 'var(--sandA7)',
+ a8: 'var(--sandA8)',
+ a9: 'var(--sandA9)',
+ a10: 'var(--sandA10)',
+ a11: 'var(--sandA11)',
+ a12: 'var(--sandA12)',
+ },
+ sky: {
+ 1: 'var(--sky1)',
+ 2: 'var(--sky2)',
+ 3: 'var(--sky3)',
+ 4: 'var(--sky4)',
+ 5: 'var(--sky5)',
+ 6: 'var(--sky6)',
+ 7: 'var(--sky7)',
+ 8: 'var(--sky8)',
+ 9: 'var(--sky9)',
+ 10: 'var(--sky10)',
+ 11: 'var(--sky11)',
+ 12: 'var(--sky12)',
+ a1: 'var(--skyA1)',
+ a2: 'var(--skyA2)',
+ a3: 'var(--skyA3)',
+ a4: 'var(--skyA4)',
+ a5: 'var(--skyA5)',
+ a6: 'var(--skyA6)',
+ a7: 'var(--skyA7)',
+ a8: 'var(--skyA8)',
+ a9: 'var(--skyA9)',
+ a10: 'var(--skyA10)',
+ a11: 'var(--skyA11)',
+ a12: 'var(--skyA12)',
+ },
+ slate: {
+ 1: 'var(--slate1)',
+ 2: 'var(--slate2)',
+ 3: 'var(--slate3)',
+ 4: 'var(--slate4)',
+ 5: 'var(--slate5)',
+ 6: 'var(--slate6)',
+ 7: 'var(--slate7)',
+ 8: 'var(--slate8)',
+ 9: 'var(--slate9)',
+ 10: 'var(--slate10)',
+ 11: 'var(--slate11)',
+ 12: 'var(--slate12)',
+ a1: 'var(--slateA1)',
+ a2: 'var(--slateA2)',
+ a3: 'var(--slateA3)',
+ a4: 'var(--slateA4)',
+ a5: 'var(--slateA5)',
+ a6: 'var(--slateA6)',
+ a7: 'var(--slateA7)',
+ a8: 'var(--slateA8)',
+ a9: 'var(--slateA9)',
+ a10: 'var(--slateA10)',
+ a11: 'var(--slateA11)',
+ a12: 'var(--slateA12)',
+ },
+ teal: {
+ 1: 'var(--teal1)',
+ 2: 'var(--teal2)',
+ 3: 'var(--teal3)',
+ 4: 'var(--teal4)',
+ 5: 'var(--teal5)',
+ 6: 'var(--teal6)',
+ 7: 'var(--teal7)',
+ 8: 'var(--teal8)',
+ 9: 'var(--teal9)',
+ 10: 'var(--teal10)',
+ 11: 'var(--teal11)',
+ 12: 'var(--teal12)',
+ a1: 'var(--tealA1)',
+ a2: 'var(--tealA2)',
+ a3: 'var(--tealA3)',
+ a4: 'var(--tealA4)',
+ a5: 'var(--tealA5)',
+ a6: 'var(--tealA6)',
+ a7: 'var(--tealA7)',
+ a8: 'var(--tealA8)',
+ a9: 'var(--tealA9)',
+ a10: 'var(--tealA10)',
+ a11: 'var(--tealA11)',
+ a12: 'var(--tealA12)',
+ },
+ tomato: {
+ 1: 'var(--tomato1)',
+ 2: 'var(--tomato2)',
+ 3: 'var(--tomato3)',
+ 4: 'var(--tomato4)',
+ 5: 'var(--tomato5)',
+ 6: 'var(--tomato6)',
+ 7: 'var(--tomato7)',
+ 8: 'var(--tomato8)',
+ 9: 'var(--tomato9)',
+ 10: 'var(--tomato10)',
+ 11: 'var(--tomato11)',
+ 12: 'var(--tomato12)',
+ a1: 'var(--tomatoA1)',
+ a2: 'var(--tomatoA2)',
+ a3: 'var(--tomatoA3)',
+ a4: 'var(--tomatoA4)',
+ a5: 'var(--tomatoA5)',
+ a6: 'var(--tomatoA6)',
+ a7: 'var(--tomatoA7)',
+ a8: 'var(--tomatoA8)',
+ a9: 'var(--tomatoA9)',
+ a10: 'var(--tomatoA10)',
+ a11: 'var(--tomatoA11)',
+ a12: 'var(--tomatoA12)',
+ },
+ violet: {
+ 1: 'var(--violet1)',
+ 2: 'var(--violet2)',
+ 3: 'var(--violet3)',
+ 4: 'var(--violet4)',
+ 5: 'var(--violet5)',
+ 6: 'var(--violet6)',
+ 7: 'var(--violet7)',
+ 8: 'var(--violet8)',
+ 9: 'var(--violet9)',
+ 10: 'var(--violet10)',
+ 11: 'var(--violet11)',
+ 12: 'var(--violet12)',
+ a1: 'var(--violetA1)',
+ a2: 'var(--violetA2)',
+ a3: 'var(--violetA3)',
+ a4: 'var(--violetA4)',
+ a5: 'var(--violetA5)',
+ a6: 'var(--violetA6)',
+ a7: 'var(--violetA7)',
+ a8: 'var(--violetA8)',
+ a9: 'var(--violetA9)',
+ a10: 'var(--violetA10)',
+ a11: 'var(--violetA11)',
+ a12: 'var(--violetA12)',
+ },
+ yellow: {
+ 1: 'var(--yellow1)',
+ 2: 'var(--yellow2)',
+ 3: 'var(--yellow3)',
+ 4: 'var(--yellow4)',
+ 5: 'var(--yellow5)',
+ 6: 'var(--yellow6)',
+ 7: 'var(--yellow7)',
+ 8: 'var(--yellow8)',
+ 9: 'var(--yellow9)',
+ 10: 'var(--yellow10)',
+ 11: 'var(--yellow11)',
+ 12: 'var(--yellow12)',
+ a1: 'var(--yellowA1)',
+ a2: 'var(--yellowA2)',
+ a3: 'var(--yellowA3)',
+ a4: 'var(--yellowA4)',
+ a5: 'var(--yellowA5)',
+ a6: 'var(--yellowA6)',
+ a7: 'var(--yellowA7)',
+ a8: 'var(--yellowA8)',
+ a9: 'var(--yellowA9)',
+ a10: 'var(--yellowA10)',
+ a11: 'var(--yellowA11)',
+ a12: 'var(--yellowA12)',
+ },
+ white: {
+ a1: 'var(--whiteA1)',
+ a2: 'var(--whiteA2)',
+ a3: 'var(--whiteA3)',
+ a4: 'var(--whiteA4)',
+ a5: 'var(--whiteA5)',
+ a6: 'var(--whiteA6)',
+ a7: 'var(--whiteA7)',
+ a8: 'var(--whiteA8)',
+ a9: 'var(--whiteA9)',
+ a10: 'var(--whiteA10)',
+ a11: 'var(--whiteA11)',
+ a12: 'var(--whiteA12)',
+ },
+ black: {
+ a1: 'var(--blackA1)',
+ a2: 'var(--blackA2)',
+ a3: 'var(--blackA3)',
+ a4: 'var(--blackA4)',
+ a5: 'var(--blackA5)',
+ a6: 'var(--blackA6)',
+ a7: 'var(--blackA7)',
+ a8: 'var(--blackA8)',
+ a9: 'var(--blackA9)',
+ a10: 'var(--blackA10)',
+ a11: 'var(--blackA11)',
+ a12: 'var(--blackA12)',
+ },
+ background: 'var(--gray2)',
foreground: 'var(--gray12)',
muted: {
@@ -172,15 +989,15 @@ export const prodktTailwindPreset: Config = {
12: 'var(--red12)',
},
- border: 'var(--gray4)',
- ring: 'var(--gray4)',
+ border: 'var(--grayA4)',
+ ring: 'var(--grayA4)',
},
borderRadius: {
radius: '0.5rem',
},
fontFamily: {
- sans: ['var(--font-labil-grotesk)'],
- mono: ['var(--font-ibm-plex-mono)'],
+ sans: ['var(--font-theme-sans)'],
+ mono: ['var(--font-theme-mono)'],
},
keyframes: {
'accordion-down': {
@@ -195,6 +1012,14 @@ export const prodktTailwindPreset: Config = {
'0%,70%,100%': { opacity: '1' },
'20%,50%': { opacity: '0' },
},
+ marquee: {
+ from: { transform: 'translateX(0)' },
+ to: { transform: 'translateX(calc(-100% - var(--gap)))' },
+ },
+ 'marquee-vertical': {
+ from: { transform: 'translateY(0)' },
+ to: { transform: 'translateY(calc(-100% - var(--gap)))' },
+ },
},
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
@@ -204,6 +1029,9 @@ export const prodktTailwindPreset: Config = {
spinSlow2x: 'spin 22.25s linear infinite',
spinSlow3x: 'spin 24.25s linear infinite',
spinSlow4x: 'spin 26.25s linear infinite',
+ marquee: 'marquee var(--duration) linear infinite',
+ 'marquee-vertical': 'marquee-vertical var(--duration) linear infinite',
+ 'border-beam': 'border-beam calc(var(--duration)*1s) infinite linear',
},
transitionDelay: {
0: '0s',
@@ -215,6 +1043,15 @@ export const prodktTailwindPreset: Config = {
500: '500ms',
700: '700ms',
1000: '1000ms',
+ 2000: '2000ms',
+ 3000: '3000ms',
+ 4000: '4000ms',
+ 5000: '5000ms',
+ 6000: '6000ms',
+ 7000: '7000ms',
+ 8000: '8000ms',
+ 9000: '9000ms',
+ 10000: '10000ms',
},
transitionDuration: {
DEFAULT: '150ms',
@@ -227,6 +1064,15 @@ export const prodktTailwindPreset: Config = {
500: '500ms',
700: '700ms',
1000: '1000ms',
+ 2000: '2000ms',
+ 3000: '3000ms',
+ 4000: '4000ms',
+ 5000: '5000ms',
+ 6000: '6000ms',
+ 7000: '7000ms',
+ 8000: '8000ms',
+ 9000: '9000ms',
+ 10000: '10000ms',
},
transitionProperty: {
none: 'none',
@@ -281,6 +1127,35 @@ export const prodktTailwindPreset: Config = {
},
},
plugins: [
+ // biome-ignore lint/suspicious/noExplicitAny:
+ plugin(({ matchUtilities, theme }: any) => {
+ matchUtilities(
+ {
+ // biome-ignore lint/suspicious/noExplicitAny:
+ 'translate-z': (value: any) => ({
+ '--tw-translate-z': value,
+ transform:
+ ' translate3d(var(--tw-translate-x), var(--tw-translate-y), var(--tw-translate-z)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))',
+ }), // this is actual CSS
+ // biome-ignore lint/suspicious/noExplicitAny:
+ 'text-shadow': (value: any) => ({
+ textShadow: value,
+ }),
+ },
+ { values: theme('textShadow') },
+ { values: theme('translate'), supportsNegativeValues: true },
+ )
+ }),
+ // biome-ignore lint/suspicious/noExplicitAny:
+ plugin(({ addUtilities }: any) => {
+ const newUtilities = {
+ '.text-shadow-glow': {
+ textShadow:
+ '0 0 5px rgba(0, 255, 0, 0.7), 0 0 10px rgba(0, 255, 0, 0.5)',
+ },
+ }
+ addUtilities(newUtilities)
+ }),
animate,
typography,
forms,
diff --git a/packages/config/tailwind/src/typography.css b/packages/config/tailwind/src/typography.css
new file mode 100644
index 0000000..e70e52c
--- /dev/null
+++ b/packages/config/tailwind/src/typography.css
@@ -0,0 +1,37 @@
+@import '@prodkt/assets/fonts/index.css';
+
+:root {
+ --font-theme-sans: var(--font-labil-grotesk);
+ --font-theme-mono: var(--font-ibm-plex-mono);
+}
+
+[data-typography='prodkt'],
+.radix-themes:where([data-typography='prodkt']) {
+ --font-theme-sans: var(--font-labil-grotesk);
+ --font-theme-mono: var(--font-ibm-plex-mono);
+}
+[data-typography='trendy'],
+.radix-themes:where([data-typography='trendy']) {
+ --font-theme-sans: var(--font-dm-sans-variable);
+ --font-theme-mono: var(--font-ibm-plex-mono);
+}
+[data-typography='techy'],
+.radix-themes:where([data-typography='techy']) {
+ --font-theme-sans: var(--font-space-grotesk);
+ --font-theme-mono: var(--font-jetbrains-mono-variable);
+}
+[data-typography='press'],
+.radix-themes:where([data-typography='press']) {
+ --font-theme-sans: var(--font-dm-sans-variable);
+ --font-theme-mono: var(--font-dm-mono);
+}
+[data-typography='giest'],
+.radix-themes:where([data-typography='giest']) {
+ --font-theme-sans: var(--font-geist-sans);
+ --font-theme-mono: var(--font-geist-mono);
+}
+[data-typography='steady'],
+.radix-themes:where([data-typography='steady']) {
+ --font-theme-sans: var(--font-figtree-variable);
+ --font-theme-mono: var(--font-jetbrains-mono-variable);
+}
diff --git a/packages/config/vite/package.json b/packages/config/vite/package.json
index fe713ea..5a40fbf 100644
--- a/packages/config/vite/package.json
+++ b/packages/config/vite/package.json
@@ -23,7 +23,7 @@
"dependencies": {
"@rollup/plugin-inject": "^5.0.5",
"@vitejs/plugin-react": "^4.3.1",
- "vite": "^5.4.6",
+ "vite": "^5.4.7",
"vite-tsconfig-paths": "^5.0.1",
"vue-tsc": "^2.1.6"
},
diff --git a/packages/config/vite/src/build.ts b/packages/config/vite/src/build.ts
index 6540488..7de080f 100644
--- a/packages/config/vite/src/build.ts
+++ b/packages/config/vite/src/build.ts
@@ -7,6 +7,7 @@ import type { Options as ExternalPluginOptions } from 'vite-plugin-external'
import { globbySync } from 'globby'
import preserveDirectives from 'rollup-plugin-preserve-directives'
+import sass from 'sass'
import { defineConfig, loadEnv } from 'vite'
import dtsPlugin from 'vite-plugin-dts'
import createExternal from 'vite-plugin-external'
@@ -36,10 +37,29 @@ export function buildConfig({
external?: ExternalPluginOptions
}) {
return defineConfig({
+ css: {
+ preprocessorOptions: {
+ scss: {
+ // This passes options to the Dart Sass compiler
+ sassOptions: {
+ silenceDeprecations: ['legacy-js-api'], // Silence the legacy API warnings
+ },
+ },
+ },
+ },
plugins: [
createExternal({
nodeBuiltins: true,
...external,
+ name: 'configure-sass',
+ configResolved() {
+ // Modify the Sass render function globally
+ sass.render = ((originalRender) => (options, callback) => {
+ // Add the silenceDeprecations option
+ options.silenceDeprecations = ['legacy-js-api']
+ originalRender.call(sass, options, callback)
+ })(sass.render)
+ },
}),
dtsPlugin({
compilerOptions: {
@@ -54,19 +74,14 @@ export function buildConfig({
}),
],
build: {
- sourcemap: true,
+ sourcemap: 'inline',
rollupOptions: {
plugins: [
preserveDirectives({
suppressPreserveModulesWarning: true,
}),
],
- external: [
- 'react',
- 'react-dom',
- '@dnd-kit',
- '@codesandbox/sandpack-react',
- ],
+ external: [/node_modules/],
output: {
preserveModules: true,
preserveModulesRoot: 'src',
diff --git a/packages/constants/package.json b/packages/constants/package.json
new file mode 100644
index 0000000..37d1aca
--- /dev/null
+++ b/packages/constants/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "@prodkt/constants",
+ "version": "0.1.0",
+ "private": true,
+ "exports": {
+ ".": "./src/index.ts",
+ "./*": "./src/*"
+ },
+ "main": "./src/index.ts",
+ "dependencies": {
+ "@nivo/core": "^0.87.0",
+ "lucide-react": "^0.446.0"
+ }
+}
diff --git a/packages/constants/src/analytics.ts b/packages/constants/src/analytics.ts
new file mode 100644
index 0000000..fdced3a
--- /dev/null
+++ b/packages/constants/src/analytics.ts
@@ -0,0 +1,79 @@
+// types
+
+import { TXAxisValues, TYAxisValues } from '@prodkt/types'
+
+export const ANALYTICS_TABS = [
+ { key: 'scope_and_demand', title: 'Scope and Demand' },
+ { key: 'custom', title: 'Custom Analytics' },
+]
+
+export const ANALYTICS_X_AXIS_VALUES: { value: TXAxisValues; label: string }[] =
+ [
+ {
+ value: 'state_id',
+ label: 'State name',
+ },
+ {
+ value: 'state__group',
+ label: 'State group',
+ },
+ {
+ value: 'priority',
+ label: 'Priority',
+ },
+ {
+ value: 'labels__id',
+ label: 'Label',
+ },
+ {
+ value: 'assignees__id',
+ label: 'Assignee',
+ },
+ {
+ value: 'estimate_point',
+ label: 'Estimate point',
+ },
+ {
+ value: 'issue_cycle__cycle_id',
+ label: 'Cycle',
+ },
+ {
+ value: 'issue_module__module_id',
+ label: 'Module',
+ },
+ {
+ value: 'completed_at',
+ label: 'Completed date',
+ },
+ {
+ value: 'target_date',
+ label: 'Due date',
+ },
+ {
+ value: 'start_date',
+ label: 'Start date',
+ },
+ {
+ value: 'created_at',
+ label: 'Created date',
+ },
+ ]
+
+export const ANALYTICS_Y_AXIS_VALUES: { value: TYAxisValues; label: string }[] =
+ [
+ {
+ value: 'issue_count',
+ label: 'Issue Count',
+ },
+ {
+ value: 'estimate',
+ label: 'Estimate',
+ },
+ ]
+
+export const DATE_KEYS = [
+ 'completed_at',
+ 'target_date',
+ 'start_date',
+ 'created_at',
+]
diff --git a/packages/constants/src/archives.ts b/packages/constants/src/archives.ts
new file mode 100644
index 0000000..48b6218
--- /dev/null
+++ b/packages/constants/src/archives.ts
@@ -0,0 +1,51 @@
+// types
+
+import { IProject } from '@prodkt/types'
+// icons
+import { ContrastIcon, DiceIcon, LayersIcon } from '@prodkt/ui/primitives'
+
+export const ARCHIVES_TAB_LIST: {
+ key: string
+ label: string
+ shouldRender: (projectDetails: IProject) => boolean
+}[] = [
+ {
+ key: 'issues',
+ label: 'Issues',
+ shouldRender: () => true,
+ },
+ {
+ key: 'cycles',
+ label: 'Cycles',
+ shouldRender: (projectDetails) => projectDetails.cycle_view,
+ },
+ {
+ key: 'modules',
+ label: 'Modules',
+ shouldRender: (projectDetails) => projectDetails.module_view,
+ },
+]
+
+export const PROJECT_ARCHIVES_BREADCRUMB_LIST: {
+ [key: string]: {
+ label: string
+ href: string
+ icon: React.FC & { className?: string }>
+ }
+} = {
+ issues: {
+ label: 'Issues',
+ href: '/issues',
+ icon: LayersIcon,
+ },
+ cycles: {
+ label: 'Cycles',
+ href: '/cycles',
+ icon: ContrastIcon,
+ },
+ modules: {
+ label: 'Modules',
+ href: '/modules',
+ icon: DiceIcon,
+ },
+}
diff --git a/packages/constants/src/auth.ts b/packages/constants/src/auth.ts
new file mode 100644
index 0000000..bd2d20d
--- /dev/null
+++ b/packages/constants/src/auth.ts
@@ -0,0 +1,370 @@
+import type { ReactNode } from "react";
+
+export enum EPageTypes {
+ PUBLIC = "PUBLIC",
+ NON_AUTHENTICATED = "NON_AUTHENTICATED",
+ SET_PASSWORD = "SET_PASSWORD",
+ ONBOARDING = "ONBOARDING",
+ AUTHENTICATED = "AUTHENTICATED",
+}
+
+export enum EAuthModes {
+ SIGN_IN = "SIGN_IN",
+ SIGN_UP = "SIGN_UP",
+}
+
+export enum EAuthSteps {
+ EMAIL = "EMAIL",
+ PASSWORD = "PASSWORD",
+ UNIQUE_CODE = "UNIQUE_CODE",
+}
+
+// TODO: remove this
+export enum EErrorAlertType {
+ BANNER_ALERT = "BANNER_ALERT",
+ INLINE_FIRST_NAME = "INLINE_FIRST_NAME",
+ INLINE_EMAIL = "INLINE_EMAIL",
+ INLINE_PASSWORD = "INLINE_PASSWORD",
+ INLINE_EMAIL_CODE = "INLINE_EMAIL_CODE",
+}
+
+export enum EAuthErrorCodes {
+ // Global
+ INSTANCE_NOT_CONFIGURED = "5000",
+ INVALID_EMAIL = "5005",
+ EMAIL_REQUIRED = "5010",
+ SIGNUP_DISABLED = "5015",
+ MAGIC_LINK_LOGIN_DISABLED = "5017",
+ PASSWORD_LOGIN_DISABLED = "5019",
+ SMTP_NOT_CONFIGURED = "5025",
+ // Password strength
+ INVALID_PASSWORD = "5020",
+ // Sign Up
+ USER_ACCOUNT_DEACTIVATED = "5019",
+ USER_ALREADY_EXIST = "5030",
+ AUTHENTICATION_FAILED_SIGN_UP = "5035",
+ REQUIRED_EMAIL_PASSWORD_SIGN_UP = "5040",
+ INVALID_EMAIL_SIGN_UP = "5045",
+ INVALID_EMAIL_MAGIC_SIGN_UP = "5050",
+ MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED = "5055",
+ // Sign In
+ USER_DOES_NOT_EXIST = "5060",
+ AUTHENTICATION_FAILED_SIGN_IN = "5065",
+ REQUIRED_EMAIL_PASSWORD_SIGN_IN = "5070",
+ INVALID_EMAIL_SIGN_IN = "5075",
+ INVALID_EMAIL_MAGIC_SIGN_IN = "5080",
+ MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED = "5085",
+ // Both Sign in and Sign up for magic
+ INVALID_MAGIC_CODE = "5090",
+ EXPIRED_MAGIC_CODE = "5095",
+ EMAIL_CODE_ATTEMPT_EXHAUSTED = "5100",
+ // Oauth
+ GOOGLE_NOT_CONFIGURED = "5105",
+ GITHUB_NOT_CONFIGURED = "5110",
+ GOOGLE_OAUTH_PROVIDER_ERROR = "5115",
+ GITHUB_OAUTH_PROVIDER_ERROR = "5120",
+ // Reset Password
+ INVALID_PASSWORD_TOKEN = "5125",
+ EXPIRED_PASSWORD_TOKEN = "5130",
+ // Change password
+ INCORRECT_OLD_PASSWORD = "5135",
+ MISSING_PASSWORD= "5138",
+ INVALID_NEW_PASSWORD = "5140",
+ // set passowrd
+ PASSWORD_ALREADY_SET = "5145",
+ // Admin
+ ADMIN_ALREADY_EXIST = "5150",
+ REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME = "5155",
+ INVALID_ADMIN_EMAIL = "5160",
+ INVALID_ADMIN_PASSWORD = "5165",
+ REQUIRED_ADMIN_EMAIL_PASSWORD = "5170",
+ ADMIN_AUTHENTICATION_FAILED = "5175",
+ ADMIN_USER_ALREADY_EXIST = "5180",
+ ADMIN_USER_DOES_NOT_EXIST = "5185",
+}
+
+export type TAuthErrorInfo = {
+ type: EErrorAlertType;
+ code: EAuthErrorCodes;
+ title: string;
+ message: ReactNode;
+};
+
+const errorCodeMessages: {
+ [key in EAuthErrorCodes]: { title: string; message: (email?: string | undefined) => ReactNode };
+} = {
+ // global
+ [EAuthErrorCodes.INSTANCE_NOT_CONFIGURED]: {
+ title: `Instance not configured`,
+ message: () => `Instance not configured. Please contact your administrator.`,
+ },
+ [EAuthErrorCodes.SIGNUP_DISABLED]: {
+ title: `Sign up disabled`,
+ message: () => `Sign up disabled. Please contact your administrator.`,
+ },
+ [EAuthErrorCodes.INVALID_PASSWORD]: {
+ title: `Invalid password`,
+ message: () => `Invalid password. Please try again.`,
+ },
+ [EAuthErrorCodes.SMTP_NOT_CONFIGURED]: {
+ title: `SMTP not configured`,
+ message: () => `SMTP not configured. Please contact your administrator.`,
+ },
+
+ // email check in both sign up and sign in
+ [EAuthErrorCodes.INVALID_EMAIL]: {
+ title: `Invalid email`,
+ message: () => `Invalid email. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.EMAIL_REQUIRED]: {
+ title: `Email required`,
+ message: () => `Email required. Please try again.`,
+ },
+
+ // sign up
+ [EAuthenticationErrorCodes.USER_ALREADY_EXIST]: {
+ title: `User already exists`,
+ message: (email = undefined) => (
+
+ Your account is already registered.
+
+ Sign In
+
+ now.
+
+ ),
+ },
+ [EAuthenticationErrorCodes.REQUIRED_EMAIL_PASSWORD_SIGN_UP]: {
+ title: `Email and password required`,
+ message: () => `Email and password required. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.AUTHENTICATION_FAILED_SIGN_UP]: {
+ title: `Authentication failed`,
+ message: () => `Authentication failed. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.INVALID_EMAIL_SIGN_UP]: {
+ title: `Invalid email`,
+ message: () => `Invalid email. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED]: {
+ title: `Email and code required`,
+ message: () => `Email and code required. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.INVALID_EMAIL_MAGIC_SIGN_UP]: {
+ title: `Invalid email`,
+ message: () => `Invalid email. Please try again.`,
+ },
+
+ // sign in
+ [EAuthenticationErrorCodes.USER_ACCOUNT_DEACTIVATED]: {
+ title: `User account deactivated`,
+ message: () => Your account is deactivated. Contact support@prodkt.cloud.
,
+ },
+ [EAuthenticationErrorCodes.USER_DOES_NOT_EXIST]: {
+ title: `User does not exist`,
+ message: (email = undefined) => (
+
+ ),
+ },
+ [EAuthenticationErrorCodes.REQUIRED_EMAIL_PASSWORD_SIGN_IN]: {
+ title: `Email and password required`,
+ message: () => `Email and password required. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.AUTHENTICATION_FAILED_SIGN_IN]: {
+ title: `Authentication failed`,
+ message: () => `Authentication failed. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.INVALID_EMAIL_SIGN_IN]: {
+ title: `Invalid email`,
+ message: () => `Invalid email. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED]: {
+ title: `Email and code required`,
+ message: () => `Email and code required. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.INVALID_EMAIL_MAGIC_SIGN_IN]: {
+ title: `Invalid email`,
+ message: () => `Invalid email. Please try again.`,
+ },
+
+ // Both Sign in and Sign up
+ [EAuthenticationErrorCodes.INVALID_MAGIC_CODE]: {
+ title: `Authentication failed`,
+ message: () => `Invalid magic code. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.EXPIRED_MAGIC_CODE]: {
+ title: `Expired magic code`,
+ message: () => `Expired magic code. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.EMAIL_CODE_ATTEMPT_EXHAUSTED]: {
+ title: `Expired magic code`,
+ message: () => `Expired magic code. Please try again.`,
+ },
+
+ // Oauth
+ [EAuthenticationErrorCodes.GOOGLE_NOT_CONFIGURED]: {
+ title: `Google not configured`,
+ message: () => `Google not configured. Please contact your administrator.`,
+ },
+ [EAuthenticationErrorCodes.GITHUB_NOT_CONFIGURED]: {
+ title: `GitHub not configured`,
+ message: () => `GitHub not configured. Please contact your administrator.`,
+ },
+ [EAuthenticationErrorCodes.GOOGLE_OAUTH_PROVIDER_ERROR]: {
+ title: `Google OAuth provider error`,
+ message: () => `Google OAuth provider error. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.GITHUB_OAUTH_PROVIDER_ERROR]: {
+ title: `GitHub OAuth provider error`,
+ message: () => `GitHub OAuth provider error. Please try again.`,
+ },
+
+ // Reset Password
+ [EAuthenticationErrorCodes.INVALID_PASSWORD_TOKEN]: {
+ title: `Invalid password token`,
+ message: () => `Invalid password token. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.EXPIRED_PASSWORD_TOKEN]: {
+ title: `Expired password token`,
+ message: () => `Expired password token. Please try again.`,
+ },
+
+ // Change password
+
+ [EAuthenticationErrorCodes.MISSING_PASSWORD]: {
+ title: `Password required`,
+ message: () => `Password required. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.INCORRECT_OLD_PASSWORD]: {
+ title: `Incorrect old password`,
+ message: () => `Incorrect old password. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.INVALID_NEW_PASSWORD]: {
+ title: `Invalid new password`,
+ message: () => `Invalid new password. Please try again.`,
+ },
+
+ // set password
+ [EAuthenticationErrorCodes.PASSWORD_ALREADY_SET]: {
+ title: `Password already set`,
+ message: () => `Password already set. Please try again.`,
+ },
+
+ // admin
+ [EAuthenticationErrorCodes.ADMIN_ALREADY_EXIST]: {
+ title: `Admin already exists`,
+ message: () => `Admin already exists. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME]: {
+ title: `Email, password and first name required`,
+ message: () => `Email, password and first name required. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.INVALID_ADMIN_EMAIL]: {
+ title: `Invalid admin email`,
+ message: () => `Invalid admin email. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.INVALID_ADMIN_PASSWORD]: {
+ title: `Invalid admin password`,
+ message: () => `Invalid admin password. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD]: {
+ title: `Email and password required`,
+ message: () => `Email and password required. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.ADMIN_AUTHENTICATION_FAILED]: {
+ title: `Authentication failed`,
+ message: () => `Authentication failed. Please try again.`,
+ },
+ [EAuthenticationErrorCodes.ADMIN_USER_ALREADY_EXIST]: {
+ title: `Admin user already exists`,
+ message: () => (
+
+ ),
+ },
+ [EAuthenticationErrorCodes.ADMIN_USER_DOES_NOT_EXIST]: {
+ title: `Admin user does not exist`,
+ message: () => (
+
+ ),
+ },
+};
+
+export const authErrorHandler = (
+ errorCode: EAuthenticationErrorCodes,
+ email?: string | undefined
+): TAuthErrorInfo | undefined => {
+ const bannerAlertErrorCodes = [
+ EAuthenticationErrorCodes.INSTANCE_NOT_CONFIGURED,
+ EAuthenticationErrorCodes.INVALID_EMAIL,
+ EAuthenticationErrorCodes.EMAIL_REQUIRED,
+ EAuthenticationErrorCodes.SIGNUP_DISABLED,
+ EAuthenticationErrorCodes.INVALID_PASSWORD,
+ EAuthenticationErrorCodes.SMTP_NOT_CONFIGURED,
+ EAuthenticationErrorCodes.USER_ALREADY_EXIST,
+ EAuthenticationErrorCodes.AUTHENTICATION_FAILED_SIGN_UP,
+ EAuthenticationErrorCodes.REQUIRED_EMAIL_PASSWORD_SIGN_UP,
+ EAuthenticationErrorCodes.INVALID_EMAIL_SIGN_UP,
+ EAuthenticationErrorCodes.INVALID_EMAIL_MAGIC_SIGN_UP,
+ EAuthenticationErrorCodes.MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED,
+ EAuthenticationErrorCodes.USER_DOES_NOT_EXIST,
+ EAuthenticationErrorCodes.AUTHENTICATION_FAILED_SIGN_IN,
+ EAuthenticationErrorCodes.REQUIRED_EMAIL_PASSWORD_SIGN_IN,
+ EAuthenticationErrorCodes.INVALID_EMAIL_SIGN_IN,
+ EAuthenticationErrorCodes.INVALID_EMAIL_MAGIC_SIGN_IN,
+ EAuthenticationErrorCodes.MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED,
+ EAuthenticationErrorCodes.INVALID_MAGIC_CODE,
+ EAuthenticationErrorCodes.EXPIRED_MAGIC_CODE,
+ EAuthenticationErrorCodes.EMAIL_CODE_ATTEMPT_EXHAUSTED,
+ EAuthenticationErrorCodes.GOOGLE_NOT_CONFIGURED,
+ EAuthenticationErrorCodes.GITHUB_NOT_CONFIGURED,
+ EAuthenticationErrorCodes.GOOGLE_OAUTH_PROVIDER_ERROR,
+ EAuthenticationErrorCodes.GITHUB_OAUTH_PROVIDER_ERROR,
+ EAuthenticationErrorCodes.INVALID_PASSWORD_TOKEN,
+ EAuthenticationErrorCodes.EXPIRED_PASSWORD_TOKEN,
+ EAuthenticationErrorCodes.INCORRECT_OLD_PASSWORD,
+ EAuthenticationErrorCodes.INVALID_NEW_PASSWORD,
+ EAuthenticationErrorCodes.PASSWORD_ALREADY_SET,
+ EAuthenticationErrorCodes.ADMIN_ALREADY_EXIST,
+ EAuthenticationErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME,
+ EAuthenticationErrorCodes.INVALID_ADMIN_EMAIL,
+ EAuthenticationErrorCodes.INVALID_ADMIN_PASSWORD,
+ EAuthenticationErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD,
+ EAuthenticationErrorCodes.ADMIN_AUTHENTICATION_FAILED,
+ EAuthenticationErrorCodes.ADMIN_USER_ALREADY_EXIST,
+ EAuthenticationErrorCodes.ADMIN_USER_DOES_NOT_EXIST,
+ ];
+
+ if (bannerAlertErrorCodes.includes(errorCode))
+ return {
+ type: EErrorAlertType.BANNER_ALERT,
+ code: errorCode,
+ title: errorCodeMessages[errorCode]?.title || "Error",
+ message: errorCodeMessages[errorCode]?.message(email) || "Something went wrong. Please try again.",
+ };
+
+ return undefined;
+};
diff --git a/packages/constants/src/calendar.ts b/packages/constants/src/calendar.ts
new file mode 100644
index 0000000..2cf9f5d
--- /dev/null
+++ b/packages/constants/src/calendar.ts
@@ -0,0 +1,109 @@
+import { TCalendarLayouts } from '@prodkt/types'
+
+export const MONTHS_LIST: {
+ [monthNumber: number]: {
+ shortTitle: string
+ title: string
+ }
+} = {
+ 1: {
+ shortTitle: 'Jan',
+ title: 'January',
+ },
+ 2: {
+ shortTitle: 'Feb',
+ title: 'February',
+ },
+ 3: {
+ shortTitle: 'Mar',
+ title: 'March',
+ },
+ 4: {
+ shortTitle: 'Apr',
+ title: 'April',
+ },
+ 5: {
+ shortTitle: 'May',
+ title: 'May',
+ },
+ 6: {
+ shortTitle: 'Jun',
+ title: 'June',
+ },
+ 7: {
+ shortTitle: 'Jul',
+ title: 'July',
+ },
+ 8: {
+ shortTitle: 'Aug',
+ title: 'August',
+ },
+ 9: {
+ shortTitle: 'Sep',
+ title: 'September',
+ },
+ 10: {
+ shortTitle: 'Oct',
+ title: 'October',
+ },
+ 11: {
+ shortTitle: 'Nov',
+ title: 'November',
+ },
+ 12: {
+ shortTitle: 'Dec',
+ title: 'December',
+ },
+}
+
+export const DAYS_LIST: {
+ [dayIndex: number]: {
+ shortTitle: string
+ title: string
+ }
+} = {
+ 1: {
+ shortTitle: 'Sun',
+ title: 'Sunday',
+ },
+ 2: {
+ shortTitle: 'Mon',
+ title: 'Monday',
+ },
+ 3: {
+ shortTitle: 'Tue',
+ title: 'Tuesday',
+ },
+ 4: {
+ shortTitle: 'Wed',
+ title: 'Wednesday',
+ },
+ 5: {
+ shortTitle: 'Thu',
+ title: 'Thursday',
+ },
+ 6: {
+ shortTitle: 'Fri',
+ title: 'Friday',
+ },
+ 7: {
+ shortTitle: 'Sat',
+ title: 'Saturday',
+ },
+}
+
+export const CALENDAR_LAYOUTS: {
+ [layout in TCalendarLayouts]: {
+ key: TCalendarLayouts
+ title: string
+ }
+} = {
+ month: {
+ key: 'month',
+ title: 'Month layout',
+ },
+ week: {
+ key: 'week',
+ title: 'Week layout',
+ },
+}
diff --git a/packages/constants/src/common.ts b/packages/constants/src/common.ts
new file mode 100644
index 0000000..8cdcf23
--- /dev/null
+++ b/packages/constants/src/common.ts
@@ -0,0 +1,7 @@
+export const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB
+
+export const MARKETING_PRICING_PAGE_LINK = 'https://prodkt.cloud/pricing'
+
+export const MARKETING_CONTACT_US_PAGE_LINK = 'https://prodkt.cloud/contact'
+
+export const MARKETING_PRODKT_ONE_PAGE_LINK = 'https://prodkt.cloud/one'
diff --git a/packages/constants/src/cycle.ts b/packages/constants/src/cycle.ts
new file mode 100644
index 0000000..8a4dcd0
--- /dev/null
+++ b/packages/constants/src/cycle.ts
@@ -0,0 +1,155 @@
+// types
+
+import type { TCycleLayoutOptions, TCycleTabOptions } from '@prodkt/types'
+
+import {
+ AlertOctagon,
+ BarChart4,
+ CircleDashed,
+ Folder,
+ GanttChartSquare,
+ LayoutGrid,
+ List,
+ Microscope,
+ Search,
+} from 'lucide-react'
+
+export const CYCLE_TABS_LIST: {
+ key: TCycleTabOptions
+ name: string
+}[] = [
+ {
+ key: 'active',
+ name: 'Active',
+ },
+ {
+ key: 'all',
+ name: 'All',
+ },
+]
+
+export const CYCLE_VIEW_LAYOUTS: {
+ key: TCycleLayoutOptions
+ icon: any
+ title: string
+}[] = [
+ {
+ key: 'list',
+ icon: List,
+ title: 'List layout',
+ },
+ {
+ key: 'board',
+ icon: LayoutGrid,
+ title: 'Grid layout',
+ },
+ {
+ key: 'gantt',
+ icon: GanttChartSquare,
+ title: 'Gantt layout',
+ },
+]
+
+export const CYCLE_STATUS: {
+ label: string
+ value: 'current' | 'upcoming' | 'completed' | 'draft'
+ title: string
+ color: string
+ textColor: string
+ bgColor: string
+}[] = [
+ {
+ label: 'day left',
+ value: 'current',
+ title: 'Active',
+ color: '#F59E0B',
+ textColor: 'text-amber-500',
+ bgColor: 'bg-amber-50',
+ },
+ {
+ label: 'Yet to start',
+ value: 'upcoming',
+ title: 'Yet to start',
+ color: '#3F76FF',
+ textColor: 'text-blue-500',
+ bgColor: 'bg-indigo-50',
+ },
+ {
+ label: 'Completed',
+ value: 'completed',
+ title: 'Completed',
+ color: '#16A34A',
+ textColor: 'text-green-600',
+ bgColor: 'bg-green-50',
+ },
+ {
+ label: 'Draft',
+ value: 'draft',
+ title: 'Draft',
+ color: '#525252',
+ textColor: 'text-custom-text-300',
+ bgColor: 'bg-custom-background-90',
+ },
+]
+
+export const CYCLE_STATE_GROUPS_DETAILS = [
+ {
+ key: 'completed_issues',
+ title: 'Completed',
+ color: '#6490FE',
+ },
+ {
+ key: 'started_issues',
+ title: 'Started',
+ color: '#FDD97F',
+ },
+ {
+ key: 'unstarted_issues',
+ title: 'Unstarted',
+ color: '#FEB055',
+ },
+ {
+ key: 'backlog_issues',
+ title: 'Backlog',
+ color: '#F0F0F3',
+ },
+]
+
+export const WORKSPACE_ACTIVE_CYCLES_DETAILS = [
+ {
+ title: '10,000-feet view of all active cycles.',
+ description:
+ 'Zoom out to see running cycles across all your projects at once instead of going from Cycle to Cycle in each project.',
+ icon: Folder,
+ },
+ {
+ title: 'Get a snapshot of each active cycle.',
+ description:
+ 'Track high-level metrics for all active cycles, see their state of progress, and get a sense of scope against deadlines.',
+ icon: CircleDashed,
+ },
+ {
+ title: 'Compare burndowns.',
+ description:
+ 'Monitor how each of your teams are performing with a peek into each cycle’s burndown report.',
+ icon: BarChart4,
+ },
+ {
+ title: 'Quickly see make-or-break issues. ',
+ description:
+ 'Preview high-priority issues for each cycle against due dates. See all of them per cycle in one click.',
+ icon: AlertOctagon,
+ },
+ {
+ title: 'Zoom into cycles that need attention. ',
+ description:
+ 'Investigate the state of any cycle that doesn’t conform to expectations in one click.',
+ icon: Search,
+ },
+ {
+ title: 'Stay ahead of blockers.',
+ description:
+ 'Spot challenges from one project to another and see inter-cycle dependencies that aren’t obvious from any other view.',
+ icon: Microscope,
+ },
+]
diff --git a/packages/constants/src/dashboard.ts b/packages/constants/src/dashboard.ts
new file mode 100644
index 0000000..c60afe2
--- /dev/null
+++ b/packages/constants/src/dashboard.ts
@@ -0,0 +1,311 @@
+import { linearGradientDef } from '@nivo/core'
+// assets
+import { BarChart2, Briefcase, CheckCircle, Home } from 'lucide-react'
+import CompletedIssuesDark from 'public/empty-state/dashboard/dark/completed-issues.svg'
+import OverdueIssuesDark from 'public/empty-state/dashboard/dark/overdue-issues.svg'
+import UpcomingIssuesDark from 'public/empty-state/dashboard/dark/upcoming-issues.svg'
+import CompletedIssuesLight from 'public/empty-state/dashboard/light/completed-issues.svg'
+import OverdueIssuesLight from 'public/empty-state/dashboard/light/overdue-issues.svg'
+import UpcomingIssuesLight from 'public/empty-state/dashboard/light/upcoming-issues.svg'
+
+// types
+import { TIssuesListTypes, TStateGroups } from '@prodkt/types'
+import { ContrastIcon } from '@prodkt/ui/primitives'
+
+import { Props } from '@/components/icons/types'
+
+// constants
+import { EUserWorkspaceRoles } from './workspace'
+
+// icons
+
+// gradients for issues by priority widget graph bars
+export const PRIORITY_GRAPH_GRADIENTS = [
+ linearGradientDef(
+ 'gradientUrgent',
+ [
+ { offset: 0, color: '#A90408' },
+ { offset: 100, color: '#DF4D51' },
+ ],
+ {
+ x1: 1,
+ y1: 0,
+ x2: 0,
+ y2: 0,
+ },
+ ),
+ linearGradientDef(
+ 'gradientHigh',
+ [
+ { offset: 0, color: '#FE6B00' },
+ { offset: 100, color: '#FFAC88' },
+ ],
+ {
+ x1: 1,
+ y1: 0,
+ x2: 0,
+ y2: 0,
+ },
+ ),
+ linearGradientDef(
+ 'gradientMedium',
+ [
+ { offset: 0, color: '#F5AC00' },
+ { offset: 100, color: '#FFD675' },
+ ],
+ {
+ x1: 1,
+ y1: 0,
+ x2: 0,
+ y2: 0,
+ },
+ ),
+ linearGradientDef(
+ 'gradientLow',
+ [
+ { offset: 0, color: '#1B46DE' },
+ { offset: 100, color: '#4F9BF4' },
+ ],
+ {
+ x1: 1,
+ y1: 0,
+ x2: 0,
+ y2: 0,
+ },
+ ),
+ linearGradientDef(
+ 'gradientNone',
+ [
+ { offset: 0, color: '#A0A1A9' },
+ { offset: 100, color: '#B9BBC6' },
+ ],
+ {
+ x1: 1,
+ y1: 0,
+ x2: 0,
+ y2: 0,
+ },
+ ),
+]
+
+// colors for issues by state group widget graph arcs
+export const STATE_GROUP_GRAPH_GRADIENTS = [
+ linearGradientDef('gradientBacklog', [
+ { offset: 0, color: '#DEDEDE' },
+ { offset: 100, color: '#BABABE' },
+ ]),
+ linearGradientDef('gradientUnstarted', [
+ { offset: 0, color: '#D4D4D4' },
+ { offset: 100, color: '#878796' },
+ ]),
+ linearGradientDef('gradientStarted', [
+ { offset: 0, color: '#FFD300' },
+ { offset: 100, color: '#FAE270' },
+ ]),
+ linearGradientDef('gradientCompleted', [
+ { offset: 0, color: '#0E8B1B' },
+ { offset: 100, color: '#37CB46' },
+ ]),
+ linearGradientDef('gradientCanceled', [
+ { offset: 0, color: '#C90004' },
+ { offset: 100, color: '#FF7679' },
+ ]),
+]
+
+export const STATE_GROUP_GRAPH_COLORS: Record = {
+ backlog: '#CDCED6',
+ unstarted: '#80838D',
+ started: '#FFC53D',
+ completed: '#3E9B4F',
+ cancelled: '#E5484D',
+}
+
+export enum EDurationFilters {
+ NONE = 'none',
+ TODAY = 'today',
+ THIS_WEEK = 'this_week',
+ THIS_MONTH = 'this_month',
+ THIS_YEAR = 'this_year',
+ CUSTOM = 'custom',
+}
+
+// filter duration options
+export const DURATION_FILTER_OPTIONS: {
+ key: EDurationFilters
+ label: string
+}[] = [
+ {
+ key: EDurationFilters.NONE,
+ label: 'All time',
+ },
+ {
+ key: EDurationFilters.TODAY,
+ label: 'Due today',
+ },
+ {
+ key: EDurationFilters.THIS_WEEK,
+ label: 'Due this week',
+ },
+ {
+ key: EDurationFilters.THIS_MONTH,
+ label: 'Due this month',
+ },
+ {
+ key: EDurationFilters.THIS_YEAR,
+ label: 'Due this year',
+ },
+ {
+ key: EDurationFilters.CUSTOM,
+ label: 'Custom',
+ },
+]
+
+// random background colors for project cards
+export const PROJECT_BACKGROUND_COLORS = [
+ 'bg-gray-500/20',
+ 'bg-green-500/20',
+ 'bg-red-500/20',
+ 'bg-orange-500/20',
+ 'bg-blue-500/20',
+ 'bg-yellow-500/20',
+ 'bg-pink-500/20',
+ 'bg-purple-500/20',
+]
+
+// assigned and created issues widgets tabs list
+export const FILTERED_ISSUES_TABS_LIST: {
+ key: TIssuesListTypes
+ label: string
+}[] = [
+ {
+ key: 'upcoming',
+ label: 'Upcoming',
+ },
+ {
+ key: 'overdue',
+ label: 'Overdue',
+ },
+ {
+ key: 'completed',
+ label: 'Marked completed',
+ },
+]
+
+// assigned and created issues widgets tabs list
+export const UNFILTERED_ISSUES_TABS_LIST: {
+ key: TIssuesListTypes
+ label: string
+}[] = [
+ {
+ key: 'pending',
+ label: 'Pending',
+ },
+ {
+ key: 'completed',
+ label: 'Marked completed',
+ },
+]
+
+export const ASSIGNED_ISSUES_EMPTY_STATES = {
+ pending: {
+ title: 'Issues assigned to you that are pending\nwill show up here.',
+ darkImage: UpcomingIssuesDark,
+ lightImage: UpcomingIssuesLight,
+ },
+ upcoming: {
+ title: 'Upcoming issues assigned to\nyou will show up here.',
+ darkImage: UpcomingIssuesDark,
+ lightImage: UpcomingIssuesLight,
+ },
+ overdue: {
+ title:
+ 'Issues assigned to you that are past\ntheir due date will show up here.',
+ darkImage: OverdueIssuesDark,
+ lightImage: OverdueIssuesLight,
+ },
+ completed: {
+ title:
+ 'Issues assigned to you that you have\nmarked Completed will show up here.',
+ darkImage: CompletedIssuesDark,
+ lightImage: CompletedIssuesLight,
+ },
+}
+
+export const CREATED_ISSUES_EMPTY_STATES = {
+ pending: {
+ title: 'Issues created by you that are pending\nwill show up here.',
+ darkImage: UpcomingIssuesDark,
+ lightImage: UpcomingIssuesLight,
+ },
+ upcoming: {
+ title: 'Upcoming issues you created\nwill show up here.',
+ darkImage: UpcomingIssuesDark,
+ lightImage: UpcomingIssuesLight,
+ },
+ overdue: {
+ title:
+ 'Issues created by you that are past their\ndue date will show up here.',
+ darkImage: OverdueIssuesDark,
+ lightImage: OverdueIssuesLight,
+ },
+ completed: {
+ title:
+ 'Issues created by you that you have\nmarked completed will show up here.',
+ darkImage: CompletedIssuesDark,
+ lightImage: CompletedIssuesLight,
+ },
+}
+
+export const SIDEBAR_MENU_ITEMS: {
+ key: string
+ label: string
+ href: string
+ access: EUserWorkspaceRoles
+ highlight: (pathname: string, baseUrl: string) => boolean
+ Icon: React.FC
+}[] = [
+ {
+ key: 'home',
+ label: 'Home',
+ href: ``,
+ access: EUserWorkspaceRoles.GUEST,
+ highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}`,
+ Icon: Home,
+ },
+ {
+ key: 'analytics',
+ label: 'Analytics',
+ href: `/analytics`,
+ access: EUserWorkspaceRoles.MEMBER,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname.includes(`${baseUrl}/analytics`),
+ Icon: BarChart2,
+ },
+ {
+ key: 'projects',
+ label: 'Projects',
+ href: `/projects`,
+ access: EUserWorkspaceRoles.GUEST,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/projects`,
+ Icon: Briefcase,
+ },
+ {
+ key: 'all-issues',
+ label: 'All Issues',
+ href: `/workspace-views/all-issues`,
+ access: EUserWorkspaceRoles.GUEST,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname.includes(`${baseUrl}/workspace-views`),
+ Icon: CheckCircle,
+ },
+ {
+ key: 'active-cycles',
+ label: 'Active Cycles',
+ href: `/active-cycles`,
+ access: EUserWorkspaceRoles.GUEST,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/active-cycles`,
+ Icon: ContrastIcon,
+ },
+]
diff --git a/packages/constants/src/editor.ts b/packages/constants/src/editor.ts
new file mode 100644
index 0000000..6683889
--- /dev/null
+++ b/packages/constants/src/editor.ts
@@ -0,0 +1,133 @@
+// editor
+
+import type { EditorMenuItemNames } from '@prodkt/document-editor'
+import type { LucideIcon } from 'lucide-react'
+
+import {
+ Bold,
+ CaseSensitive,
+ Code2,
+ Heading1,
+ Heading2,
+ Heading3,
+ Heading4,
+ Heading5,
+ Heading6,
+ Image,
+ Italic,
+ List,
+ ListOrdered,
+ ListTodo,
+ Quote,
+ Strikethrough,
+ Table,
+ Underline,
+} from 'lucide-react'
+
+type TEditorTypes = 'lite' | 'document'
+
+export type ToolbarMenuItem = {
+ key: EditorMenuItemNames
+ name: string
+ icon: LucideIcon
+ shortcut?: string[]
+ editors: TEditorTypes[]
+}
+
+export const TYPOGRAPHY_ITEMS: ToolbarMenuItem[] = [
+ { key: 'text', name: 'Text', icon: CaseSensitive, editors: ['document'] },
+ { key: 'h1', name: 'Heading 1', icon: Heading1, editors: ['document'] },
+ { key: 'h2', name: 'Heading 2', icon: Heading2, editors: ['document'] },
+ { key: 'h3', name: 'Heading 3', icon: Heading3, editors: ['document'] },
+ { key: 'h4', name: 'Heading 4', icon: Heading4, editors: ['document'] },
+ { key: 'h5', name: 'Heading 5', icon: Heading5, editors: ['document'] },
+ { key: 'h6', name: 'Heading 6', icon: Heading6, editors: ['document'] },
+]
+
+const BASIC_MARK_ITEMS: ToolbarMenuItem[] = [
+ {
+ key: 'bold',
+ name: 'Bold',
+ icon: Bold,
+ shortcut: ['Cmd', 'B'],
+ editors: ['lite', 'document'],
+ },
+ {
+ key: 'italic',
+ name: 'Italic',
+ icon: Italic,
+ shortcut: ['Cmd', 'I'],
+ editors: ['lite', 'document'],
+ },
+ {
+ key: 'underline',
+ name: 'Underline',
+ icon: Underline,
+ shortcut: ['Cmd', 'U'],
+ editors: ['lite', 'document'],
+ },
+ {
+ key: 'strikethrough',
+ name: 'Strikethrough',
+ icon: Strikethrough,
+ shortcut: ['Cmd', 'Shift', 'S'],
+ editors: ['lite', 'document'],
+ },
+]
+
+const LIST_ITEMS: ToolbarMenuItem[] = [
+ {
+ key: 'bulleted-list',
+ name: 'Bulleted list',
+ icon: List,
+ shortcut: ['Cmd', 'Shift', '7'],
+ editors: ['lite', 'document'],
+ },
+ {
+ key: 'numbered-list',
+ name: 'Numbered list',
+ icon: ListOrdered,
+ shortcut: ['Cmd', 'Shift', '8'],
+ editors: ['lite', 'document'],
+ },
+ {
+ key: 'to-do-list',
+ name: 'To-do list',
+ icon: ListTodo,
+ shortcut: ['Cmd', 'Shift', '9'],
+ editors: ['lite', 'document'],
+ },
+]
+
+const USER_ACTION_ITEMS: ToolbarMenuItem[] = [
+ { key: 'quote', name: 'Quote', icon: Quote, editors: ['lite', 'document'] },
+ { key: 'code', name: 'Code', icon: Code2, editors: ['lite', 'document'] },
+]
+
+const COMPLEX_ITEMS: ToolbarMenuItem[] = [
+ { key: 'table', name: 'Table', icon: Table, editors: ['document'] },
+ { key: 'image', name: 'Image', icon: Image, editors: ['lite', 'document'] },
+]
+
+export const TOOLBAR_ITEMS: {
+ [editorType in TEditorTypes]: {
+ [key: string]: ToolbarMenuItem[]
+ }
+} = {
+ lite: {
+ basic: BASIC_MARK_ITEMS.filter((item) => item.editors.includes('lite')),
+ list: LIST_ITEMS.filter((item) => item.editors.includes('lite')),
+ userAction: USER_ACTION_ITEMS.filter((item) =>
+ item.editors.includes('lite'),
+ ),
+ complex: COMPLEX_ITEMS.filter((item) => item.editors.includes('lite')),
+ },
+ document: {
+ basic: BASIC_MARK_ITEMS.filter((item) => item.editors.includes('document')),
+ list: LIST_ITEMS.filter((item) => item.editors.includes('document')),
+ userAction: USER_ACTION_ITEMS.filter((item) =>
+ item.editors.includes('document'),
+ ),
+ complex: COMPLEX_ITEMS.filter((item) => item.editors.includes('document')),
+ },
+}
diff --git a/packages/constants/src/empty-state.ts b/packages/constants/src/empty-state.ts
new file mode 100644
index 0000000..d1014bc
--- /dev/null
+++ b/packages/constants/src/empty-state.ts
@@ -0,0 +1,736 @@
+import { EUserProjectRoles } from './project'
+import { EUserWorkspaceRoles } from './workspace'
+
+export interface EmptyStateDetails {
+ key: EmptyStateType
+ title?: string
+ description?: string
+ path?: string
+ primaryButton?: {
+ icon?: React.ReactNode
+ text: string
+ comicBox?: {
+ title?: string
+ description?: string
+ }
+ }
+ secondaryButton?: {
+ icon?: React.ReactNode
+ text: string
+ comicBox?: {
+ title?: string
+ description?: string
+ }
+ }
+ accessType?: 'workspace' | 'project'
+ access?: EUserWorkspaceRoles | EUserProjectRoles
+}
+
+export enum EmptyStateType {
+ WORKSPACE_DASHBOARD = 'workspace-dashboard',
+ WORKSPACE_ANALYTICS = 'workspace-analytics',
+ WORKSPACE_PROJECTS = 'workspace-projects',
+ WORKSPACE_ALL_ISSUES = 'workspace-all-issues',
+ WORKSPACE_ASSIGNED = 'workspace-assigned',
+ WORKSPACE_CREATED = 'workspace-created',
+ WORKSPACE_SUBSCRIBED = 'workspace-subscribed',
+ WORKSPACE_CUSTOM_VIEW = 'workspace-custom-view',
+ WORKSPACE_NO_PROJECTS = 'workspace-no-projects',
+ WORKSPACE_SETTINGS_API_TOKENS = 'workspace-settings-api-tokens',
+ WORKSPACE_SETTINGS_WEBHOOKS = 'workspace-settings-webhooks',
+ WORKSPACE_SETTINGS_EXPORT = 'workspace-settings-export',
+ WORKSPACE_SETTINGS_IMPORT = 'workspace-settings-import',
+ PROFILE_ACTIVITY = 'profile-activity',
+ PROFILE_ASSIGNED = 'profile-assigned',
+ PROFILE_CREATED = 'profile-created',
+ PROFILE_SUBSCRIBED = 'profile-subscribed',
+ PROJECT_SETTINGS_LABELS = 'project-settings-labels',
+ PROJECT_SETTINGS_INTEGRATIONS = 'project-settings-integrations',
+ PROJECT_SETTINGS_ESTIMATE = 'project-settings-estimate',
+ PROJECT_CYCLES = 'project-cycles',
+ PROJECT_CYCLE_NO_ISSUES = 'project-cycle-no-issues',
+ PROJECT_CYCLE_ACTIVE = 'project-cycle-active',
+ PROJECT_CYCLE_ALL = 'project-cycle-all',
+ PROJECT_CYCLE_COMPLETED_NO_ISSUES = 'project-cycle-completed-no-issues',
+ PROJECT_ARCHIVED_NO_CYCLES = 'project-archived-no-cycles',
+ PROJECT_EMPTY_FILTER = 'project-empty-filter',
+ PROJECT_ARCHIVED_EMPTY_FILTER = 'project-archived-empty-filter',
+ PROJECT_DRAFT_EMPTY_FILTER = 'project-draft-empty-filter',
+ PROJECT_NO_ISSUES = 'project-no-issues',
+ PROJECT_ARCHIVED_NO_ISSUES = 'project-archived-no-issues',
+ PROJECT_DRAFT_NO_ISSUES = 'project-draft-no-issues',
+ VIEWS_EMPTY_SEARCH = 'views-empty-search',
+ PROJECTS_EMPTY_SEARCH = 'projects-empty-search',
+ MEMBERS_EMPTY_SEARCH = 'members-empty-search',
+ PROJECT_MODULE_ISSUES = 'project-module-issues',
+ PROJECT_MODULE = 'project-module',
+ PROJECT_ARCHIVED_NO_MODULES = 'project-archived-no-modules',
+ PROJECT_VIEW = 'project-view',
+ PROJECT_PAGE = 'project-page',
+ PROJECT_PAGE_PRIVATE = 'project-page-private',
+ PROJECT_PAGE_PUBLIC = 'project-page-public',
+ PROJECT_PAGE_ARCHIVED = 'project-page-archived',
+
+ COMMAND_K_SEARCH_EMPTY_STATE = 'command-k-search-empty-state',
+ ISSUE_RELATION_SEARCH_EMPTY_STATE = 'issue-relation-search-empty-state',
+ ISSUE_RELATION_EMPTY_STATE = 'issue-relation-empty-state',
+ ISSUE_COMMENT_EMPTY_STATE = 'issue-comment-empty-state',
+
+ NOTIFICATION_MY_ISSUE_EMPTY_STATE = 'notification-my-issues-empty-state',
+ NOTIFICATION_CREATED_EMPTY_STATE = 'notification-created-empty-state',
+ NOTIFICATION_SUBSCRIBED_EMPTY_STATE = 'notification-subscribed-empty-state',
+ NOTIFICATION_ARCHIVED_EMPTY_STATE = 'notification-archived-empty-state',
+ NOTIFICATION_SNOOZED_EMPTY_STATE = 'notification-snoozed-empty-state',
+ NOTIFICATION_UNREAD_EMPTY_STATE = 'notification-unread-empty-state',
+
+ ACTIVE_CYCLE_PROGRESS_EMPTY_STATE = 'active-cycle-progress-empty-state',
+ ACTIVE_CYCLE_CHART_EMPTY_STATE = 'active-cycle-chart-empty-state',
+ ACTIVE_CYCLE_PRIORITY_ISSUE_EMPTY_STATE = 'active-cycle-priority-issue-empty-state',
+ ACTIVE_CYCLE_ASSIGNEE_EMPTY_STATE = 'active-cycle-assignee-empty-state',
+ ACTIVE_CYCLE_LABEL_EMPTY_STATE = 'active-cycle-label-empty-state',
+
+ DISABLED_PROJECT_INBOX = 'disabled-project-inbox',
+ DISABLED_PROJECT_CYCLE = 'disabled-project-cycle',
+ DISABLED_PROJECT_MODULE = 'disabled-project-module',
+ DISABLED_PROJECT_VIEW = 'disabled-project-view',
+ DISABLED_PROJECT_PAGE = 'disabled-project-page',
+
+ INBOX_SIDEBAR_OPEN_TAB = 'inbox-sidebar-open-tab',
+ INBOX_SIDEBAR_CLOSED_TAB = 'inbox-sidebar-closed-tab',
+ INBOX_SIDEBAR_FILTER_EMPTY_STATE = 'inbox-sidebar-filter-empty-state',
+ INBOX_DETAIL_EMPTY_STATE = 'inbox-detail-empty-state',
+}
+
+const emptyStateDetails = {
+ // workspace
+ [EmptyStateType.WORKSPACE_DASHBOARD]: {
+ key: EmptyStateType.WORKSPACE_DASHBOARD,
+ title: 'Overview of your projects, activity, and metrics',
+ description:
+ ' Welcome to Prodkt, we are excited to have you here. Create your first project and track your issues, and this page will transform into a space that helps you progress. Admins will also see items which help their team progress.',
+ path: '/empty-state/onboarding/dashboard',
+ // path: "/empty-state/onboarding/",
+ primaryButton: {
+ text: 'Build your first project',
+ comicBox: {
+ title: 'Everything starts with a project in Prodkt',
+ description:
+ 'A project could be a product’s roadmap, a marketing campaign, or launching a new car.',
+ },
+ },
+
+ accessType: 'workspace',
+ access: EUserWorkspaceRoles.MEMBER,
+ },
+ [EmptyStateType.WORKSPACE_ANALYTICS]: {
+ key: EmptyStateType.WORKSPACE_ANALYTICS,
+ title:
+ 'Track progress, workloads, and allocations. Spot trends, remove blockers, and move work faster',
+ description:
+ 'See scope versus demand, estimates, and scope creep. Get performance by team members and teams, and make sure your project runs on time.',
+ path: '/empty-state/onboarding/analytics',
+ primaryButton: {
+ text: 'Create Cycles and Modules first',
+ comicBox: {
+ title: 'Analytics works best with Cycles + Modules',
+ description:
+ 'First, timebox your issues into Cycles and, if you can, group issues that span more than a cycle into Modules. Check out both on the left nav.',
+ },
+ },
+ accessType: 'workspace',
+ access: EUserWorkspaceRoles.MEMBER,
+ },
+ [EmptyStateType.WORKSPACE_PROJECTS]: {
+ key: EmptyStateType.WORKSPACE_PROJECTS,
+ title: 'No active projects',
+ description:
+ 'Think of each project as the parent for goal-oriented work. Projects are where Jobs, Cycles, and Modules live and, along with your colleagues, help you achieve that goal. Create a new project or filter for archived projects.',
+ path: '/empty-state/onboarding/projects',
+ primaryButton: {
+ text: 'Start your first project',
+ comicBox: {
+ title: 'Everything starts with a project in Prodkt',
+ description:
+ 'A project could be a product’s roadmap, a marketing campaign, or launching a new car.',
+ },
+ },
+ accessType: 'workspace',
+ access: EUserWorkspaceRoles.MEMBER,
+ },
+ // all-issues
+ [EmptyStateType.WORKSPACE_ALL_ISSUES]: {
+ key: EmptyStateType.WORKSPACE_ALL_ISSUES,
+ title: 'No issues in the project',
+ description:
+ "First project done! Now, slice your work into trackable pieces with issues. Let's go!",
+ path: '/empty-state/all-issues/all-issues',
+ primaryButton: {
+ text: 'Create new issue',
+ },
+ accessType: 'workspace',
+ access: EUserWorkspaceRoles.MEMBER,
+ },
+ [EmptyStateType.WORKSPACE_ASSIGNED]: {
+ key: EmptyStateType.WORKSPACE_ASSIGNED,
+ title: 'No issues yet',
+ description: 'Issues assigned to you can be tracked from here.',
+ path: '/empty-state/all-issues/assigned',
+ primaryButton: {
+ text: 'Create new issue',
+ },
+ accessType: 'workspace',
+ access: EUserWorkspaceRoles.MEMBER,
+ },
+ [EmptyStateType.WORKSPACE_CREATED]: {
+ key: EmptyStateType.WORKSPACE_CREATED,
+ title: 'No issues yet',
+ description:
+ 'All issues created by you come here, track them here directly.',
+ path: '/empty-state/all-issues/created',
+ primaryButton: {
+ text: 'Create new issue',
+ },
+ accessType: 'workspace',
+ access: EUserWorkspaceRoles.MEMBER,
+ },
+ [EmptyStateType.WORKSPACE_SUBSCRIBED]: {
+ key: EmptyStateType.WORKSPACE_SUBSCRIBED,
+ title: 'No issues yet',
+ description:
+ 'Subscribe to issues you are interested in, track all of them here.',
+ path: '/empty-state/all-issues/subscribed',
+ },
+ [EmptyStateType.WORKSPACE_CUSTOM_VIEW]: {
+ key: EmptyStateType.WORKSPACE_CUSTOM_VIEW,
+ title: 'No issues yet',
+ description: 'Issues that applies to the filters, track all of them here.',
+ path: '/empty-state/all-issues/custom-view',
+ },
+ [EmptyStateType.WORKSPACE_NO_PROJECTS]: {
+ key: EmptyStateType.WORKSPACE_NO_PROJECTS,
+ title: 'No project',
+ description:
+ 'To create issues or manage your work, you need to create a project or be a part of one.',
+ path: '/empty-state/onboarding/projects',
+ primaryButton: {
+ text: 'Start your first project',
+ comicBox: {
+ title: 'Everything starts with a project in Prodkt',
+ description:
+ 'A project could be a product’s roadmap, a marketing campaign, or launching a new car.',
+ },
+ },
+ accessType: 'workspace',
+ access: EUserWorkspaceRoles.MEMBER,
+ },
+ // workspace settings
+ [EmptyStateType.WORKSPACE_SETTINGS_API_TOKENS]: {
+ key: EmptyStateType.WORKSPACE_SETTINGS_API_TOKENS,
+ title: 'No API tokens created',
+ description:
+ 'Prodkt APIs can be used to integrate your data in Prodkt with any external system. Create a token to get started.',
+ path: '/empty-state/workspace-settings/api-tokens',
+ },
+ [EmptyStateType.WORKSPACE_SETTINGS_WEBHOOKS]: {
+ key: EmptyStateType.WORKSPACE_SETTINGS_WEBHOOKS,
+ title: 'No webhooks added',
+ description:
+ 'Create webhooks to receive real-time updates and automate actions.',
+ path: '/empty-state/workspace-settings/webhooks',
+ },
+ [EmptyStateType.WORKSPACE_SETTINGS_EXPORT]: {
+ key: EmptyStateType.WORKSPACE_SETTINGS_EXPORT,
+ title: 'No previous exports yet',
+ description:
+ 'Anytime you export, you will also have a copy here for reference.',
+ path: '/empty-state/workspace-settings/exports',
+ },
+ [EmptyStateType.WORKSPACE_SETTINGS_IMPORT]: {
+ key: EmptyStateType.WORKSPACE_SETTINGS_IMPORT,
+ title: 'No previous imports yet',
+ description: 'Find all your previous imports here and download them.',
+ path: '/empty-state/workspace-settings/imports',
+ },
+ // profile
+ [EmptyStateType.PROFILE_ACTIVITY]: {
+ key: EmptyStateType.PROFILE_ASSIGNED,
+ title: 'No activities yet',
+ description:
+ 'Get started by creating a new issue! Add details and properties to it. Explore more in Prodkt to see your activity.',
+ path: '/empty-state/profile/activity',
+ },
+ [EmptyStateType.PROFILE_ASSIGNED]: {
+ key: EmptyStateType.PROFILE_ASSIGNED,
+ title: 'No issues are assigned to you',
+ description: 'Issues assigned to you can be tracked from here.',
+ path: '/empty-state/profile/assigned',
+ },
+ [EmptyStateType.PROFILE_CREATED]: {
+ key: EmptyStateType.PROFILE_CREATED,
+ title: 'No issues yet',
+ description:
+ 'All issues created by you come here, track them here directly.',
+ path: '/empty-state/profile/created',
+ },
+ [EmptyStateType.PROFILE_SUBSCRIBED]: {
+ key: EmptyStateType.PROFILE_SUBSCRIBED,
+ title: 'No issues yet',
+ description:
+ 'Subscribe to issues you are interested in, track all of them here.',
+ path: '/empty-state/profile/subscribed',
+ },
+ // project settings
+ [EmptyStateType.PROJECT_SETTINGS_LABELS]: {
+ key: EmptyStateType.PROJECT_SETTINGS_LABELS,
+ title: 'No labels yet',
+ description:
+ 'Create labels to help organize and filter issues in you project.',
+ path: '/empty-state/project-settings/labels',
+ },
+ [EmptyStateType.PROJECT_SETTINGS_INTEGRATIONS]: {
+ key: EmptyStateType.PROJECT_SETTINGS_INTEGRATIONS,
+ title: 'No integrations configured',
+ description:
+ 'Configure GitHub and other integrations to sync your project issues.',
+ path: '/empty-state/project-settings/integrations',
+ },
+ [EmptyStateType.PROJECT_SETTINGS_ESTIMATE]: {
+ key: EmptyStateType.PROJECT_SETTINGS_ESTIMATE,
+ title: 'No estimates added',
+ description:
+ 'Create a set of estimates to communicate the amount of work per issue.',
+ path: '/empty-state/project-settings/estimates',
+ },
+ // project cycles
+ [EmptyStateType.PROJECT_CYCLES]: {
+ key: EmptyStateType.PROJECT_CYCLES,
+ title: 'Group and timebox your work in Cycles.',
+ description:
+ 'Break work down by timeboxed chunks, work backwards from your project deadline to set dates, and make tangible progress as a team.',
+ path: '/empty-state/onboarding/cycles',
+ primaryButton: {
+ text: 'Set your first cycle',
+ comicBox: {
+ title: 'Cycles are repetitive time-boxes.',
+ description:
+ 'A sprint, an iteration, and or any other term you use for weekly or fortnightly tracking of work is a cycle.',
+ },
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_CYCLE_NO_ISSUES]: {
+ key: EmptyStateType.PROJECT_CYCLE_NO_ISSUES,
+ title: 'No issues added to the cycle',
+ description:
+ 'Add or create issues you wish to timebox and deliver within this cycle',
+ path: '/empty-state/cycle-issues/',
+ primaryButton: {
+ text: 'Create new issue ',
+ },
+ secondaryButton: {
+ text: 'Add an existing issue',
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_CYCLE_ACTIVE]: {
+ key: EmptyStateType.PROJECT_CYCLE_ACTIVE,
+ title: 'No active cycle',
+ description:
+ "An active cycle includes any period that encompasses today's date within its range. Find the progress and details of the active cycle here.",
+ path: '/empty-state/cycle/active',
+ },
+ [EmptyStateType.PROJECT_CYCLE_COMPLETED_NO_ISSUES]: {
+ key: EmptyStateType.PROJECT_CYCLE_COMPLETED_NO_ISSUES,
+ title: 'No issues in the cycle',
+ description:
+ 'No issues in the cycle. Issues are either transferred or hidden. To see hidden issues if any, update your display properties accordingly.',
+ path: '/empty-state/cycle/completed-no-issues',
+ },
+ [EmptyStateType.PROJECT_ARCHIVED_NO_CYCLES]: {
+ key: EmptyStateType.PROJECT_ARCHIVED_NO_CYCLES,
+ title: 'No archived cycles yet',
+ description:
+ 'To tidy up your project, archive completed cycles. Find them here once archived.',
+ path: '/empty-state/archived/empty-cycles',
+ },
+ [EmptyStateType.PROJECT_CYCLE_ALL]: {
+ key: EmptyStateType.PROJECT_CYCLE_ALL,
+ title: 'No cycles',
+ description:
+ "An active cycle includes any period that encompasses today's date within its range. Find the progress and details of the active cycle here.",
+ path: '/empty-state/cycle/active',
+ },
+ // empty filters
+ [EmptyStateType.PROJECT_EMPTY_FILTER]: {
+ key: EmptyStateType.PROJECT_EMPTY_FILTER,
+ title: 'No issues found matching the filters applied',
+ path: '/empty-state/empty-filters/',
+ secondaryButton: {
+ text: 'Clear all filters',
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_ARCHIVED_EMPTY_FILTER]: {
+ key: EmptyStateType.PROJECT_ARCHIVED_EMPTY_FILTER,
+ title: 'No issues found matching the filters applied',
+ path: '/empty-state/empty-filters/',
+ secondaryButton: {
+ text: 'Clear all filters',
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_DRAFT_EMPTY_FILTER]: {
+ key: EmptyStateType.PROJECT_DRAFT_EMPTY_FILTER,
+ title: 'No issues found matching the filters applied',
+ path: '/empty-state/empty-filters/',
+ secondaryButton: {
+ text: 'Clear all filters',
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ // project issues
+ [EmptyStateType.PROJECT_NO_ISSUES]: {
+ key: EmptyStateType.PROJECT_NO_ISSUES,
+ title: 'Create an issue and assign it to someone, even yourself',
+ description:
+ 'Think of issues as jobs, tasks, work, or JTBD. Which we like. An issue and its sub-issues are usually time-based actionables assigned to members of your team. Your team creates, assigns, and completes issues to move your project towards its goal.',
+ path: '/empty-state/onboarding/issues',
+ primaryButton: {
+ text: 'Create your first issue',
+ comicBox: {
+ title: 'Issues are building blocks in Prodkt.',
+ description:
+ 'Redesign the Prodkt UI, Rebrand the company, or Launch the new fuel injection system are examples of issues that likely have sub-issues.',
+ },
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_ARCHIVED_NO_ISSUES]: {
+ key: EmptyStateType.PROJECT_ARCHIVED_NO_ISSUES,
+ title: 'No archived issues yet',
+ description:
+ 'Manually or through automation, you can archive issues that are completed or cancelled. Find them here once archived.',
+ path: '/empty-state/archived/empty-issues',
+ primaryButton: {
+ text: 'Set automation',
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_DRAFT_NO_ISSUES]: {
+ key: EmptyStateType.PROJECT_DRAFT_NO_ISSUES,
+ title: 'No draft issues yet',
+ description:
+ 'Quickly stepping away but want to keep your place? No worries – save a draft now. Your issues will be right here waiting for you.',
+ path: '/empty-state/draft/draft-issues-empty',
+ },
+ [EmptyStateType.VIEWS_EMPTY_SEARCH]: {
+ key: EmptyStateType.VIEWS_EMPTY_SEARCH,
+ title: 'No matching views',
+ description:
+ 'No views match the search criteria. Create a new view instead.',
+ path: '/empty-state/search/search',
+ },
+ [EmptyStateType.PROJECTS_EMPTY_SEARCH]: {
+ key: EmptyStateType.PROJECTS_EMPTY_SEARCH,
+ title: 'No matching projects',
+ description:
+ 'No projects detected with the matching criteria. Create a new project instead.',
+ path: '/empty-state/search/project',
+ },
+ [EmptyStateType.MEMBERS_EMPTY_SEARCH]: {
+ key: EmptyStateType.MEMBERS_EMPTY_SEARCH,
+ title: 'No matching members',
+ description:
+ 'Add them to the project if they are already a part of the workspace',
+ path: '/empty-state/search/member',
+ },
+ // project module
+ [EmptyStateType.PROJECT_MODULE_ISSUES]: {
+ key: EmptyStateType.PROJECT_MODULE_ISSUES,
+ title: 'No issues in the module',
+ description:
+ 'Create or add issues which you want to accomplish as part of this module',
+ path: '/empty-state/module-issues/',
+ primaryButton: {
+ text: 'Create new issue ',
+ },
+ secondaryButton: {
+ text: 'Add an existing issue',
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_MODULE]: {
+ key: EmptyStateType.PROJECT_MODULE,
+ title:
+ 'Map your project milestones to Modules and track aggregated work easily.',
+ description:
+ 'A group of issues that belong to a logical, hierarchical parent form a module. Think of them as a way to track work by project milestones. They have their own periods and deadlines as well as analytics to help you see how close or far you are from a milestone.',
+ path: '/empty-state/onboarding/modules',
+ primaryButton: {
+ text: 'Build your first module',
+ comicBox: {
+ title: 'Modules help group work by hierarchy.',
+ description:
+ 'A cart module, a chassis module, and a warehouse module are all good example of this grouping.',
+ },
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_ARCHIVED_NO_MODULES]: {
+ key: EmptyStateType.PROJECT_ARCHIVED_NO_MODULES,
+ title: 'No archived Modules yet',
+ description:
+ 'To tidy up your project, archive completed or cancelled modules. Find them here once archived.',
+ path: '/empty-state/archived/empty-modules',
+ },
+ // project views
+ [EmptyStateType.PROJECT_VIEW]: {
+ key: EmptyStateType.PROJECT_VIEW,
+ title: 'Save filtered views for your project. Create as many as you need',
+ description:
+ 'Views are a set of saved filters that you use frequently or want easy access to. All your colleagues in a project can see everyone’s views and choose whichever suits their needs best.',
+ path: '/empty-state/onboarding/views',
+ primaryButton: {
+ text: 'Create your first view',
+ comicBox: {
+ title: 'Views work atop Issue properties.',
+ description:
+ 'You can create a view from here with as many properties as filters as you see fit.',
+ },
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ // project pages
+ [EmptyStateType.PROJECT_PAGE]: {
+ key: EmptyStateType.PROJECT_PAGE,
+ title:
+ 'Write a note, a doc, or a full knowledge base. Get Galileo, Prodkt’s AI assistant, to help you get started',
+ description:
+ 'Pages are thoughts potting space in Prodkt. Take down meeting notes, format them easily, embed issues, lay them out using a library of components, and keep them all in your project’s context. To make short work of any doc, invoke Galileo, Prodkt’s AI, with a shortcut or the click of a button.',
+ path: '/empty-state/onboarding/pages',
+ primaryButton: {
+ text: 'Create your first page',
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_PAGE_PRIVATE]: {
+ key: EmptyStateType.PROJECT_PAGE_PRIVATE,
+ title: 'No private pages yet',
+ description:
+ "Keep your private thoughts here. When you're ready to share, the team's just a click away.",
+ path: '/empty-state/pages/private',
+ primaryButton: {
+ text: 'Create your first page',
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_PAGE_PUBLIC]: {
+ key: EmptyStateType.PROJECT_PAGE_PUBLIC,
+ title: 'No public pages yet',
+ description: 'See pages shared with everyone in your project right here.',
+ path: '/empty-state/pages/public',
+ primaryButton: {
+ text: 'Create your first page',
+ },
+ accessType: 'project',
+ access: EUserProjectRoles.MEMBER,
+ },
+ [EmptyStateType.PROJECT_PAGE_ARCHIVED]: {
+ key: EmptyStateType.PROJECT_PAGE_ARCHIVED,
+ title: 'No archived pages yet',
+ description:
+ 'Archive pages not on your radar. Access them here when needed.',
+ path: '/empty-state/pages/archived',
+ },
+
+ [EmptyStateType.COMMAND_K_SEARCH_EMPTY_STATE]: {
+ key: EmptyStateType.COMMAND_K_SEARCH_EMPTY_STATE,
+ title: 'No results found',
+ path: '/empty-state/search/search',
+ },
+ [EmptyStateType.ISSUE_RELATION_SEARCH_EMPTY_STATE]: {
+ key: EmptyStateType.ISSUE_RELATION_SEARCH_EMPTY_STATE,
+ title: 'No matching issues found',
+ path: '/empty-state/search/search',
+ },
+ [EmptyStateType.ISSUE_RELATION_EMPTY_STATE]: {
+ key: EmptyStateType.ISSUE_RELATION_EMPTY_STATE,
+ title: 'No issues found',
+ path: '/empty-state/search/issues',
+ },
+ [EmptyStateType.ISSUE_COMMENT_EMPTY_STATE]: {
+ key: EmptyStateType.ISSUE_COMMENT_EMPTY_STATE,
+ title: 'No comments yet',
+ description:
+ 'Comments can be used as a discussion and \n follow-up space for the issues',
+ path: '/empty-state/search/comments',
+ },
+
+ [EmptyStateType.NOTIFICATION_MY_ISSUE_EMPTY_STATE]: {
+ key: EmptyStateType.NOTIFICATION_MY_ISSUE_EMPTY_STATE,
+ title: 'No issues assigned',
+ description: 'Updates for issues assigned to you can be \n seen here',
+ path: '/empty-state/search/notification',
+ },
+
+ [EmptyStateType.NOTIFICATION_CREATED_EMPTY_STATE]: {
+ key: EmptyStateType.NOTIFICATION_CREATED_EMPTY_STATE,
+ title: 'No updates to issues',
+ description: 'Updates to issues created by you can be \n seen here',
+ path: '/empty-state/search/notification',
+ },
+ [EmptyStateType.NOTIFICATION_SUBSCRIBED_EMPTY_STATE]: {
+ key: EmptyStateType.NOTIFICATION_SUBSCRIBED_EMPTY_STATE,
+ title: 'No updates to issues',
+ description:
+ 'Updates to any issue you are \n subscribed to can be seen here',
+ path: '/empty-state/search/notification',
+ },
+ [EmptyStateType.NOTIFICATION_UNREAD_EMPTY_STATE]: {
+ key: EmptyStateType.NOTIFICATION_UNREAD_EMPTY_STATE,
+ title: 'No unread notifications',
+ description:
+ 'Congratulations, you are up-to-date \n with everything happening in the issues \n you care about',
+ path: '/empty-state/search/notification',
+ },
+ [EmptyStateType.NOTIFICATION_SNOOZED_EMPTY_STATE]: {
+ key: EmptyStateType.NOTIFICATION_SNOOZED_EMPTY_STATE,
+ title: 'No snoozed notifications yet',
+ description:
+ 'Any notification you snooze for later will \n be available here to act upon',
+ path: '/empty-state/search/snooze',
+ },
+ [EmptyStateType.NOTIFICATION_ARCHIVED_EMPTY_STATE]: {
+ key: EmptyStateType.NOTIFICATION_ARCHIVED_EMPTY_STATE,
+ title: 'No archived notifications yet',
+ description:
+ 'Any notification you archive will be \n available here to help you focus',
+ path: '/empty-state/search/archive',
+ },
+ [EmptyStateType.ACTIVE_CYCLE_PROGRESS_EMPTY_STATE]: {
+ key: EmptyStateType.ACTIVE_CYCLE_PROGRESS_EMPTY_STATE,
+ title: "Add issues to the cycle to view it's \n progress",
+ path: '/empty-state/active-cycle/progress',
+ },
+ [EmptyStateType.ACTIVE_CYCLE_CHART_EMPTY_STATE]: {
+ key: EmptyStateType.ACTIVE_CYCLE_CHART_EMPTY_STATE,
+ title: 'Add issues to the cycle to view the \n burndown chart.',
+ path: '/empty-state/active-cycle/chart',
+ },
+ [EmptyStateType.ACTIVE_CYCLE_PRIORITY_ISSUE_EMPTY_STATE]: {
+ key: EmptyStateType.ACTIVE_CYCLE_PRIORITY_ISSUE_EMPTY_STATE,
+ title: 'Observe high priority issues tackled in \n the cycle at a glance.',
+ path: '/empty-state/active-cycle/priority',
+ },
+ [EmptyStateType.ACTIVE_CYCLE_ASSIGNEE_EMPTY_STATE]: {
+ key: EmptyStateType.ACTIVE_CYCLE_ASSIGNEE_EMPTY_STATE,
+ title:
+ 'Add assignees to issues to see a \n breakdown of work by assignees.',
+ path: '/empty-state/active-cycle/assignee',
+ },
+ [EmptyStateType.ACTIVE_CYCLE_LABEL_EMPTY_STATE]: {
+ key: EmptyStateType.ACTIVE_CYCLE_LABEL_EMPTY_STATE,
+ title: 'Add labels to issues to see the \n breakdown of work by labels.',
+ path: '/empty-state/active-cycle/label',
+ },
+ [EmptyStateType.DISABLED_PROJECT_INBOX]: {
+ key: EmptyStateType.DISABLED_PROJECT_INBOX,
+ title: 'Inbox is not enabled for the project.',
+ description:
+ 'Inbox helps you manage incoming requests to your project and add them as issues in your workflow. Enable inbox \n from project settings to manage requests.',
+ accessType: 'project',
+ access: EUserProjectRoles.ADMIN,
+ path: '/empty-state/disabled-feature/inbox',
+ primaryButton: {
+ text: 'Manage features',
+ },
+ },
+ [EmptyStateType.DISABLED_PROJECT_CYCLE]: {
+ key: EmptyStateType.DISABLED_PROJECT_CYCLE,
+ title: 'Cycles is not enabled for this project.',
+ description:
+ 'Break work down by timeboxed chunks, work backwards from your project deadline to set dates, and make tangible progress as a team. Enable the cycles feature for your project to start using them.',
+ accessType: 'project',
+ access: EUserProjectRoles.ADMIN,
+ path: '/empty-state/disabled-feature/cycles',
+ primaryButton: {
+ text: 'Manage features',
+ },
+ },
+ [EmptyStateType.DISABLED_PROJECT_MODULE]: {
+ key: EmptyStateType.DISABLED_PROJECT_MODULE,
+ title: 'Modules are not enabled for the project.',
+ description:
+ 'A group of issues that belong to a logical, hierarchical parent form a module. Think of them as a way to track work by project milestones. Enable modules from project settings.',
+ accessType: 'project',
+ access: EUserProjectRoles.ADMIN,
+ path: '/empty-state/disabled-feature/modules',
+ primaryButton: {
+ text: 'Manage features',
+ },
+ },
+ [EmptyStateType.DISABLED_PROJECT_PAGE]: {
+ key: EmptyStateType.DISABLED_PROJECT_PAGE,
+ title: 'Pages are not enabled for the project.',
+ description:
+ 'Pages are thought spotting space in Prodkt. Take down meeting notes, format them easily, embed issues, lay them out using a library of components, and keep them all in your project’s context. Enable the pages feature to start creating them in your project.',
+ accessType: 'project',
+ access: EUserProjectRoles.ADMIN,
+ path: '/empty-state/disabled-feature/pages',
+ primaryButton: {
+ text: 'Manage features',
+ },
+ },
+ [EmptyStateType.DISABLED_PROJECT_VIEW]: {
+ key: EmptyStateType.DISABLED_PROJECT_VIEW,
+ title: 'Views is not enabled for this project.',
+ description:
+ 'Views are a set of saved filters that you use frequently or want easy access to. All your colleagues in a project can see everyone’s views and choose whichever suits their needs best. Enable views in the project settings to start using them.',
+ accessType: 'project',
+ access: EUserProjectRoles.ADMIN,
+ path: '/empty-state/disabled-feature/views',
+ primaryButton: {
+ text: 'Manage features',
+ },
+ },
+ [EmptyStateType.INBOX_SIDEBAR_OPEN_TAB]: {
+ key: EmptyStateType.INBOX_SIDEBAR_OPEN_TAB,
+ title: 'No open issues',
+ description: 'Find open issues here. Create new issue.',
+ path: '/empty-state/inbox/inbox-issue',
+ },
+ [EmptyStateType.INBOX_SIDEBAR_CLOSED_TAB]: {
+ key: EmptyStateType.INBOX_SIDEBAR_CLOSED_TAB,
+ title: 'No closed issues',
+ description:
+ 'All the issues whether accepted or \n declined can be found here.',
+ path: '/empty-state/inbox/inbox-issue',
+ },
+ [EmptyStateType.INBOX_SIDEBAR_FILTER_EMPTY_STATE]: {
+ key: EmptyStateType.INBOX_SIDEBAR_FILTER_EMPTY_STATE,
+ title: 'No matching issues',
+ description:
+ 'No issue matches filter applied in inbox. \n Create a new issue.',
+ path: '/empty-state/inbox/filter-issue',
+ },
+ [EmptyStateType.INBOX_DETAIL_EMPTY_STATE]: {
+ key: EmptyStateType.INBOX_DETAIL_EMPTY_STATE,
+ title: 'Select an issue to view its details.',
+ path: '/empty-state/inbox/issue-detail',
+ },
+} as const
+
+export const EMPTY_STATE_DETAILS: Record =
+ emptyStateDetails
diff --git a/packages/constants/src/event-tracker.ts b/packages/constants/src/event-tracker.ts
new file mode 100644
index 0000000..14ef5f1
--- /dev/null
+++ b/packages/constants/src/event-tracker.ts
@@ -0,0 +1,227 @@
+export type IssueEventProps = {
+ eventName: string
+ payload: any
+ updates?: any
+ path?: string
+}
+
+export type EventProps = {
+ eventName: string
+ payload: any
+}
+
+export const getWorkspaceEventPayload = (payload: any) => ({
+ workspace_id: payload.id,
+ created_at: payload.created_at,
+ updated_at: payload.updated_at,
+ organization_size: payload.organization_size,
+ first_time: payload.first_time,
+ state: payload.state,
+ element: payload.element,
+})
+
+export const getProjectEventPayload = (payload: any) => ({
+ workspace_id: payload.workspace_id,
+ project_id: payload.id,
+ identifier: payload.identifier,
+ project_visibility: payload.network == 2 ? 'Public' : 'Private',
+ changed_properties: payload.changed_properties,
+ lead_id: payload.project_lead,
+ created_at: payload.created_at,
+ updated_at: payload.updated_at,
+ state: payload.state,
+ element: payload.element,
+})
+
+export const getCycleEventPayload = (payload: any) => ({
+ workspace_id: payload.workspace_id,
+ project_id: payload.project,
+ cycle_id: payload.id,
+ created_at: payload.created_at,
+ updated_at: payload.updated_at,
+ start_date: payload.start_date,
+ target_date: payload.target_date,
+ cycle_status: payload.status,
+ changed_properties: payload.changed_properties,
+ state: payload.state,
+ element: payload.element,
+})
+
+export const getModuleEventPayload = (payload: any) => ({
+ workspace_id: payload.workspace_id,
+ project_id: payload.project,
+ module_id: payload.id,
+ created_at: payload.created_at,
+ updated_at: payload.updated_at,
+ start_date: payload.start_date,
+ target_date: payload.target_date,
+ module_status: payload.status,
+ lead_id: payload.lead,
+ changed_properties: payload.changed_properties,
+ member_ids: payload.members,
+ state: payload.state,
+ element: payload.element,
+})
+
+export const getPageEventPayload = (payload: any) => ({
+ workspace_id: payload.workspace_id,
+ project_id: payload.project,
+ created_at: payload.created_at,
+ updated_at: payload.updated_at,
+ access: payload.access === 0 ? 'Public' : 'Private',
+ is_locked: payload.is_locked,
+ archived_at: payload.archived_at,
+ created_by: payload.created_by,
+ state: payload.state,
+ element: payload.element,
+})
+
+export const getIssueEventPayload = (props: IssueEventProps) => {
+ const { eventName, payload, updates, path } = props
+ let eventPayload: any = {
+ issue_id: payload.id,
+ estimate_point: payload.estimate_point,
+ link_count: payload.link_count,
+ target_date: payload.target_date,
+ is_draft: payload.is_draft,
+ label_ids: payload.label_ids,
+ assignee_ids: payload.assignee_ids,
+ created_at: payload.created_at,
+ updated_at: payload.updated_at,
+ sequence_id: payload.sequence_id,
+ module_ids: payload.module_ids,
+ sub_issues_count: payload.sub_issues_count,
+ parent_id: payload.parent_id,
+ project_id: payload.project_id,
+ workspace_id: payload.workspace_id,
+ priority: payload.priority,
+ state_id: payload.state_id,
+ start_date: payload.start_date,
+ attachment_count: payload.attachment_count,
+ cycle_id: payload.cycle_id,
+ module_id: payload.module_id,
+ archived_at: payload.archived_at,
+ state: payload.state,
+ view_id:
+ path?.includes('workspace-views') || path?.includes('views')
+ ? path.split('/').pop()
+ : '',
+ }
+
+ if (eventName === ISSUE_UPDATED) {
+ eventPayload = {
+ ...eventPayload,
+ ...updates,
+ updated_from: props.path?.includes('workspace-views')
+ ? 'All views'
+ : props.path?.includes('cycles')
+ ? 'Cycle'
+ : props.path?.includes('modules')
+ ? 'Module'
+ : props.path?.includes('views')
+ ? 'Project view'
+ : props.path?.includes('inbox')
+ ? 'Inbox'
+ : props.path?.includes('draft')
+ ? 'Draft'
+ : 'Project',
+ }
+ }
+ return eventPayload
+}
+
+export const getProjectStateEventPayload = (payload: any) => ({
+ workspace_id: payload.workspace_id,
+ project_id: payload.id,
+ state_id: payload.id,
+ created_at: payload.created_at,
+ updated_at: payload.updated_at,
+ group: payload.group,
+ color: payload.color,
+ default: payload.default,
+ state: payload.state,
+ element: payload.element,
+})
+
+// Workspace crud Events
+export const WORKSPACE_CREATED = 'Workspace created'
+export const WORKSPACE_UPDATED = 'Workspace updated'
+export const WORKSPACE_DELETED = 'Workspace deleted'
+// Project Events
+export const PROJECT_CREATED = 'Project created'
+export const PROJECT_UPDATED = 'Project updated'
+export const PROJECT_DELETED = 'Project deleted'
+// Cycle Events
+export const CYCLE_CREATED = 'Cycle created'
+export const CYCLE_UPDATED = 'Cycle updated'
+export const CYCLE_DELETED = 'Cycle deleted'
+export const CYCLE_FAVORITED = 'Cycle favorited'
+export const CYCLE_UNFAVORITED = 'Cycle unfavorited'
+// Module Events
+export const MODULE_CREATED = 'Module created'
+export const MODULE_UPDATED = 'Module updated'
+export const MODULE_DELETED = 'Module deleted'
+export const MODULE_FAVORITED = 'Module favorited'
+export const MODULE_UNFAVORITED = 'Module unfavorited'
+export const MODULE_LINK_CREATED = 'Module link created'
+export const MODULE_LINK_UPDATED = 'Module link updated'
+export const MODULE_LINK_DELETED = 'Module link deleted'
+// Issue Events
+export const ISSUE_CREATED = 'Issue created'
+export const ISSUE_UPDATED = 'Issue updated'
+export const ISSUE_DELETED = 'Issue deleted'
+export const ISSUE_ARCHIVED = 'Issue archived'
+export const ISSUE_RESTORED = 'Issue restored'
+export const ISSUE_OPENED = 'Issue opened'
+// Project State Events
+export const STATE_CREATED = 'State created'
+export const STATE_UPDATED = 'State updated'
+export const STATE_DELETED = 'State deleted'
+// Project Page Events
+export const PAGE_CREATED = 'Page created'
+export const PAGE_UPDATED = 'Page updated'
+export const PAGE_DELETED = 'Page deleted'
+// Member Events
+export const MEMBER_INVITED = 'Member invited'
+export const MEMBER_ACCEPTED = 'Member accepted'
+export const PROJECT_MEMBER_ADDED = 'Project member added'
+export const PROJECT_MEMBER_LEAVE = 'Project member leave'
+export const WORKSPACE_MEMBER_lEAVE = 'Workspace member leave'
+// Sign-in & Sign-up Events
+export const NAVIGATE_TO_SIGNUP = 'Navigate to sign-up page'
+export const NAVIGATE_TO_SIGNIN = 'Navigate to sign-in page'
+export const CODE_VERIFIED = 'Code verified'
+export const SETUP_PASSWORD = 'Password setup'
+export const PASSWORD_CREATE_SELECTED = 'Password created'
+export const PASSWORD_CREATE_SKIPPED = 'Skipped to setup'
+export const SIGN_IN_WITH_PASSWORD = 'Sign in with password'
+export const FORGOT_PASSWORD = 'Forgot password clicked'
+export const FORGOT_PASS_LINK = 'Forgot password link generated'
+export const NEW_PASS_CREATED = 'New password created'
+// Onboarding Events
+export const USER_DETAILS = 'User details added'
+export const USER_ONBOARDING_COMPLETED = 'User onboarding completed'
+// Product Tour Events
+export const PRODUCT_TOUR_STARTED = 'Product tour started'
+export const PRODUCT_TOUR_COMPLETED = 'Product tour completed'
+export const PRODUCT_TOUR_SKIPPED = 'Product tour skipped'
+// Dashboard Events
+export const CHANGELOG_REDIRECTED = 'Changelog redirected'
+export const GITHUB_REDIRECTED = 'Github redirected'
+// Sidebar Events
+export const SIDEBAR_CLICKED = 'Sidenav clicked'
+// Global View Events
+export const GLOBAL_VIEW_CREATED = 'Global view created'
+export const GLOBAL_VIEW_UPDATED = 'Global view updated'
+export const GLOBAL_VIEW_DELETED = 'Global view deleted'
+export const GLOBAL_VIEW_OPENED = 'Global view opened'
+// Notification Events
+export const NOTIFICATION_ARCHIVED = 'Notification archived'
+export const NOTIFICATION_SNOOZED = 'Notification snoozed'
+export const NOTIFICATION_READ = 'Notification marked read'
+export const UNREAD_NOTIFICATIONS = 'Unread notifications viewed'
+export const NOTIFICATIONS_READ = 'All notifications marked read'
+export const SNOOZED_NOTIFICATIONS = 'Snoozed notifications viewed'
+export const ARCHIVED_NOTIFICATIONS = 'Archived notifications viewed'
+// Groups
+export const GROUP_WORKSPACE = 'Workspace_metrics'
diff --git a/packages/constants/src/fetch-keys.ts b/packages/constants/src/fetch-keys.ts
new file mode 100644
index 0000000..ba947a0
--- /dev/null
+++ b/packages/constants/src/fetch-keys.ts
@@ -0,0 +1,433 @@
+import { objToQueryParams } from '@prodkt/helpers/string.helper'
+import {
+ IAnalyticsParams,
+ IJiraMetadata,
+ INotificationParams,
+} from '@prodkt/types'
+
+const paramsToKey = (params: any) => {
+ const {
+ state,
+ state_group,
+ priority,
+ mentions,
+ assignees,
+ created_by,
+ labels,
+ start_date,
+ target_date,
+ sub_issue,
+ project,
+ layout,
+ subscriber,
+ } = params
+
+ let projectKey = project ? project.split(',') : []
+ let stateKey = state ? state.split(',') : []
+ let stateGroupKey = state_group ? state_group.split(',') : []
+ let priorityKey = priority ? priority.split(',') : []
+ let mentionsKey = mentions ? mentions.split(',') : []
+ let assigneesKey = assignees ? assignees.split(',') : []
+ let createdByKey = created_by ? created_by.split(',') : []
+ let labelsKey = labels ? labels.split(',') : []
+ let subscriberKey = subscriber ? subscriber.split(',') : []
+ const startDateKey = start_date ?? ''
+ const targetDateKey = target_date ?? ''
+ const type = params.type ? params.type.toUpperCase() : 'NULL'
+ const groupBy = params.group_by ? params.group_by.toUpperCase() : 'NULL'
+ const orderBy = params.order_by ? params.order_by.toUpperCase() : 'NULL'
+ const layoutKey = layout ? layout.toUpperCase() : ''
+
+ // sorting each keys in ascending order
+ projectKey = projectKey.sort().join('_')
+ stateKey = stateKey.sort().join('_')
+ stateGroupKey = stateGroupKey.sort().join('_')
+ priorityKey = priorityKey.sort().join('_')
+ assigneesKey = assigneesKey.sort().join('_')
+ mentionsKey = mentionsKey.sort().join('_')
+ createdByKey = createdByKey.sort().join('_')
+ labelsKey = labelsKey.sort().join('_')
+ subscriberKey = subscriberKey.sort().join('_')
+
+ return `${layoutKey}_${projectKey}_${stateGroupKey}_${stateKey}_${priorityKey}_${assigneesKey}_${mentionsKey}_${createdByKey}_${type}_${groupBy}_${orderBy}_${labelsKey}_${startDateKey}_${targetDateKey}_${sub_issue}_${subscriberKey}`
+}
+
+const myIssuesParamsToKey = (params: any) => {
+ const {
+ assignees,
+ created_by,
+ labels,
+ priority,
+ state_group,
+ subscriber,
+ start_date,
+ target_date,
+ } = params
+
+ let assigneesKey = assignees ? assignees.split(',') : []
+ let createdByKey = created_by ? created_by.split(',') : []
+ let stateGroupKey = state_group ? state_group.split(',') : []
+ let subscriberKey = subscriber ? subscriber.split(',') : []
+ let priorityKey = priority ? priority.split(',') : []
+ let labelsKey = labels ? labels.split(',') : []
+ const startDateKey = start_date ?? ''
+ const targetDateKey = target_date ?? ''
+ const type = params?.type ? params.type.toUpperCase() : 'NULL'
+ const groupBy = params?.group_by ? params.group_by.toUpperCase() : 'NULL'
+ const orderBy = params?.order_by ? params.order_by.toUpperCase() : 'NULL'
+
+ // sorting each keys in ascending order
+ assigneesKey = assigneesKey.sort().join('_')
+ createdByKey = createdByKey.sort().join('_')
+ stateGroupKey = stateGroupKey.sort().join('_')
+ subscriberKey = subscriberKey.sort().join('_')
+ priorityKey = priorityKey.sort().join('_')
+ labelsKey = labelsKey.sort().join('_')
+
+ return `${assigneesKey}_${createdByKey}_${stateGroupKey}_${subscriberKey}_${priorityKey}_${type}_${groupBy}_${orderBy}_${labelsKey}_${startDateKey}_${targetDateKey}`
+}
+
+export const CURRENT_USER = 'CURRENT_USER'
+export const USER_WORKSPACE_INVITATIONS = 'USER_WORKSPACE_INVITATIONS'
+export const USER_WORKSPACES_LIST = 'USER_WORKSPACES_LIST'
+
+export const WORKSPACE_DETAILS = (workspaceSlug: string) =>
+ `WORKSPACE_DETAILS_${workspaceSlug.toUpperCase()}`
+
+export const WORKSPACE_MEMBERS = (workspaceSlug: string) =>
+ `WORKSPACE_MEMBERS_${workspaceSlug.toUpperCase()}`
+export const WORKSPACE_MEMBERS_ME = (workspaceSlug: string) =>
+ `WORKSPACE_MEMBERS_ME${workspaceSlug.toUpperCase()}`
+export const WORKSPACE_INVITATIONS = (workspaceSlug: string) =>
+ `WORKSPACE_INVITATIONS_${workspaceSlug.toString()}`
+export const WORKSPACE_INVITATION = (invitationId: string) =>
+ `WORKSPACE_INVITATION_${invitationId}`
+export const LAST_ACTIVE_WORKSPACE_AND_PROJECTS =
+ 'LAST_ACTIVE_WORKSPACE_AND_PROJECTS'
+
+export const PROJECTS_LIST = (
+ workspaceSlug: string,
+ params: {
+ is_favorite: 'all' | boolean
+ },
+) => {
+ if (!params) return `PROJECTS_LIST_${workspaceSlug.toUpperCase()}`
+
+ return `PROJECTS_LIST_${workspaceSlug.toUpperCase()}_${params.is_favorite.toString().toUpperCase()}`
+}
+export const PROJECT_DETAILS = (projectId: string) =>
+ `PROJECT_DETAILS_${projectId.toUpperCase()}`
+
+export const PROJECT_MEMBERS = (projectId: string) =>
+ `PROJECT_MEMBERS_${projectId.toUpperCase()}`
+export const PROJECT_INVITATIONS = (projectId: string) =>
+ `PROJECT_INVITATIONS_${projectId.toString()}`
+
+export const PROJECT_ISSUES_LIST = (workspaceSlug: string, projectId: string) =>
+ `PROJECT_ISSUES_LIST_${workspaceSlug.toUpperCase()}_${projectId.toUpperCase()}`
+export const PROJECT_ISSUES_LIST_WITH_PARAMS = (
+ projectId: string,
+ params?: any,
+) => {
+ if (!params)
+ return `PROJECT_ISSUES_LIST_WITH_PARAMS_${projectId.toUpperCase()}`
+
+ const paramsKey = paramsToKey(params)
+
+ return `PROJECT_ISSUES_LIST_WITH_PARAMS_${projectId.toUpperCase()}_${paramsKey}`
+}
+export const PROJECT_ARCHIVED_ISSUES_LIST_WITH_PARAMS = (
+ projectId: string,
+ params?: any,
+) => {
+ if (!params)
+ return `PROJECT_ARCHIVED_ISSUES_LIST_WITH_PARAMS_${projectId.toUpperCase()}`
+
+ const paramsKey = paramsToKey(params)
+
+ return `PROJECT_ARCHIVED_ISSUES_LIST_WITH_PARAMS_${projectId.toUpperCase()}_${paramsKey}`
+}
+
+export const PROJECT_DRAFT_ISSUES_LIST_WITH_PARAMS = (
+ projectId: string,
+ params?: any,
+) => {
+ if (!params)
+ return `PROJECT_DRAFT_ISSUES_LIST_WITH_PARAMS${projectId.toUpperCase()}`
+
+ const paramsKey = paramsToKey(params)
+
+ return `PROJECT_DRAFT_ISSUES_LIST_WITH_PARAMS${projectId.toUpperCase()}_${paramsKey}`
+}
+
+export const GLOBAL_VIEWS_LIST = (workspaceSlug: string) =>
+ `GLOBAL_VIEWS_LIST_${workspaceSlug.toUpperCase()}`
+export const GLOBAL_VIEW_DETAILS = (globalViewId: string) =>
+ `GLOBAL_VIEW_DETAILS_${globalViewId.toUpperCase()}`
+export const GLOBAL_VIEW_ISSUES = (globalViewId: string) =>
+ `GLOBAL_VIEW_ISSUES_${globalViewId.toUpperCase()}`
+
+export const PROJECT_ISSUES_DETAILS = (issueId: string) =>
+ `PROJECT_ISSUES_DETAILS_${issueId.toUpperCase()}`
+export const PROJECT_ISSUES_PROPERTIES = (projectId: string) =>
+ `PROJECT_ISSUES_PROPERTIES_${projectId.toUpperCase()}`
+export const PROJECT_ISSUES_COMMENTS = (issueId: string) =>
+ `PROJECT_ISSUES_COMMENTS_${issueId.toUpperCase()}`
+export const PROJECT_ISSUES_ACTIVITY = (issueId: string) =>
+ `PROJECT_ISSUES_ACTIVITY_${issueId.toUpperCase()}`
+export const PROJECT_ISSUE_BY_STATE = (projectId: string) =>
+ `PROJECT_ISSUE_BY_STATE_${projectId.toUpperCase()}`
+export const PROJECT_ISSUE_LABELS = (projectId: string) =>
+ `PROJECT_ISSUE_LABELS_${projectId.toUpperCase()}`
+export const WORKSPACE_LABELS = (workspaceSlug: string) =>
+ `WORKSPACE_LABELS_${workspaceSlug.toUpperCase()}`
+export const PROJECT_GITHUB_REPOSITORY = (projectId: string) =>
+ `PROJECT_GITHUB_REPOSITORY_${projectId.toUpperCase()}`
+
+// cycles
+export const CYCLES_LIST = (projectId: string) =>
+ `CYCLE_LIST_${projectId.toUpperCase()}`
+export const INCOMPLETE_CYCLES_LIST = (projectId: string) =>
+ `INCOMPLETE_CYCLES_LIST_${projectId.toUpperCase()}`
+export const CURRENT_CYCLE_LIST = (projectId: string) =>
+ `CURRENT_CYCLE_LIST_${projectId.toUpperCase()}`
+export const UPCOMING_CYCLES_LIST = (projectId: string) =>
+ `UPCOMING_CYCLES_LIST_${projectId.toUpperCase()}`
+export const DRAFT_CYCLES_LIST = (projectId: string) =>
+ `DRAFT_CYCLES_LIST_${projectId.toUpperCase()}`
+export const COMPLETED_CYCLES_LIST = (projectId: string) =>
+ `COMPLETED_CYCLES_LIST_${projectId.toUpperCase()}`
+export const CYCLE_ISSUES = (cycleId: string) =>
+ `CYCLE_ISSUES_${cycleId.toUpperCase()}`
+export const CYCLE_ISSUES_WITH_PARAMS = (cycleId: string, params?: any) => {
+ if (!params) return `CYCLE_ISSUES_WITH_PARAMS_${cycleId.toUpperCase()}`
+
+ const paramsKey = paramsToKey(params)
+
+ return `CYCLE_ISSUES_WITH_PARAMS_${cycleId.toUpperCase()}_${paramsKey.toUpperCase()}`
+}
+export const CYCLE_DETAILS = (cycleId: string) =>
+ `CYCLE_DETAILS_${cycleId.toUpperCase()}`
+
+export const STATES_LIST = (projectId: string) =>
+ `STATES_LIST_${projectId.toUpperCase()}`
+
+export const USER_ISSUE = (workspaceSlug: string) =>
+ `USER_ISSUE_${workspaceSlug.toUpperCase()}`
+export const USER_ISSUES = (workspaceSlug: string, params: any) => {
+ const paramsKey = myIssuesParamsToKey(params)
+
+ return `USER_ISSUES_${workspaceSlug.toUpperCase()}_${paramsKey}`
+}
+export const USER_ACTIVITY = (params: { cursor?: string }) =>
+ `USER_ACTIVITY_${params?.cursor}`
+export const USER_WORKSPACE_DASHBOARD = (workspaceSlug: string) =>
+ `USER_WORKSPACE_DASHBOARD_${workspaceSlug.toUpperCase()}`
+export const USER_PROJECT_VIEW = (projectId: string) =>
+ `USER_PROJECT_VIEW_${projectId.toUpperCase()}`
+
+export const MODULE_LIST = (projectId: string) =>
+ `MODULE_LIST_${projectId.toUpperCase()}`
+export const MODULE_ISSUES = (moduleId: string) =>
+ `MODULE_ISSUES_${moduleId.toUpperCase()}`
+export const MODULE_ISSUES_WITH_PARAMS = (moduleId: string, params?: any) => {
+ if (!params) return `MODULE_ISSUES_WITH_PARAMS_${moduleId.toUpperCase()}`
+
+ const paramsKey = paramsToKey(params)
+
+ return `MODULE_ISSUES_WITH_PARAMS_${moduleId.toUpperCase()}_${paramsKey.toUpperCase()}`
+}
+export const MODULE_DETAILS = (moduleId: string) =>
+ `MODULE_DETAILS_${moduleId.toUpperCase()}`
+
+export const VIEWS_LIST = (projectId: string) =>
+ `VIEWS_LIST_${projectId.toUpperCase()}`
+export const VIEW_DETAILS = (viewId: string) =>
+ `VIEW_DETAILS_${viewId.toUpperCase()}`
+export const VIEW_ISSUES = (viewId: string, params: any) => {
+ if (!params) return `VIEW_ISSUES_${viewId.toUpperCase()}`
+
+ const paramsKey = paramsToKey(params)
+
+ return `VIEW_ISSUES_${viewId.toUpperCase()}_${paramsKey.toUpperCase()}`
+}
+
+// Issues
+export const ISSUE_DETAILS = (issueId: string) =>
+ `ISSUE_DETAILS_${issueId.toUpperCase()}`
+export const SUB_ISSUES = (issueId: string) =>
+ `SUB_ISSUES_${issueId.toUpperCase()}`
+export const ISSUE_ATTACHMENTS = (issueId: string) =>
+ `ISSUE_ATTACHMENTS_${issueId.toUpperCase()}`
+export const ARCHIVED_ISSUE_DETAILS = (issueId: string) =>
+ `ARCHIVED_ISSUE_DETAILS_${issueId.toUpperCase()}`
+
+// integrations
+export const APP_INTEGRATIONS = 'APP_INTEGRATIONS'
+export const WORKSPACE_INTEGRATIONS = (workspaceSlug: string) =>
+ `WORKSPACE_INTEGRATIONS_${workspaceSlug.toUpperCase()}`
+
+export const JIRA_IMPORTER_DETAIL = (
+ workspaceSlug: string,
+ params: IJiraMetadata,
+) => {
+ const { api_token, cloud_hostname, email, project_key } = params
+
+ return `JIRA_IMPORTER_DETAIL_${workspaceSlug.toUpperCase()}_${api_token}_${cloud_hostname}_${email}_${project_key}`
+}
+
+//import-export
+export const IMPORTER_SERVICES_LIST = (workspaceSlug: string) =>
+ `IMPORTER_SERVICES_LIST_${workspaceSlug.toUpperCase()}`
+
+//export
+export const EXPORT_SERVICES_LIST = (
+ workspaceSlug: string,
+ cursor: string,
+ per_page: string,
+) =>
+ `EXPORTER_SERVICES_LIST_${workspaceSlug.toUpperCase()}_${cursor.toUpperCase()}_${per_page.toUpperCase()}`
+
+// github-importer
+export const GITHUB_REPOSITORY_INFO = (
+ workspaceSlug: string,
+ repoName: string,
+) =>
+ `GITHUB_REPO_INFO_${workspaceSlug.toString().toUpperCase()}_${repoName.toUpperCase()}`
+
+// slack-project-integration
+export const SLACK_CHANNEL_INFO = (workspaceSlug: string, projectId: string) =>
+ `SLACK_CHANNEL_INFO_${workspaceSlug.toString().toUpperCase()}_${projectId.toUpperCase()}`
+
+// Pages
+export const RECENT_PAGES_LIST = (projectId: string) =>
+ `RECENT_PAGES_LIST_${projectId.toUpperCase()}`
+export const ALL_PAGES_LIST = (projectId: string) =>
+ `ALL_PAGES_LIST_${projectId.toUpperCase()}`
+export const ARCHIVED_PAGES_LIST = (projectId: string) =>
+ `ARCHIVED_PAGES_LIST_${projectId.toUpperCase}`
+export const FAVORITE_PAGES_LIST = (projectId: string) =>
+ `FAVORITE_PAGES_LIST_${projectId.toUpperCase()}`
+export const PRIVATE_PAGES_LIST = (projectId: string) =>
+ `PRIVATE_PAGES_LIST_${projectId.toUpperCase()}`
+export const SHARED_PAGES_LIST = (projectId: string) =>
+ `SHARED_PAGES_LIST_${projectId.toUpperCase()}`
+export const PAGE_DETAILS = (pageId: string) =>
+ `PAGE_DETAILS_${pageId.toUpperCase()}`
+export const PAGE_BLOCKS_LIST = (pageId: string) =>
+ `PAGE_BLOCK_LIST_${pageId.toUpperCase()}`
+export const PAGE_BLOCK_DETAILS = (pageId: string) =>
+ `PAGE_BLOCK_DETAILS_${pageId.toUpperCase()}`
+export const MY_PAGES_LIST = (pageId: string) => `MY_PAGE_LIST_${pageId}`
+// estimates
+export const ESTIMATES_LIST = (projectId: string) =>
+ `ESTIMATES_LIST_${projectId.toUpperCase()}`
+export const ESTIMATE_DETAILS = (estimateId: string) =>
+ `ESTIMATE_DETAILS_${estimateId.toUpperCase()}`
+
+// analytics
+export const ANALYTICS = (workspaceSlug: string, params: IAnalyticsParams) =>
+ `ANALYTICS${workspaceSlug.toUpperCase()}_${params.x_axis}_${params.y_axis}_${
+ params.segment
+ }_${params.project?.toString()}`
+export const DEFAULT_ANALYTICS = (
+ workspaceSlug: string,
+ params?: Partial,
+) =>
+ `DEFAULT_ANALYTICS_${workspaceSlug.toUpperCase()}_${params?.project?.toString()}_${params?.cycle}_${params?.module}`
+
+// notifications
+export const USER_WORKSPACE_NOTIFICATIONS = (
+ workspaceSlug: string,
+ params: INotificationParams,
+) => {
+ const { type, snoozed, archived, read } = params
+
+ return `USER_WORKSPACE_NOTIFICATIONS_${workspaceSlug?.toUpperCase()}_TYPE_${(
+ type ?? 'assigned'
+ )?.toUpperCase()}_SNOOZED_${snoozed}_ARCHIVED_${archived}_READ_${read}`
+}
+
+export const USER_WORKSPACE_NOTIFICATIONS_DETAILS = (
+ workspaceSlug: string,
+ notificationId: string,
+) =>
+ `USER_WORKSPACE_NOTIFICATIONS_DETAILS_${workspaceSlug?.toUpperCase()}_${notificationId?.toUpperCase()}`
+
+export const UNREAD_NOTIFICATIONS_COUNT = (workspaceSlug: string) =>
+ `UNREAD_NOTIFICATIONS_COUNT_${workspaceSlug?.toUpperCase()}`
+
+export const getPaginatedNotificationKey = (
+ index: number,
+ prevData: any,
+ workspaceSlug: string,
+ params: any,
+) => {
+ if (prevData && !prevData?.results?.length) return null
+
+ if (index === 0)
+ return `/api/workspaces/${workspaceSlug}/users/notifications?${objToQueryParams(
+ {
+ ...params,
+ cursor: '30:0:0',
+ },
+ )}`
+
+ const cursor = prevData?.next_cursor
+ const nextPageResults = prevData?.next_page_results
+
+ if (!nextPageResults) return null
+
+ return `/api/workspaces/${workspaceSlug}/users/notifications?${objToQueryParams(
+ {
+ ...params,
+ cursor,
+ },
+ )}`
+}
+
+// profile
+export const USER_PROFILE_DATA = (workspaceSlug: string, userId: string) =>
+ `USER_PROFILE_ACTIVITY_${workspaceSlug.toUpperCase()}_${userId.toUpperCase()}`
+export const USER_PROFILE_ACTIVITY = (
+ workspaceSlug: string,
+ userId: string,
+ params: {
+ cursor?: string
+ },
+) =>
+ `USER_WORKSPACE_PROFILE_ACTIVITY_${workspaceSlug.toUpperCase()}_${userId.toUpperCase()}_${params?.cursor}`
+export const USER_PROFILE_PROJECT_SEGREGATION = (
+ workspaceSlug: string,
+ userId: string,
+) =>
+ `USER_PROFILE_PROJECT_SEGREGATION_${workspaceSlug.toUpperCase()}_${userId.toUpperCase()}`
+export const USER_PROFILE_ISSUES = (
+ workspaceSlug: string,
+ userId: string,
+ params: any,
+) => {
+ const paramsKey = myIssuesParamsToKey(params)
+
+ return `USER_PROFILE_ISSUES_${workspaceSlug.toUpperCase()}_${userId.toUpperCase()}_${paramsKey}`
+}
+
+// reactions
+export const ISSUE_REACTION_LIST = (
+ workspaceSlug: string,
+ projectId: string,
+ issueId: string,
+) =>
+ `ISSUE_REACTION_LIST_${workspaceSlug.toUpperCase()}_${projectId.toUpperCase()}_${issueId.toUpperCase()}`
+export const COMMENT_REACTION_LIST = (
+ workspaceSlug: string,
+ projectId: string,
+ commendId: string,
+) =>
+ `COMMENT_REACTION_LIST_${workspaceSlug.toUpperCase()}_${projectId.toUpperCase()}_${commendId.toUpperCase()}`
+
+// api-tokens
+export const API_TOKENS_LIST = (workspaceSlug: string) =>
+ `API_TOKENS_LIST_${workspaceSlug.toUpperCase()}`
+export const API_TOKEN_DETAILS = (workspaceSlug: string, tokenId: string) =>
+ `API_TOKEN_DETAILS_${workspaceSlug.toUpperCase()}_${tokenId.toUpperCase()}`
diff --git a/packages/constants/src/filters.ts b/packages/constants/src/filters.ts
new file mode 100644
index 0000000..dcaa988
--- /dev/null
+++ b/packages/constants/src/filters.ts
@@ -0,0 +1,52 @@
+export const DATE_AFTER_FILTER_OPTIONS = [
+ {
+ name: '1 week from now',
+ value: '1_weeks;after;fromnow',
+ },
+ {
+ name: '2 weeks from now',
+ value: '2_weeks;after;fromnow',
+ },
+ {
+ name: '1 month from now',
+ value: '1_months;after;fromnow',
+ },
+ {
+ name: '2 months from now',
+ value: '2_months;after;fromnow',
+ },
+]
+
+export const DATE_BEFORE_FILTER_OPTIONS = [
+ {
+ name: '1 week ago',
+ value: '1_weeks;before;fromnow',
+ },
+ {
+ name: '2 weeks ago',
+ value: '2_weeks;before;fromnow',
+ },
+ {
+ name: '1 month ago',
+ value: '1_months;before;fromnow',
+ },
+]
+
+export const PROJECT_CREATED_AT_FILTER_OPTIONS = [
+ {
+ name: 'Today',
+ value: 'today;custom;custom',
+ },
+ {
+ name: 'Yesterday',
+ value: 'yesterday;custom;custom',
+ },
+ {
+ name: 'Last 7 days',
+ value: 'last_7_days;custom;custom',
+ },
+ {
+ name: 'Last 30 days',
+ value: 'last_30_days;custom;custom',
+ },
+]
diff --git a/packages/constants/src/graph.ts b/packages/constants/src/graph.ts
new file mode 100644
index 0000000..3fb7da9
--- /dev/null
+++ b/packages/constants/src/graph.ts
@@ -0,0 +1,36 @@
+// nivo
+
+import { Theme } from '@nivo/core'
+
+export const CHARTS_THEME: Theme = {
+ background: 'transparent',
+ textColor: 'rgb(var(--color-text-200))',
+ axis: {
+ domain: {
+ line: {
+ stroke: 'rgb(var(--color-background-80))',
+ strokeWidth: 0.5,
+ },
+ },
+ },
+ tooltip: {
+ container: {
+ background: 'rgb(var(--color-background-80))',
+ color: 'rgb(var(--color-text-200))',
+ fontSize: '0.8rem',
+ border: '1px solid rgb(var(--color-border-300))',
+ },
+ },
+ grid: {
+ line: {
+ stroke: 'rgb(var(--color-border-100))',
+ },
+ },
+}
+
+export const DEFAULT_MARGIN = {
+ top: 50,
+ right: 50,
+ bottom: 50,
+ left: 50,
+}
diff --git a/packages/constants/src/inbox.tsx b/packages/constants/src/inbox.tsx
new file mode 100644
index 0000000..604e0e4
--- /dev/null
+++ b/packages/constants/src/inbox.tsx
@@ -0,0 +1,121 @@
+// icons
+
+import {
+ AlertTriangle,
+ CheckCircle2,
+ Clock,
+ Copy,
+ LucideIcon,
+ XCircle,
+} from 'lucide-react'
+
+// helpers
+import { findHowManyDaysLeft } from '@prodkt/helpers/date-time.helper'
+import { EInboxIssueStatus } from '@prodkt/helpers/inbox.helper'
+// types
+import {
+ TInboxIssueSortingOrderByKeys,
+ TInboxIssueSortingSortByKeys,
+ TInboxIssueStatus,
+} from '@prodkt/types'
+
+export const INBOX_STATUS: {
+ key: string
+ status: TInboxIssueStatus
+ icon: LucideIcon
+ title: string
+ description: (snoozedTillDate: Date) => string
+ textColor: (snoozeDatePassed: boolean) => string
+ bgColor: (snoozeDatePassed: boolean) => string
+}[] = [
+ {
+ key: 'pending',
+ status: EInboxIssueStatus.PENDING,
+ icon: AlertTriangle,
+ title: 'Pending',
+ description: () => `Pending`,
+ textColor: (snoozeDatePassed: boolean = false) =>
+ snoozeDatePassed ? '' : 'text-[#AB6400]',
+ bgColor: (snoozeDatePassed: boolean = false) =>
+ snoozeDatePassed ? '' : 'bg-[#FFF7C2]',
+ },
+ {
+ key: 'declined',
+ status: EInboxIssueStatus.DECLINED,
+ icon: XCircle,
+ title: 'Declined',
+ description: () => `Declined`,
+ textColor: (snoozeDatePassed: boolean = false) =>
+ snoozeDatePassed ? '' : 'text-[#CE2C31]',
+ bgColor: (snoozeDatePassed: boolean = false) =>
+ snoozeDatePassed ? '' : 'bg-[#FEEBEC]',
+ },
+ {
+ key: 'snoozed',
+ status: EInboxIssueStatus.SNOOZED,
+ icon: Clock,
+ title: 'Snoozed',
+ description: (snoozedTillDate: Date = new Date()) =>
+ `${findHowManyDaysLeft(snoozedTillDate)} days to go`,
+ textColor: (snoozeDatePassed: boolean = false) =>
+ snoozeDatePassed ? 'text-red-500' : 'text-custom-text-400',
+ bgColor: (snoozeDatePassed: boolean = false) =>
+ snoozeDatePassed ? 'bg-red-500/10' : 'bg-[#E0E1E6]',
+ },
+ {
+ key: 'accepted',
+ status: EInboxIssueStatus.ACCEPTED,
+ icon: CheckCircle2,
+ title: 'Accepted',
+ description: () => `Accepted`,
+ textColor: (snoozeDatePassed: boolean = false) =>
+ snoozeDatePassed ? '' : 'text-[#3E9B4F]',
+ bgColor: (snoozeDatePassed: boolean = false) =>
+ snoozeDatePassed ? '' : 'bg-[#E9F6E9]',
+ },
+ {
+ key: 'duplicate',
+ status: EInboxIssueStatus.DUPLICATE,
+ icon: Copy,
+ title: 'Duplicate',
+ description: () => `Duplicate`,
+ textColor: (snoozeDatePassed: boolean = false) =>
+ snoozeDatePassed ? '' : 'text-custom-text-200',
+ bgColor: (snoozeDatePassed: boolean = false) =>
+ snoozeDatePassed ? '' : 'bg-gray-500/10',
+ },
+]
+
+export const INBOX_ISSUE_SOURCE = 'in-app'
+
+export const INBOX_ISSUE_ORDER_BY_OPTIONS: {
+ key: TInboxIssueSortingOrderByKeys
+ label: string
+}[] = [
+ {
+ key: 'issue__created_at',
+ label: 'Date created',
+ },
+ {
+ key: 'issue__updated_at',
+ label: 'Date updated',
+ },
+ {
+ key: 'issue__sequence_id',
+ label: 'ID',
+ },
+]
+
+export const INBOX_ISSUE_SORT_BY_OPTIONS: {
+ key: TInboxIssueSortingSortByKeys
+ label: string
+}[] = [
+ {
+ key: 'asc',
+ label: 'Ascending',
+ },
+ {
+ key: 'desc',
+ label: 'Descending',
+ },
+]
diff --git a/packages/constants/src/index.ts b/packages/constants/src/index.ts
new file mode 100644
index 0000000..96f661a
--- /dev/null
+++ b/packages/constants/src/index.ts
@@ -0,0 +1,30 @@
+export * from './auth'
+export * from './analytics'
+export * from './archives'
+export * from './auth'
+export * from './calendar'
+export * from './common'
+export * from './cycle'
+export * from './dashboard'
+export * from './editor'
+export * from './empty-state'
+export * from './event-tracker'
+export * from './fetch-keys'
+export * from './filters'
+export * from './graph'
+export * from './inbox'
+export * from './index'
+export * from './issue'
+export * from './label'
+export * from './module'
+export * from './notification'
+export * from './page'
+export * from './profile'
+export * from './project'
+export * from './seo-variables'
+export * from './spreadsheet'
+export * from './state'
+export * from './swr-config'
+export * from './themes'
+export * from './timezones'
+export * from './workspace'
diff --git a/packages/constants/src/issue.ts b/packages/constants/src/issue.ts
new file mode 100644
index 0000000..1de269e
--- /dev/null
+++ b/packages/constants/src/issue.ts
@@ -0,0 +1,578 @@
+// icons
+
+import { Calendar, GanttChartSquare, Kanban, List, Sheet } from 'lucide-react'
+
+// types
+import {
+ IIssueDisplayProperties,
+ IIssueFilterOptions,
+ TIssueExtraOptions,
+ TIssueGroupByOptions,
+ TIssueLayouts,
+ TIssueOrderByOptions,
+ TIssuePriorities,
+ TIssueTypeFilters,
+} from '@prodkt/types'
+
+export const DRAG_ALLOWED_GROUPS: TIssueGroupByOptions[] = [
+ 'state',
+ 'priority',
+ 'assignees',
+ 'labels',
+ 'module',
+ 'cycle',
+]
+
+export enum EIssuesStoreType {
+ GLOBAL = 'GLOBAL',
+ PROFILE = 'PROFILE',
+ PROJECT = 'PROJECT',
+ CYCLE = 'CYCLE',
+ MODULE = 'MODULE',
+ PROJECT_VIEW = 'PROJECT_VIEW',
+ ARCHIVED = 'ARCHIVED',
+ DRAFT = 'DRAFT',
+ DEFAULT = 'DEFAULT',
+}
+
+export type TCreateModalStoreTypes =
+ | EIssuesStoreType.PROJECT
+ | EIssuesStoreType.PROJECT_VIEW
+ | EIssuesStoreType.PROFILE
+ | EIssuesStoreType.CYCLE
+ | EIssuesStoreType.MODULE
+
+export enum EIssueFilterType {
+ FILTERS = 'filters',
+ DISPLAY_FILTERS = 'display_filters',
+ DISPLAY_PROPERTIES = 'display_properties',
+ KANBAN_FILTERS = 'kanban_filters',
+}
+
+export enum EIssueCommentAccessSpecifier {
+ EXTERNAL = 'EXTERNAL',
+ INTERNAL = 'INTERNAL',
+}
+
+export const ISSUE_PRIORITIES: {
+ key: TIssuePriorities
+ title: string
+}[] = [
+ { key: 'urgent', title: 'Urgent' },
+ { key: 'high', title: 'High' },
+ { key: 'medium', title: 'Medium' },
+ { key: 'low', title: 'Low' },
+ { key: 'none', title: 'None' },
+]
+
+export const ISSUE_GROUP_BY_OPTIONS: {
+ key: TIssueGroupByOptions
+ title: string
+}[] = [
+ { key: 'state', title: 'States' },
+ { key: 'state_detail.group', title: 'State Groups' },
+ { key: 'priority', title: 'Priority' },
+ { key: 'project', title: 'Project' }, // required this on my issues
+ { key: 'cycle', title: 'Cycle' }, // required this on my issues
+ { key: 'module', title: 'Module' }, // required this on my issues
+ { key: 'labels', title: 'Labels' },
+ { key: 'assignees', title: 'Assignees' },
+ { key: 'created_by', title: 'Created By' },
+ { key: null, title: 'None' },
+]
+
+export const ISSUE_ORDER_BY_OPTIONS: {
+ key: TIssueOrderByOptions
+ title: string
+}[] = [
+ { key: 'sort_order', title: 'Manual' },
+ { key: '-created_at', title: 'Last Created' },
+ { key: '-updated_at', title: 'Last Updated' },
+ { key: 'start_date', title: 'Start Date' },
+ { key: 'target_date', title: 'Due Date' },
+ { key: '-priority', title: 'Priority' },
+]
+
+export const ISSUE_FILTER_OPTIONS: {
+ key: TIssueTypeFilters
+ title: string
+}[] = [
+ { key: null, title: 'All' },
+ { key: 'active', title: 'Active Issues' },
+ { key: 'backlog', title: 'Backlog Issues' },
+ // { key: "draft", title: "Draft Issues" },
+]
+
+export const ISSUE_DISPLAY_PROPERTIES: {
+ key: keyof IIssueDisplayProperties
+ title: string
+}[] = [
+ { key: 'assignee', title: 'Assignee' },
+ { key: 'start_date', title: 'Start date' },
+ { key: 'due_date', title: 'Due date' },
+ { key: 'key', title: 'ID' },
+ { key: 'labels', title: 'Labels' },
+ { key: 'priority', title: 'Priority' },
+ { key: 'state', title: 'State' },
+ { key: 'sub_issue_count', title: 'Sub issue count' },
+ { key: 'attachment_count', title: 'Attachment count' },
+ { key: 'link', title: 'Link' },
+ { key: 'estimate', title: 'Estimate' },
+ { key: 'modules', title: 'Modules' },
+ { key: 'cycle', title: 'Cycle' },
+]
+
+export const ISSUE_EXTRA_OPTIONS: {
+ key: TIssueExtraOptions
+ title: string
+}[] = [
+ { key: 'sub_issue', title: 'Show sub-issues' }, // in spreadsheet its always false
+ { key: 'show_empty_groups', title: 'Show empty groups' }, // filter on front-end
+]
+
+export const ISSUE_LAYOUTS: {
+ key: TIssueLayouts
+ title: string
+ icon: any
+}[] = [
+ { key: 'list', title: 'List Layout', icon: List },
+ { key: 'kanban', title: 'Kanban Layout', icon: Kanban },
+ { key: 'calendar', title: 'Calendar Layout', icon: Calendar },
+ { key: 'spreadsheet', title: 'Spreadsheet Layout', icon: Sheet },
+ { key: 'gantt_chart', title: 'Gantt Chart Layout', icon: GanttChartSquare },
+]
+
+export interface ILayoutDisplayFiltersOptions {
+ filters: (keyof IIssueFilterOptions)[]
+ display_properties: boolean
+ display_filters: {
+ group_by?: TIssueGroupByOptions[]
+ sub_group_by?: TIssueGroupByOptions[]
+ order_by?: TIssueOrderByOptions[]
+ type?: TIssueTypeFilters[]
+ }
+ extra_options: {
+ access: boolean
+ values: TIssueExtraOptions[]
+ }
+}
+
+export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
+ [pageType: string]: { [layoutType: string]: ILayoutDisplayFiltersOptions }
+} = {
+ profile_issues: {
+ list: {
+ filters: [
+ 'priority',
+ 'state_group',
+ 'labels',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: true,
+ display_filters: {
+ group_by: ['state_detail.group', 'priority', 'project', 'labels', null],
+ order_by: [
+ 'sort_order',
+ '-created_at',
+ '-updated_at',
+ 'start_date',
+ '-priority',
+ ],
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['show_empty_groups', 'sub_issue'],
+ },
+ },
+ kanban: {
+ filters: [
+ 'priority',
+ 'state_group',
+ 'labels',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: true,
+ display_filters: {
+ group_by: ['state_detail.group', 'priority', 'project', 'labels'],
+ order_by: [
+ 'sort_order',
+ '-created_at',
+ '-updated_at',
+ 'start_date',
+ '-priority',
+ ],
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['show_empty_groups'],
+ },
+ },
+ },
+ archived_issues: {
+ list: {
+ filters: [
+ 'priority',
+ 'state',
+ 'cycle',
+ 'module',
+ 'assignees',
+ 'created_by',
+ 'labels',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: true,
+ display_filters: {
+ group_by: [
+ 'state',
+ 'cycle',
+ 'module',
+ 'state_detail.group',
+ 'priority',
+ 'labels',
+ 'assignees',
+ 'created_by',
+ null,
+ ],
+ order_by: [
+ 'sort_order',
+ '-created_at',
+ '-updated_at',
+ 'start_date',
+ '-priority',
+ ],
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['show_empty_groups'],
+ },
+ },
+ },
+ draft_issues: {
+ list: {
+ filters: [
+ 'priority',
+ 'state_group',
+ 'cycle',
+ 'module',
+ 'labels',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: true,
+ display_filters: {
+ group_by: [
+ 'state_detail.group',
+ 'cycle',
+ 'module',
+ 'priority',
+ 'project',
+ 'labels',
+ null,
+ ],
+ order_by: [
+ 'sort_order',
+ '-created_at',
+ '-updated_at',
+ 'start_date',
+ '-priority',
+ ],
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['show_empty_groups'],
+ },
+ },
+ kanban: {
+ filters: [
+ 'priority',
+ 'state_group',
+ 'cycle',
+ 'module',
+ 'labels',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: true,
+ display_filters: {
+ group_by: [
+ 'state_detail.group',
+ 'cycle',
+ 'module',
+ 'priority',
+ 'project',
+ 'labels',
+ ],
+ order_by: [
+ 'sort_order',
+ '-created_at',
+ '-updated_at',
+ 'start_date',
+ '-priority',
+ ],
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['show_empty_groups'],
+ },
+ },
+ },
+ my_issues: {
+ spreadsheet: {
+ filters: [
+ 'priority',
+ 'state_group',
+ 'labels',
+ 'assignees',
+ 'created_by',
+ 'subscriber',
+ 'project',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: true,
+ display_filters: {
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['sub_issue'],
+ },
+ },
+ list: {
+ filters: [
+ 'priority',
+ 'state_group',
+ 'labels',
+ 'assignees',
+ 'created_by',
+ 'subscriber',
+ 'project',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: true,
+ display_filters: {
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: false,
+ values: [],
+ },
+ },
+ },
+ issues: {
+ list: {
+ filters: [
+ 'priority',
+ 'state',
+ 'cycle',
+ 'module',
+ 'assignees',
+ 'mentions',
+ 'created_by',
+ 'labels',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: true,
+ display_filters: {
+ group_by: [
+ 'state',
+ 'priority',
+ 'cycle',
+ 'module',
+ 'labels',
+ 'assignees',
+ 'created_by',
+ null,
+ ],
+ order_by: [
+ 'sort_order',
+ '-created_at',
+ '-updated_at',
+ 'start_date',
+ '-priority',
+ ],
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['show_empty_groups', 'sub_issue'],
+ },
+ },
+ kanban: {
+ filters: [
+ 'priority',
+ 'state',
+ 'cycle',
+ 'module',
+ 'assignees',
+ 'mentions',
+ 'created_by',
+ 'labels',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: true,
+ display_filters: {
+ group_by: [
+ 'state',
+ 'priority',
+ 'cycle',
+ 'module',
+ 'labels',
+ 'assignees',
+ 'created_by',
+ ],
+ sub_group_by: [
+ 'state',
+ 'priority',
+ 'cycle',
+ 'module',
+ 'labels',
+ 'assignees',
+ 'created_by',
+ null,
+ ],
+ order_by: [
+ 'sort_order',
+ '-created_at',
+ '-updated_at',
+ 'start_date',
+ '-priority',
+ 'target_date',
+ ],
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['show_empty_groups', 'sub_issue'],
+ },
+ },
+ calendar: {
+ filters: [
+ 'priority',
+ 'state',
+ 'cycle',
+ 'module',
+ 'assignees',
+ 'mentions',
+ 'created_by',
+ 'labels',
+ 'start_date',
+ ],
+ display_properties: false,
+ display_filters: {
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['sub_issue'],
+ },
+ },
+ spreadsheet: {
+ filters: [
+ 'priority',
+ 'state',
+ 'cycle',
+ 'module',
+ 'assignees',
+ 'mentions',
+ 'created_by',
+ 'labels',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: true,
+ display_filters: {
+ order_by: [
+ 'sort_order',
+ '-created_at',
+ '-updated_at',
+ 'start_date',
+ '-priority',
+ ],
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['sub_issue'],
+ },
+ },
+ gantt_chart: {
+ filters: [
+ 'priority',
+ 'state',
+ 'cycle',
+ 'module',
+ 'assignees',
+ 'mentions',
+ 'created_by',
+ 'labels',
+ 'start_date',
+ 'target_date',
+ ],
+ display_properties: false,
+ display_filters: {
+ order_by: [
+ 'sort_order',
+ '-created_at',
+ '-updated_at',
+ 'start_date',
+ '-priority',
+ ],
+ type: [null, 'active', 'backlog'],
+ },
+ extra_options: {
+ access: true,
+ values: ['sub_issue'],
+ },
+ },
+ },
+}
+
+export enum EIssueListRow {
+ HEADER = 'HEADER',
+ ISSUE = 'ISSUE',
+ NO_ISSUES = 'NO_ISSUES',
+ QUICK_ADD = 'QUICK_ADD',
+}
+
+// issue reactions
+export const issueReactionEmojis = [
+ '128077',
+ '128078',
+ '128516',
+ '128165',
+ '128533',
+ '129505',
+ '9992',
+ '128064',
+]
+
+export const groupReactionEmojis = (reactions: any) => {
+ let groupedEmojis: any = {}
+
+ issueReactionEmojis.map((_r) => {
+ groupedEmojis = { ...groupedEmojis, [_r]: [] }
+ })
+
+ if (reactions && reactions.length > 0) {
+ reactions.map((_reaction: any) => {
+ groupedEmojis = {
+ ...groupedEmojis,
+ [_reaction.reaction]: [...groupedEmojis[_reaction.reaction], _reaction],
+ }
+ })
+ }
+
+ return groupedEmojis
+}
diff --git a/packages/constants/src/label.ts b/packages/constants/src/label.ts
new file mode 100644
index 0000000..9c14ab2
--- /dev/null
+++ b/packages/constants/src/label.ts
@@ -0,0 +1,17 @@
+export const LABEL_COLOR_OPTIONS = [
+ '#FF6900',
+ '#FCB900',
+ '#7BDCB5',
+ '#00D084',
+ '#8ED1FC',
+ '#0693E3',
+ '#ABB8C3',
+ '#EB144C',
+ '#F78DA7',
+ '#9900EF',
+]
+
+export const getRandomLabelColor = () => {
+ const randomIndex = Math.floor(Math.random() * LABEL_COLOR_OPTIONS.length)
+ return LABEL_COLOR_OPTIONS[randomIndex]
+}
diff --git a/packages/constants/src/module.ts b/packages/constants/src/module.ts
new file mode 100644
index 0000000..b783875
--- /dev/null
+++ b/packages/constants/src/module.ts
@@ -0,0 +1,111 @@
+import { GanttChartSquare, LayoutGrid, List } from 'lucide-react'
+
+// types
+import {
+ TModuleLayoutOptions,
+ TModuleOrderByOptions,
+ TModuleStatus,
+} from '@prodkt/types'
+
+export const MODULE_STATUS: {
+ label: string
+ value: TModuleStatus
+ color: string
+ textColor: string
+ bgColor: string
+}[] = [
+ {
+ label: 'Backlog',
+ value: 'backlog',
+ color: '#a3a3a2',
+ textColor: 'text-custom-text-400',
+ bgColor: 'bg-custom-background-80',
+ },
+ {
+ label: 'Planned',
+ value: 'planned',
+ color: '#3f76ff',
+ textColor: 'text-blue-500',
+ bgColor: 'bg-indigo-50',
+ },
+ {
+ label: 'In Progress',
+ value: 'in-progress',
+ color: '#f39e1f',
+ textColor: 'text-amber-500',
+ bgColor: 'bg-amber-50',
+ },
+ {
+ label: 'Paused',
+ value: 'paused',
+ color: '#525252',
+ textColor: 'text-custom-text-300',
+ bgColor: 'bg-custom-background-90',
+ },
+ {
+ label: 'Completed',
+ value: 'completed',
+ color: '#16a34a',
+ textColor: 'text-green-600',
+ bgColor: 'bg-green-100',
+ },
+ {
+ label: 'Cancelled',
+ value: 'cancelled',
+ color: '#ef4444',
+ textColor: 'text-red-500',
+ bgColor: 'bg-red-50',
+ },
+]
+
+export const MODULE_VIEW_LAYOUTS: {
+ key: TModuleLayoutOptions
+ icon: any
+ title: string
+}[] = [
+ {
+ key: 'list',
+ icon: List,
+ title: 'List layout',
+ },
+ {
+ key: 'board',
+ icon: LayoutGrid,
+ title: 'Grid layout',
+ },
+ {
+ key: 'gantt',
+ icon: GanttChartSquare,
+ title: 'Gantt layout',
+ },
+]
+
+export const MODULE_ORDER_BY_OPTIONS: {
+ key: TModuleOrderByOptions
+ label: string
+}[] = [
+ {
+ key: 'name',
+ label: 'Name',
+ },
+ {
+ key: 'progress',
+ label: 'Progress',
+ },
+ {
+ key: 'issues_length',
+ label: 'Number of issues',
+ },
+ {
+ key: 'target_date',
+ label: 'Due date',
+ },
+ {
+ key: 'created_at',
+ label: 'Created date',
+ },
+ {
+ key: 'sort_order',
+ label: 'Manual',
+ },
+]
diff --git a/packages/constants/src/notification.ts b/packages/constants/src/notification.ts
new file mode 100644
index 0000000..5001da7
--- /dev/null
+++ b/packages/constants/src/notification.ts
@@ -0,0 +1,57 @@
+export const snoozeOptions = [
+ {
+ label: '1 day',
+ value: new Date(new Date().getTime() + 24 * 60 * 60 * 1000),
+ },
+ {
+ label: '3 days',
+ value: new Date(new Date().getTime() + 3 * 24 * 60 * 60 * 1000),
+ },
+ {
+ label: '5 days',
+ value: new Date(new Date().getTime() + 5 * 24 * 60 * 60 * 1000),
+ },
+ {
+ label: '1 week',
+ value: new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000),
+ },
+ {
+ label: '2 weeks',
+ value: new Date(new Date().getTime() + 14 * 24 * 60 * 60 * 1000),
+ },
+ {
+ label: 'Custom',
+ value: null,
+ },
+]
+
+// Constant for all time values in 30 minutes interval in 12 hours format
+export const allTimeIn30MinutesInterval12HoursFormat: Array<{
+ label: string
+ value: string
+}> = [
+ { label: '12:00', value: '12:00' },
+ { label: '12:30', value: '12:30' },
+ { label: '01:00', value: '01:00' },
+ { label: '01:30', value: '01:30' },
+ { label: '02:00', value: '02:00' },
+ { label: '02:30', value: '02:30' },
+ { label: '03:00', value: '03:00' },
+ { label: '03:30', value: '03:30' },
+ { label: '04:00', value: '04:00' },
+ { label: '04:30', value: '04:30' },
+ { label: '05:00', value: '05:00' },
+ { label: '05:30', value: '05:30' },
+ { label: '06:00', value: '06:00' },
+ { label: '06:30', value: '06:30' },
+ { label: '07:00', value: '07:00' },
+ { label: '07:30', value: '07:30' },
+ { label: '08:00', value: '08:00' },
+ { label: '08:30', value: '08:30' },
+ { label: '09:00', value: '09:00' },
+ { label: '09:30', value: '09:30' },
+ { label: '10:00', value: '10:00' },
+ { label: '10:30', value: '10:30' },
+ { label: '11:00', value: '11:00' },
+ { label: '11:30', value: '11:30' },
+]
diff --git a/packages/constants/src/page.ts b/packages/constants/src/page.ts
new file mode 100644
index 0000000..2a18731
--- /dev/null
+++ b/packages/constants/src/page.ts
@@ -0,0 +1,45 @@
+import { Globe2, Lock, LucideIcon } from 'lucide-react'
+
+// types
+import { TPageFiltersSortBy, TPageFiltersSortKey } from '@prodkt/types'
+
+export enum EPageAccess {
+ PUBLIC = 0,
+ PRIVATE = 1,
+}
+
+export const PAGE_ACCESS_SPECIFIERS: {
+ key: EPageAccess
+ label: string
+ icon: LucideIcon
+}[] = [
+ { key: EPageAccess.PUBLIC, label: 'Public', icon: Globe2 },
+ { key: EPageAccess.PRIVATE, label: 'Private', icon: Lock },
+]
+
+export const PAGE_SORTING_KEY_OPTIONS: {
+ key: TPageFiltersSortKey
+ label: string
+}[] = [
+ { key: 'name', label: 'Name' },
+ { key: 'created_at', label: 'Date created' },
+ { key: 'updated_at', label: 'Date modified' },
+]
+
+export const PAGE_SORT_BY_OPTIONS: {
+ key: TPageFiltersSortBy
+ label: string
+}[] = [
+ { key: 'asc', label: 'Ascending' },
+ { key: 'desc', label: 'Descending' },
+]
+
+export type TCreatePageModal = {
+ isOpen: boolean
+ pageAccess?: EPageAccess
+}
+
+export const DEFAULT_CREATE_PAGE_MODAL_DATA: TCreatePageModal = {
+ isOpen: false,
+ pageAccess: EPageAccess.PUBLIC,
+}
diff --git a/packages/constants/src/profile.ts b/packages/constants/src/profile.ts
new file mode 100644
index 0000000..6165c28
--- /dev/null
+++ b/packages/constants/src/profile.ts
@@ -0,0 +1,78 @@
+import React from 'react'
+
+// icons
+import {
+ Activity,
+ CircleUser,
+ KeyRound,
+ LucideProps,
+ Settings2,
+} from 'lucide-react'
+
+export const PROFILE_ACTION_LINKS: {
+ key: string
+ label: string
+ href: string
+ highlight: (pathname: string) => boolean
+ Icon: React.FC
+}[] = [
+ {
+ key: 'profile',
+ label: 'Profile',
+ href: `/profile`,
+ highlight: (pathname: string) => pathname === '/profile',
+ Icon: CircleUser,
+ },
+ {
+ key: 'change-password',
+ label: 'Change password',
+ href: `/profile/change-password`,
+ highlight: (pathname: string) => pathname === '/profile/change-password',
+ Icon: KeyRound,
+ },
+ {
+ key: 'activity',
+ label: 'Activity',
+ href: `/profile/activity`,
+ highlight: (pathname: string) => pathname === '/profile/activity',
+ Icon: Activity,
+ },
+ {
+ key: 'preferences',
+ label: 'Preferences',
+ href: `/profile/preferences/theme`,
+ highlight: (pathname: string) => pathname.includes('/profile/preferences'),
+ Icon: Settings2,
+ },
+]
+
+export const PROFILE_VIEWER_TAB = [
+ {
+ route: '',
+ label: 'Summary',
+ selected: '/[workspaceSlug]/profile/[userId]',
+ },
+]
+
+export const PROFILE_ADMINS_TAB = [
+ {
+ route: 'assigned',
+ label: 'Assigned',
+ selected: '/[workspaceSlug]/profile/[userId]/assigned',
+ },
+ {
+ route: 'created',
+ label: 'Created',
+ selected: '/[workspaceSlug]/profile/[userId]/created',
+ },
+ {
+ route: 'subscribed',
+ label: 'Subscribed',
+ selected: '/[workspaceSlug]/profile/[userId]/subscribed',
+ },
+ {
+ route: 'activity',
+ label: 'Activity',
+ selected: '/[workspaceSlug]/profile/[userId]/activity',
+ },
+]
diff --git a/packages/constants/src/project.ts b/packages/constants/src/project.ts
new file mode 100644
index 0000000..ed8038b
--- /dev/null
+++ b/packages/constants/src/project.ts
@@ -0,0 +1,183 @@
+// icons
+
+import { Globe2, Lock, LucideIcon } from 'lucide-react'
+
+import {
+ TProjectAppliedDisplayFilterKeys,
+ TProjectOrderByOptions,
+} from '@prodkt/types'
+
+import { SettingIcon } from '@/components/icons/attachment'
+// types
+import { Props } from '@/components/icons/types'
+
+export enum EUserProjectRoles {
+ GUEST = 5,
+ VIEWER = 10,
+ MEMBER = 15,
+ ADMIN = 20,
+}
+
+export const NETWORK_CHOICES: {
+ key: 0 | 2
+ label: string
+ description: string
+ icon: LucideIcon
+}[] = [
+ {
+ key: 0,
+ label: 'Private',
+ description: 'Accessible only by invite',
+ icon: Lock,
+ },
+ {
+ key: 2,
+ label: 'Public',
+ description: 'Anyone in the workspace can join',
+ icon: Globe2,
+ },
+]
+
+export const GROUP_CHOICES = {
+ backlog: 'Backlog',
+ unstarted: 'Unstarted',
+ started: 'Started',
+ completed: 'Completed',
+ cancelled: 'Cancelled',
+}
+
+export const PROJECT_AUTOMATION_MONTHS = [
+ { label: '1 month', value: 1 },
+ { label: '3 months', value: 3 },
+ { label: '6 months', value: 6 },
+ { label: '9 months', value: 9 },
+ { label: '12 months', value: 12 },
+]
+
+export const PROJECT_UNSPLASH_COVERS = [
+ 'https://images.unsplash.com/photo-1531045535792-b515d59c3d1f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80',
+ 'https://images.unsplash.com/photo-1693027407934-e3aa8a54c7ae?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80',
+ 'https://images.unsplash.com/photo-1518837695005-2083093ee35b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80',
+ 'https://images.unsplash.com/photo-1464925257126-6450e871c667?auto=format&fit=crop&q=80&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&w=870&q=80',
+ 'https://images.unsplash.com/photo-1606768666853-403c90a981ad?auto=format&fit=crop&q=80&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&w=870&q=80',
+ 'https://images.unsplash.com/photo-1627556592933-ffe99c1cd9eb?auto=format&fit=crop&q=80&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&w=870&q=80',
+ 'https://images.unsplash.com/photo-1643330683233-ff2ac89b002c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80',
+ 'https://images.unsplash.com/photo-1542202229-7d93c33f5d07?auto=format&fit=crop&q=80&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&w=870&q=80',
+ 'https://images.unsplash.com/photo-1511497584788-876760111969?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80',
+ 'https://images.unsplash.com/photo-1475738972911-5b44ce984c42?auto=format&fit=crop&q=80&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&w=870&q=80',
+ 'https://images.unsplash.com/photo-1418065460487-3e41a6c84dc5?auto=format&fit=crop&q=80&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&w=870&q=80',
+ 'https://images.unsplash.com/photo-1673393058808-50e9baaf4d2c?auto=format&fit=crop&q=80&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&w=870&q=80',
+ 'https://images.unsplash.com/photo-1696643830146-44a8755f1905?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80',
+ 'https://images.unsplash.com/photo-1693868769698-6c7440636a09?auto=format&fit=crop&q=80&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&w=870&q=80',
+ 'https://images.unsplash.com/photo-1691230995681-480d86cbc135?auto=format&fit=crop&q=80&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&w=870&q=80',
+ 'https://images.unsplash.com/photo-1675351066828-6fc770b90dd2?auto=format&fit=crop&q=80&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&w=870&q=80',
+]
+
+export const PROJECT_SETTINGS_LINKS: {
+ key: string
+ label: string
+ href: string
+ access: EUserProjectRoles
+ highlight: (pathname: string, baseUrl: string) => boolean
+ Icon: React.FC
+}[] = [
+ {
+ key: 'general',
+ label: 'General',
+ href: `/settings`,
+ access: EUserProjectRoles.MEMBER,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'members',
+ label: 'Members',
+ href: `/settings/members`,
+ access: EUserProjectRoles.MEMBER,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/members`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'features',
+ label: 'Features',
+ href: `/settings/features`,
+ access: EUserProjectRoles.ADMIN,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/features`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'states',
+ label: 'States',
+ href: `/settings/states`,
+ access: EUserProjectRoles.MEMBER,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/states`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'labels',
+ label: 'Labels',
+ href: `/settings/labels`,
+ access: EUserProjectRoles.MEMBER,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/labels`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'estimates',
+ label: 'Estimates',
+ href: `/settings/estimates`,
+ access: EUserProjectRoles.ADMIN,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/estimates`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'automations',
+ label: 'Automations',
+ href: `/settings/automations`,
+ access: EUserProjectRoles.ADMIN,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/automations`,
+ Icon: SettingIcon,
+ },
+]
+
+export const PROJECT_ORDER_BY_OPTIONS: {
+ key: TProjectOrderByOptions
+ label: string
+}[] = [
+ {
+ key: 'sort_order',
+ label: 'Manual',
+ },
+ {
+ key: 'name',
+ label: 'Name',
+ },
+ {
+ key: 'created_at',
+ label: 'Created date',
+ },
+ {
+ key: 'members_length',
+ label: 'Number of members',
+ },
+]
+
+export const PROJECT_DISPLAY_FILTER_OPTIONS: {
+ key: TProjectAppliedDisplayFilterKeys
+ label: string
+}[] = [
+ {
+ key: 'my_projects',
+ label: 'My projects',
+ },
+ {
+ key: 'archived_projects',
+ label: 'Archived',
+ },
+]
diff --git a/packages/constants/src/seo-variables.ts b/packages/constants/src/seo-variables.ts
new file mode 100644
index 0000000..b6dcbec
--- /dev/null
+++ b/packages/constants/src/seo-variables.ts
@@ -0,0 +1,11 @@
+export const SITE_NAME =
+ 'Prodkt | Simple, extensible, open-source project management tool.'
+export const SITE_TITLE =
+ 'Prodkt | Simple, extensible, open-source project management tool.'
+export const SITE_DESCRIPTION =
+ 'Open-source project management tool to manage issues, sprints, and product roadmaps with peace of mind.'
+export const SITE_KEYWORDS =
+ 'software development, plan, ship, software, accelerate, code management, release management, project management, issue tracking, agile, scrum, kanban, collaboration'
+export const SITE_URL = 'https://app.prodkt.cloud/'
+export const TWITTER_USER_NAME =
+ 'Prodkt | Simple, extensible, open-source project management tool.'
diff --git a/packages/constants/src/spreadsheet.ts b/packages/constants/src/spreadsheet.ts
new file mode 100644
index 0000000..5a9ea0b
--- /dev/null
+++ b/packages/constants/src/spreadsheet.ts
@@ -0,0 +1,210 @@
+import { FC } from 'react'
+
+// icons
+import {
+ CalendarCheck2,
+ CalendarClock,
+ CalendarDays,
+ Link2,
+ Paperclip,
+ Signal,
+ Tag,
+ Triangle,
+ Users,
+} from 'lucide-react'
+
+// types
+import {
+ IIssueDisplayProperties,
+ TIssue,
+ TIssueOrderByOptions,
+} from '@prodkt/types'
+// ui
+import {
+ ContrastIcon,
+ DiceIcon,
+ DoubleCircleIcon,
+ LayersIcon,
+} from '@prodkt/ui/primitives'
+import { ISvgIcons } from '@prodkt/ui/primitives/src/icons/type'
+
+// components
+import {
+ SpreadsheetAssigneeColumn,
+ SpreadsheetAttachmentColumn,
+ SpreadsheetCreatedOnColumn,
+ SpreadsheetCycleColumn,
+ SpreadsheetDueDateColumn,
+ SpreadsheetEstimateColumn,
+ SpreadsheetLabelColumn,
+ SpreadsheetLinkColumn,
+ SpreadsheetModuleColumn,
+ SpreadsheetPriorityColumn,
+ SpreadsheetStartDateColumn,
+ SpreadsheetStateColumn,
+ SpreadsheetSubIssueColumn,
+ SpreadsheetUpdatedOnColumn,
+} from '@/components/issues/issue-layouts/spreadsheet'
+
+export const SPREADSHEET_PROPERTY_DETAILS: {
+ [key: string]: {
+ title: string
+ ascendingOrderKey: TIssueOrderByOptions
+ ascendingOrderTitle: string
+ descendingOrderKey: TIssueOrderByOptions
+ descendingOrderTitle: string
+ icon: FC
+ Column: React.FC<{
+ issue: TIssue
+ onClose: () => void
+ onChange: (issue: TIssue, data: Partial, updates: any) => void
+ disabled: boolean
+ }>
+ }
+} = {
+ assignee: {
+ title: 'Assignees',
+ ascendingOrderKey: 'assignees__first_name',
+ ascendingOrderTitle: 'A',
+ descendingOrderKey: '-assignees__first_name',
+ descendingOrderTitle: 'Z',
+ icon: Users,
+ Column: SpreadsheetAssigneeColumn,
+ },
+ created_on: {
+ title: 'Created on',
+ ascendingOrderKey: '-created_at',
+ ascendingOrderTitle: 'New',
+ descendingOrderKey: 'created_at',
+ descendingOrderTitle: 'Old',
+ icon: CalendarDays,
+ Column: SpreadsheetCreatedOnColumn,
+ },
+ due_date: {
+ title: 'Due date',
+ ascendingOrderKey: '-target_date',
+ ascendingOrderTitle: 'New',
+ descendingOrderKey: 'target_date',
+ descendingOrderTitle: 'Old',
+ icon: CalendarCheck2,
+ Column: SpreadsheetDueDateColumn,
+ },
+ estimate: {
+ title: 'Estimate',
+ ascendingOrderKey: 'estimate_point',
+ ascendingOrderTitle: 'Low',
+ descendingOrderKey: '-estimate_point',
+ descendingOrderTitle: 'High',
+ icon: Triangle,
+ Column: SpreadsheetEstimateColumn,
+ },
+ labels: {
+ title: 'Labels',
+ ascendingOrderKey: 'labels__name',
+ ascendingOrderTitle: 'A',
+ descendingOrderKey: '-labels__name',
+ descendingOrderTitle: 'Z',
+ icon: Tag,
+ Column: SpreadsheetLabelColumn,
+ },
+ modules: {
+ title: 'Modules',
+ ascendingOrderKey: 'modules__name',
+ ascendingOrderTitle: 'A',
+ descendingOrderKey: '-modules__name',
+ descendingOrderTitle: 'Z',
+ icon: DiceIcon,
+ Column: SpreadsheetModuleColumn,
+ },
+ cycle: {
+ title: 'Cycle',
+ ascendingOrderKey: 'cycle__name',
+ ascendingOrderTitle: 'A',
+ descendingOrderKey: '-cycle__name',
+ descendingOrderTitle: 'Z',
+ icon: ContrastIcon,
+ Column: SpreadsheetCycleColumn,
+ },
+ priority: {
+ title: 'Priority',
+ ascendingOrderKey: 'priority',
+ ascendingOrderTitle: 'None',
+ descendingOrderKey: '-priority',
+ descendingOrderTitle: 'Urgent',
+ icon: Signal,
+ Column: SpreadsheetPriorityColumn,
+ },
+ start_date: {
+ title: 'Start date',
+ ascendingOrderKey: '-start_date',
+ ascendingOrderTitle: 'New',
+ descendingOrderKey: 'start_date',
+ descendingOrderTitle: 'Old',
+ icon: CalendarClock,
+ Column: SpreadsheetStartDateColumn,
+ },
+ state: {
+ title: 'State',
+ ascendingOrderKey: 'state__name',
+ ascendingOrderTitle: 'A',
+ descendingOrderKey: '-state__name',
+ descendingOrderTitle: 'Z',
+ icon: DoubleCircleIcon,
+ Column: SpreadsheetStateColumn,
+ },
+ updated_on: {
+ title: 'Updated on',
+ ascendingOrderKey: '-updated_at',
+ ascendingOrderTitle: 'New',
+ descendingOrderKey: 'updated_at',
+ descendingOrderTitle: 'Old',
+ icon: CalendarDays,
+ Column: SpreadsheetUpdatedOnColumn,
+ },
+ link: {
+ title: 'Link',
+ ascendingOrderKey: '-link_count',
+ ascendingOrderTitle: 'Most',
+ descendingOrderKey: 'link_count',
+ descendingOrderTitle: 'Least',
+ icon: Link2,
+ Column: SpreadsheetLinkColumn,
+ },
+ attachment_count: {
+ title: 'Attachment',
+ ascendingOrderKey: '-attachment_count',
+ ascendingOrderTitle: 'Most',
+ descendingOrderKey: 'attachment_count',
+ descendingOrderTitle: 'Least',
+ icon: Paperclip,
+ Column: SpreadsheetAttachmentColumn,
+ },
+ sub_issue_count: {
+ title: 'Sub-issue',
+ ascendingOrderKey: '-sub_issues_count',
+ ascendingOrderTitle: 'Most',
+ descendingOrderKey: 'sub_issues_count',
+ descendingOrderTitle: 'Least',
+ icon: LayersIcon,
+ Column: SpreadsheetSubIssueColumn,
+ },
+}
+
+export const SPREADSHEET_PROPERTY_LIST: (keyof IIssueDisplayProperties)[] = [
+ 'state',
+ 'priority',
+ 'assignee',
+ 'labels',
+ 'modules',
+ 'cycle',
+ 'start_date',
+ 'due_date',
+ 'estimate',
+ 'created_on',
+ 'updated_on',
+ 'link',
+ 'attachment_count',
+ 'sub_issue_count',
+]
+
+export const SPREADSHEET_SELECT_GROUP = 'spreadsheet-issues'
diff --git a/packages/constants/src/state.ts b/packages/constants/src/state.ts
new file mode 100644
index 0000000..5074659
--- /dev/null
+++ b/packages/constants/src/state.ts
@@ -0,0 +1,40 @@
+import { TStateGroups } from '@prodkt/types'
+
+export const STATE_GROUPS: {
+ [key in TStateGroups]: {
+ key: TStateGroups
+ label: string
+ color: string
+ }
+} = {
+ backlog: {
+ key: 'backlog',
+ label: 'Backlog',
+ color: '#d9d9d9',
+ },
+ unstarted: {
+ key: 'unstarted',
+ label: 'Unstarted',
+ color: '#3f76ff',
+ },
+ started: {
+ key: 'started',
+ label: 'Started',
+ color: '#f59e0b',
+ },
+ completed: {
+ key: 'completed',
+ label: 'Completed',
+ color: '#16a34a',
+ },
+ cancelled: {
+ key: 'cancelled',
+ label: 'Canceled',
+ color: '#dc2626',
+ },
+}
+
+export const ARCHIVABLE_STATE_GROUPS = [
+ STATE_GROUPS.completed.key,
+ STATE_GROUPS.cancelled.key,
+]
diff --git a/packages/constants/src/swr-config.ts b/packages/constants/src/swr-config.ts
new file mode 100644
index 0000000..777f05e
--- /dev/null
+++ b/packages/constants/src/swr-config.ts
@@ -0,0 +1,8 @@
+export const SWR_CONFIG = {
+ refreshWhenHidden: false,
+ revalidateIfStale: true,
+ revalidateOnFocus: true,
+ revalidateOnMount: true,
+ refreshInterval: 600000,
+ errorRetryCount: 3,
+}
diff --git a/packages/constants/src/themes.ts b/packages/constants/src/themes.ts
new file mode 100644
index 0000000..dcbf286
--- /dev/null
+++ b/packages/constants/src/themes.ts
@@ -0,0 +1,81 @@
+export const THEMES = [
+ 'light',
+ 'dark',
+ 'light-contrast',
+ 'dark-contrast',
+ 'custom',
+]
+
+export interface I_THEME_OPTION {
+ value: string
+ label: string
+ type: string
+ icon: {
+ border: string
+ color1: string
+ color2: string
+ }
+}
+
+export const THEME_OPTIONS: I_THEME_OPTION[] = [
+ {
+ value: 'system',
+ label: 'System Preference',
+ type: 'light',
+ icon: {
+ border: '#DEE2E6',
+ color1: '#FAFAFA',
+ color2: '#3F76FF',
+ },
+ },
+ {
+ value: 'light',
+ label: 'Light',
+ type: 'light',
+ icon: {
+ border: '#DEE2E6',
+ color1: '#FAFAFA',
+ color2: '#3F76FF',
+ },
+ },
+ {
+ value: 'dark',
+ label: 'Dark',
+ type: 'dark',
+ icon: {
+ border: '#2E3234',
+ color1: '#191B1B',
+ color2: '#3C85D9',
+ },
+ },
+ {
+ value: 'light-contrast',
+ label: 'Light High Contrast',
+ type: 'light',
+ icon: {
+ border: '#000000',
+ color1: '#FFFFFF',
+ color2: '#3F76FF',
+ },
+ },
+ {
+ value: 'dark-contrast',
+ label: 'Dark High Contrast',
+ type: 'dark',
+ icon: {
+ border: '#FFFFFF',
+ color1: '#030303',
+ color2: '#3A8BE9',
+ },
+ },
+ {
+ value: 'custom',
+ label: 'Custom Theming',
+ type: 'light',
+ icon: {
+ border: '#FFC9C9',
+ color1: '#FFF7F7',
+ color2: '#FF5151',
+ },
+ },
+]
diff --git a/packages/constants/src/timezones.ts b/packages/constants/src/timezones.ts
new file mode 100644
index 0000000..d8c8271
--- /dev/null
+++ b/packages/constants/src/timezones.ts
@@ -0,0 +1,2386 @@
+export const TIME_ZONES = [
+ {
+ label: 'Africa/Abidjan, GMT',
+ value: 'Africa/Abidjan',
+ },
+ {
+ label: 'Africa/Accra, GMT',
+ value: 'Africa/Accra',
+ },
+ {
+ label: 'Africa/Addis_Ababa, GMT+03:00',
+ value: 'Africa/Addis_Ababa',
+ },
+ {
+ label: 'Africa/Algiers, GMT+01:00',
+ value: 'Africa/Algiers',
+ },
+ {
+ label: 'Africa/Asmara, GMT+03:00',
+ value: 'Africa/Asmara',
+ },
+ {
+ label: 'Africa/Asmera, GMT+03:00',
+ value: 'Africa/Asmera',
+ },
+ {
+ label: 'Africa/Bamako, GMT',
+ value: 'Africa/Bamako',
+ },
+ {
+ label: 'Africa/Bangui, GMT+01:00',
+ value: 'Africa/Bangui',
+ },
+ {
+ label: 'Africa/Banjul, GMT',
+ value: 'Africa/Banjul',
+ },
+ {
+ label: 'Africa/Bissau, GMT',
+ value: 'Africa/Bissau',
+ },
+ {
+ label: 'Africa/Blantyre, GMT+02:00',
+ value: 'Africa/Blantyre',
+ },
+ {
+ label: 'Africa/Brazzaville, GMT+01:00',
+ value: 'Africa/Brazzaville',
+ },
+ {
+ label: 'Africa/Bujumbura, GMT+02:00',
+ value: 'Africa/Bujumbura',
+ },
+ {
+ label: 'Africa/Cairo, GMT+03:00',
+ value: 'Africa/Cairo',
+ },
+ {
+ label: 'Africa/Casablanca, GMT+01:00',
+ value: 'Africa/Casablanca',
+ },
+ {
+ label: 'Africa/Ceuta, GMT+02:00',
+ value: 'Africa/Ceuta',
+ },
+ {
+ label: 'Africa/Conakry, GMT',
+ value: 'Africa/Conakry',
+ },
+ {
+ label: 'Africa/Dakar, GMT',
+ value: 'Africa/Dakar',
+ },
+ {
+ label: 'Africa/Dar_es_Salaam, GMT+03:00',
+ value: 'Africa/Dar_es_Salaam',
+ },
+ {
+ label: 'Africa/Djibouti, GMT+03:00',
+ value: 'Africa/Djibouti',
+ },
+ {
+ label: 'Africa/Douala, GMT+01:00',
+ value: 'Africa/Douala',
+ },
+ {
+ label: 'Africa/El_Aaiun, GMT+01:00',
+ value: 'Africa/El_Aaiun',
+ },
+ {
+ label: 'Africa/Freetown, GMT',
+ value: 'Africa/Freetown',
+ },
+ {
+ label: 'Africa/Gaborone, GMT+02:00',
+ value: 'Africa/Gaborone',
+ },
+ {
+ label: 'Africa/Harare, GMT+02:00',
+ value: 'Africa/Harare',
+ },
+ {
+ label: 'Africa/Johannesburg, GMT+02:00',
+ value: 'Africa/Johannesburg',
+ },
+ {
+ label: 'Africa/Juba, GMT+02:00',
+ value: 'Africa/Juba',
+ },
+ {
+ label: 'Africa/Kampala, GMT+03:00',
+ value: 'Africa/Kampala',
+ },
+ {
+ label: 'Africa/Khartoum, GMT+02:00',
+ value: 'Africa/Khartoum',
+ },
+ {
+ label: 'Africa/Kigali, GMT+02:00',
+ value: 'Africa/Kigali',
+ },
+ {
+ label: 'Africa/Kinshasa, GMT+01:00',
+ value: 'Africa/Kinshasa',
+ },
+ {
+ label: 'Africa/Lagos, GMT+01:00',
+ value: 'Africa/Lagos',
+ },
+ {
+ label: 'Africa/Libreville, GMT+01:00',
+ value: 'Africa/Libreville',
+ },
+ {
+ label: 'Africa/Lome, GMT',
+ value: 'Africa/Lome',
+ },
+ {
+ label: 'Africa/Luanda, GMT+01:00',
+ value: 'Africa/Luanda',
+ },
+ {
+ label: 'Africa/Lubumbashi, GMT+02:00',
+ value: 'Africa/Lubumbashi',
+ },
+ {
+ label: 'Africa/Lusaka, GMT+02:00',
+ value: 'Africa/Lusaka',
+ },
+ {
+ label: 'Africa/Malabo, GMT+01:00',
+ value: 'Africa/Malabo',
+ },
+ {
+ label: 'Africa/Maputo, GMT+02:00',
+ value: 'Africa/Maputo',
+ },
+ {
+ label: 'Africa/Maseru, GMT+02:00',
+ value: 'Africa/Maseru',
+ },
+ {
+ label: 'Africa/Mbabane, GMT+02:00',
+ value: 'Africa/Mbabane',
+ },
+ {
+ label: 'Africa/Mogadishu, GMT+03:00',
+ value: 'Africa/Mogadishu',
+ },
+ {
+ label: 'Africa/Monrovia, GMT',
+ value: 'Africa/Monrovia',
+ },
+ {
+ label: 'Africa/Nairobi, GMT+03:00',
+ value: 'Africa/Nairobi',
+ },
+ {
+ label: 'Africa/Ndjamena, GMT+01:00',
+ value: 'Africa/Ndjamena',
+ },
+ {
+ label: 'Africa/Niamey, GMT+01:00',
+ value: 'Africa/Niamey',
+ },
+ {
+ label: 'Africa/Nouakchott, GMT',
+ value: 'Africa/Nouakchott',
+ },
+ {
+ label: 'Africa/Ouagadougou, GMT',
+ value: 'Africa/Ouagadougou',
+ },
+ {
+ label: 'Africa/Porto-Novo, GMT+01:00',
+ value: 'Africa/Porto-Novo',
+ },
+ {
+ label: 'Africa/Sao_Tome, GMT',
+ value: 'Africa/Sao_Tome',
+ },
+ {
+ label: 'Africa/Timbuktu, GMT',
+ value: 'Africa/Timbuktu',
+ },
+ {
+ label: 'Africa/Tripoli, GMT+02:00',
+ value: 'Africa/Tripoli',
+ },
+ {
+ label: 'Africa/Tunis, GMT+01:00',
+ value: 'Africa/Tunis',
+ },
+ {
+ label: 'Africa/Windhoek, GMT+02:00',
+ value: 'Africa/Windhoek',
+ },
+ {
+ label: 'America/Adak, GMT-09:00',
+ value: 'America/Adak',
+ },
+ {
+ label: 'America/Anchorage, GMT-08:00',
+ value: 'America/Anchorage',
+ },
+ {
+ label: 'America/Anguilla, GMT-04:00',
+ value: 'America/Anguilla',
+ },
+ {
+ label: 'America/Antigua, GMT-04:00',
+ value: 'America/Antigua',
+ },
+ {
+ label: 'America/Araguaina, GMT-03:00',
+ value: 'America/Araguaina',
+ },
+ {
+ label: 'America/Argentina/Buenos_Aires, GMT-03:00',
+ value: 'America/Argentina/Buenos_Aires',
+ },
+ {
+ label: 'America/Argentina/Catamarca, GMT-03:00',
+ value: 'America/Argentina/Catamarca',
+ },
+ {
+ label: 'America/Argentina/ComodRivadavia, GMT-03:00',
+ value: 'America/Argentina/ComodRivadavia',
+ },
+ {
+ label: 'America/Argentina/Cordoba, GMT-03:00',
+ value: 'America/Argentina/Cordoba',
+ },
+ {
+ label: 'America/Argentina/Jujuy, GMT-03:00',
+ value: 'America/Argentina/Jujuy',
+ },
+ {
+ label: 'America/Argentina/La_Rioja, GMT-03:00',
+ value: 'America/Argentina/La_Rioja',
+ },
+ {
+ label: 'America/Argentina/Mendoza, GMT-03:00',
+ value: 'America/Argentina/Mendoza',
+ },
+ {
+ label: 'America/Argentina/Rio_Gallegos, GMT-03:00',
+ value: 'America/Argentina/Rio_Gallegos',
+ },
+ {
+ label: 'America/Argentina/Salta, GMT-03:00',
+ value: 'America/Argentina/Salta',
+ },
+ {
+ label: 'America/Argentina/San_Juan, GMT-03:00',
+ value: 'America/Argentina/San_Juan',
+ },
+ {
+ label: 'America/Argentina/San_Luis, GMT-03:00',
+ value: 'America/Argentina/San_Luis',
+ },
+ {
+ label: 'America/Argentina/Tucuman, GMT-03:00',
+ value: 'America/Argentina/Tucuman',
+ },
+ {
+ label: 'America/Argentina/Ushuaia, GMT-03:00',
+ value: 'America/Argentina/Ushuaia',
+ },
+ {
+ label: 'America/Aruba, GMT-04:00',
+ value: 'America/Aruba',
+ },
+ {
+ label: 'America/Asuncion, GMT-04:00',
+ value: 'America/Asuncion',
+ },
+ {
+ label: 'America/Atikokan, GMT-05:00',
+ value: 'America/Atikokan',
+ },
+ {
+ label: 'America/Atka, GMT-09:00',
+ value: 'America/Atka',
+ },
+ {
+ label: 'America/Bahia, GMT-03:00',
+ value: 'America/Bahia',
+ },
+ {
+ label: 'America/Bahia_Banderas, GMT-06:00',
+ value: 'America/Bahia_Banderas',
+ },
+ {
+ label: 'America/Barbados, GMT-04:00',
+ value: 'America/Barbados',
+ },
+ {
+ label: 'America/Belem, GMT-03:00',
+ value: 'America/Belem',
+ },
+ {
+ label: 'America/Belize, GMT-06:00',
+ value: 'America/Belize',
+ },
+ {
+ label: 'America/Blanc-Sablon, GMT-04:00',
+ value: 'America/Blanc-Sablon',
+ },
+ {
+ label: 'America/Boa_Vista, GMT-04:00',
+ value: 'America/Boa_Vista',
+ },
+ {
+ label: 'America/Bogota, GMT-05:00',
+ value: 'America/Bogota',
+ },
+ {
+ label: 'America/Boise, GMT-06:00',
+ value: 'America/Boise',
+ },
+ {
+ label: 'America/Buenos_Aires, GMT-03:00',
+ value: 'America/Buenos_Aires',
+ },
+ {
+ label: 'America/Cambridge_Bay, GMT-06:00',
+ value: 'America/Cambridge_Bay',
+ },
+ {
+ label: 'America/Campo_Grande, GMT-04:00',
+ value: 'America/Campo_Grande',
+ },
+ {
+ label: 'America/Cancun, GMT-05:00',
+ value: 'America/Cancun',
+ },
+ {
+ label: 'America/Caracas, GMT-04:00',
+ value: 'America/Caracas',
+ },
+ {
+ label: 'America/Catamarca, GMT-03:00',
+ value: 'America/Catamarca',
+ },
+ {
+ label: 'America/Cayenne, GMT-03:00',
+ value: 'America/Cayenne',
+ },
+ {
+ label: 'America/Cayman, GMT-05:00',
+ value: 'America/Cayman',
+ },
+ {
+ label: 'America/Chicago, GMT-05:00',
+ value: 'America/Chicago',
+ },
+ {
+ label: 'America/Chihuahua, GMT-06:00',
+ value: 'America/Chihuahua',
+ },
+ {
+ label: 'America/Ciudad_Juarez, GMT-06:00',
+ value: 'America/Ciudad_Juarez',
+ },
+ {
+ label: 'America/Coral_Harbour, GMT-05:00',
+ value: 'America/Coral_Harbour',
+ },
+ {
+ label: 'America/Cordoba, GMT-03:00',
+ value: 'America/Cordoba',
+ },
+ {
+ label: 'America/Costa_Rica, GMT-06:00',
+ value: 'America/Costa_Rica',
+ },
+ {
+ label: 'America/Creston, GMT-07:00',
+ value: 'America/Creston',
+ },
+ {
+ label: 'America/Cuiaba, GMT-04:00',
+ value: 'America/Cuiaba',
+ },
+ {
+ label: 'America/Curacao, GMT-04:00',
+ value: 'America/Curacao',
+ },
+ {
+ label: 'America/Danmarkshavn, GMT',
+ value: 'America/Danmarkshavn',
+ },
+ {
+ label: 'America/Dawson, GMT-07:00',
+ value: 'America/Dawson',
+ },
+ {
+ label: 'America/Dawson_Creek, GMT-07:00',
+ value: 'America/Dawson_Creek',
+ },
+ {
+ label: 'America/Denver, GMT-06:00',
+ value: 'America/Denver',
+ },
+ {
+ label: 'America/Detroit, GMT-04:00',
+ value: 'America/Detroit',
+ },
+ {
+ label: 'America/Dominica, GMT-04:00',
+ value: 'America/Dominica',
+ },
+ {
+ label: 'America/Edmonton, GMT-06:00',
+ value: 'America/Edmonton',
+ },
+ {
+ label: 'America/Eirunepe, GMT-05:00',
+ value: 'America/Eirunepe',
+ },
+ {
+ label: 'America/El_Salvador, GMT-06:00',
+ value: 'America/El_Salvador',
+ },
+ {
+ label: 'America/Ensenada, GMT-07:00',
+ value: 'America/Ensenada',
+ },
+ {
+ label: 'America/Fort_Nelson, GMT-07:00',
+ value: 'America/Fort_Nelson',
+ },
+ {
+ label: 'America/Fort_Wayne, GMT-04:00',
+ value: 'America/Fort_Wayne',
+ },
+ {
+ label: 'America/Fortaleza, GMT-03:00',
+ value: 'America/Fortaleza',
+ },
+ {
+ label: 'America/Glace_Bay, GMT-03:00',
+ value: 'America/Glace_Bay',
+ },
+ {
+ label: 'America/Godthab, GMT-02:00',
+ value: 'America/Godthab',
+ },
+ {
+ label: 'America/Goose_Bay, GMT-03:00',
+ value: 'America/Goose_Bay',
+ },
+ {
+ label: 'America/Grand_Turk, GMT-04:00',
+ value: 'America/Grand_Turk',
+ },
+ {
+ label: 'America/Grenada, GMT-04:00',
+ value: 'America/Grenada',
+ },
+ {
+ label: 'America/Guadeloupe, GMT-04:00',
+ value: 'America/Guadeloupe',
+ },
+ {
+ label: 'America/Guatemala, GMT-06:00',
+ value: 'America/Guatemala',
+ },
+ {
+ label: 'America/Guayaquil, GMT-05:00',
+ value: 'America/Guayaquil',
+ },
+ {
+ label: 'America/Guyana, GMT-04:00',
+ value: 'America/Guyana',
+ },
+ {
+ label: 'America/Halifax, GMT-03:00',
+ value: 'America/Halifax',
+ },
+ {
+ label: 'America/Havana, GMT-04:00',
+ value: 'America/Havana',
+ },
+ {
+ label: 'America/Hermosillo, GMT-07:00',
+ value: 'America/Hermosillo',
+ },
+ {
+ label: 'America/Indiana/Indianapolis, GMT-04:00',
+ value: 'America/Indiana/Indianapolis',
+ },
+ {
+ label: 'America/Indiana/Knox, GMT-05:00',
+ value: 'America/Indiana/Knox',
+ },
+ {
+ label: 'America/Indiana/Marengo, GMT-04:00',
+ value: 'America/Indiana/Marengo',
+ },
+ {
+ label: 'America/Indiana/Petersburg, GMT-04:00',
+ value: 'America/Indiana/Petersburg',
+ },
+ {
+ label: 'America/Indiana/Tell_City, GMT-05:00',
+ value: 'America/Indiana/Tell_City',
+ },
+ {
+ label: 'America/Indiana/Vevay, GMT-04:00',
+ value: 'America/Indiana/Vevay',
+ },
+ {
+ label: 'America/Indiana/Vincennes, GMT-04:00',
+ value: 'America/Indiana/Vincennes',
+ },
+ {
+ label: 'America/Indiana/Winamac, GMT-04:00',
+ value: 'America/Indiana/Winamac',
+ },
+ {
+ label: 'America/Indianapolis, GMT-04:00',
+ value: 'America/Indianapolis',
+ },
+ {
+ label: 'America/Inuvik, GMT-06:00',
+ value: 'America/Inuvik',
+ },
+ {
+ label: 'America/Iqaluit, GMT-04:00',
+ value: 'America/Iqaluit',
+ },
+ {
+ label: 'America/Jamaica, GMT-05:00',
+ value: 'America/Jamaica',
+ },
+ {
+ label: 'America/Jujuy, GMT-03:00',
+ value: 'America/Jujuy',
+ },
+ {
+ label: 'America/Juneau, GMT-08:00',
+ value: 'America/Juneau',
+ },
+ {
+ label: 'America/Kentucky/Louisville, GMT-04:00',
+ value: 'America/Kentucky/Louisville',
+ },
+ {
+ label: 'America/Kentucky/Monticello, GMT-04:00',
+ value: 'America/Kentucky/Monticello',
+ },
+ {
+ label: 'America/Knox_IN, GMT-05:00',
+ value: 'America/Knox_IN',
+ },
+ {
+ label: 'America/Kralendijk, GMT-04:00',
+ value: 'America/Kralendijk',
+ },
+ {
+ label: 'America/La_Paz, GMT-04:00',
+ value: 'America/La_Paz',
+ },
+ {
+ label: 'America/Lima, GMT-05:00',
+ value: 'America/Lima',
+ },
+ {
+ label: 'America/Los_Angeles, GMT-07:00',
+ value: 'America/Los_Angeles',
+ },
+ {
+ label: 'America/Louisville, GMT-04:00',
+ value: 'America/Louisville',
+ },
+ {
+ label: 'America/Lower_Princes, GMT-04:00',
+ value: 'America/Lower_Princes',
+ },
+ {
+ label: 'America/Maceio, GMT-03:00',
+ value: 'America/Maceio',
+ },
+ {
+ label: 'America/Managua, GMT-06:00',
+ value: 'America/Managua',
+ },
+ {
+ label: 'America/Manaus, GMT-04:00',
+ value: 'America/Manaus',
+ },
+ {
+ label: 'America/Marigot, GMT-04:00',
+ value: 'America/Marigot',
+ },
+ {
+ label: 'America/Martinique, GMT-04:00',
+ value: 'America/Martinique',
+ },
+ {
+ label: 'America/Matamoros, GMT-05:00',
+ value: 'America/Matamoros',
+ },
+ {
+ label: 'America/Mazatlan, GMT-07:00',
+ value: 'America/Mazatlan',
+ },
+ {
+ label: 'America/Mendoza, GMT-03:00',
+ value: 'America/Mendoza',
+ },
+ {
+ label: 'America/Menominee, GMT-05:00',
+ value: 'America/Menominee',
+ },
+ {
+ label: 'America/Merida, GMT-06:00',
+ value: 'America/Merida',
+ },
+ {
+ label: 'America/Metlakatla, GMT-08:00',
+ value: 'America/Metlakatla',
+ },
+ {
+ label: 'America/Mexico_City, GMT-06:00',
+ value: 'America/Mexico_City',
+ },
+ {
+ label: 'America/Miquelon, GMT-02:00',
+ value: 'America/Miquelon',
+ },
+ {
+ label: 'America/Moncton, GMT-03:00',
+ value: 'America/Moncton',
+ },
+ {
+ label: 'America/Monterrey, GMT-06:00',
+ value: 'America/Monterrey',
+ },
+ {
+ label: 'America/Montevideo, GMT-03:00',
+ value: 'America/Montevideo',
+ },
+ {
+ label: 'America/Montreal, GMT-04:00',
+ value: 'America/Montreal',
+ },
+ {
+ label: 'America/Montserrat, GMT-04:00',
+ value: 'America/Montserrat',
+ },
+ {
+ label: 'America/Nassau, GMT-04:00',
+ value: 'America/Nassau',
+ },
+ {
+ label: 'America/New_York, GMT-04:00',
+ value: 'America/New_York',
+ },
+ {
+ label: 'America/Nipigon, GMT-04:00',
+ value: 'America/Nipigon',
+ },
+ {
+ label: 'America/Nome, GMT-08:00',
+ value: 'America/Nome',
+ },
+ {
+ label: 'America/Noronha, GMT-02:00',
+ value: 'America/Noronha',
+ },
+ {
+ label: 'America/North_Dakota/Beulah, GMT-05:00',
+ value: 'America/North_Dakota/Beulah',
+ },
+ {
+ label: 'America/North_Dakota/Center, GMT-05:00',
+ value: 'America/North_Dakota/Center',
+ },
+ {
+ label: 'America/North_Dakota/New_Salem, GMT-05:00',
+ value: 'America/North_Dakota/New_Salem',
+ },
+ {
+ label: 'America/Nuuk, GMT-02:00',
+ value: 'America/Nuuk',
+ },
+ {
+ label: 'America/Ojinaga, GMT-05:00',
+ value: 'America/Ojinaga',
+ },
+ {
+ label: 'America/Panama, GMT-05:00',
+ value: 'America/Panama',
+ },
+ {
+ label: 'America/Pangnirtung, GMT-04:00',
+ value: 'America/Pangnirtung',
+ },
+ {
+ label: 'America/Paramaribo, GMT-03:00',
+ value: 'America/Paramaribo',
+ },
+ {
+ label: 'America/Phoenix, GMT-07:00',
+ value: 'America/Phoenix',
+ },
+ {
+ label: 'America/Port-au-Prince, GMT-04:00',
+ value: 'America/Port-au-Prince',
+ },
+ {
+ label: 'America/Port_of_Spain, GMT-04:00',
+ value: 'America/Port_of_Spain',
+ },
+ {
+ label: 'America/Porto_Acre, GMT-05:00',
+ value: 'America/Porto_Acre',
+ },
+ {
+ label: 'America/Porto_Velho, GMT-04:00',
+ value: 'America/Porto_Velho',
+ },
+ {
+ label: 'America/Puerto_Rico, GMT-04:00',
+ value: 'America/Puerto_Rico',
+ },
+ {
+ label: 'America/Punta_Arenas, GMT-03:00',
+ value: 'America/Punta_Arenas',
+ },
+ {
+ label: 'America/Rainy_River, GMT-05:00',
+ value: 'America/Rainy_River',
+ },
+ {
+ label: 'America/Rankin_Inlet, GMT-05:00',
+ value: 'America/Rankin_Inlet',
+ },
+ {
+ label: 'America/Recife, GMT-03:00',
+ value: 'America/Recife',
+ },
+ {
+ label: 'America/Regina, GMT-06:00',
+ value: 'America/Regina',
+ },
+ {
+ label: 'America/Resolute, GMT-05:00',
+ value: 'America/Resolute',
+ },
+ {
+ label: 'America/Rio_Branco, GMT-05:00',
+ value: 'America/Rio_Branco',
+ },
+ {
+ label: 'America/Rosario, GMT-03:00',
+ value: 'America/Rosario',
+ },
+ {
+ label: 'America/Santa_Isabel, GMT-07:00',
+ value: 'America/Santa_Isabel',
+ },
+ {
+ label: 'America/Santarem, GMT-03:00',
+ value: 'America/Santarem',
+ },
+ {
+ label: 'America/Santiago, GMT-04:00',
+ value: 'America/Santiago',
+ },
+ {
+ label: 'America/Santo_Domingo, GMT-04:00',
+ value: 'America/Santo_Domingo',
+ },
+ {
+ label: 'America/Sao_Paulo, GMT-03:00',
+ value: 'America/Sao_Paulo',
+ },
+ {
+ label: 'America/Scoresbysund, GMT',
+ value: 'America/Scoresbysund',
+ },
+ {
+ label: 'America/Shiprock, GMT-06:00',
+ value: 'America/Shiprock',
+ },
+ {
+ label: 'America/Sitka, GMT-08:00',
+ value: 'America/Sitka',
+ },
+ {
+ label: 'America/St_Barthelemy, GMT-04:00',
+ value: 'America/St_Barthelemy',
+ },
+ {
+ label: 'America/St_Johns, GMT-02:30',
+ value: 'America/St_Johns',
+ },
+ {
+ label: 'America/St_Kitts, GMT-04:00',
+ value: 'America/St_Kitts',
+ },
+ {
+ label: 'America/St_Lucia, GMT-04:00',
+ value: 'America/St_Lucia',
+ },
+ {
+ label: 'America/St_Thomas, GMT-04:00',
+ value: 'America/St_Thomas',
+ },
+ {
+ label: 'America/St_Vincent, GMT-04:00',
+ value: 'America/St_Vincent',
+ },
+ {
+ label: 'America/Swift_Current, GMT-06:00',
+ value: 'America/Swift_Current',
+ },
+ {
+ label: 'America/Tegucigalpa, GMT-06:00',
+ value: 'America/Tegucigalpa',
+ },
+ {
+ label: 'America/Thule, GMT-03:00',
+ value: 'America/Thule',
+ },
+ {
+ label: 'America/Thunder_Bay, GMT-04:00',
+ value: 'America/Thunder_Bay',
+ },
+ {
+ label: 'America/Tijuana, GMT-07:00',
+ value: 'America/Tijuana',
+ },
+ {
+ label: 'America/Toronto, GMT-04:00',
+ value: 'America/Toronto',
+ },
+ {
+ label: 'America/Tortola, GMT-04:00',
+ value: 'America/Tortola',
+ },
+ {
+ label: 'America/Vancouver, GMT-07:00',
+ value: 'America/Vancouver',
+ },
+ {
+ label: 'America/Virgin, GMT-04:00',
+ value: 'America/Virgin',
+ },
+ {
+ label: 'America/Whitehorse, GMT-07:00',
+ value: 'America/Whitehorse',
+ },
+ {
+ label: 'America/Winnipeg, GMT-05:00',
+ value: 'America/Winnipeg',
+ },
+ {
+ label: 'America/Yakutat, GMT-08:00',
+ value: 'America/Yakutat',
+ },
+ {
+ label: 'America/Yellowknife, GMT-06:00',
+ value: 'America/Yellowknife',
+ },
+ {
+ label: 'Antarctica/Casey, GMT+11:00',
+ value: 'Antarctica/Casey',
+ },
+ {
+ label: 'Antarctica/Davis, GMT+07:00',
+ value: 'Antarctica/Davis',
+ },
+ {
+ label: 'Antarctica/DumontDUrville, GMT+10:00',
+ value: 'Antarctica/DumontDUrville',
+ },
+ {
+ label: 'Antarctica/Macquarie, GMT+10:00',
+ value: 'Antarctica/Macquarie',
+ },
+ {
+ label: 'Antarctica/Mawson, GMT+05:00',
+ value: 'Antarctica/Mawson',
+ },
+ {
+ label: 'Antarctica/McMurdo, GMT+12:00',
+ value: 'Antarctica/McMurdo',
+ },
+ {
+ label: 'Antarctica/Palmer, GMT-03:00',
+ value: 'Antarctica/Palmer',
+ },
+ {
+ label: 'Antarctica/Rothera, GMT-03:00',
+ value: 'Antarctica/Rothera',
+ },
+ {
+ label: 'Antarctica/South_Pole, GMT+12:00',
+ value: 'Antarctica/South_Pole',
+ },
+ {
+ label: 'Antarctica/Syowa, GMT+03:00',
+ value: 'Antarctica/Syowa',
+ },
+ {
+ label: 'Antarctica/Troll, GMT+02:00',
+ value: 'Antarctica/Troll',
+ },
+ {
+ label: 'Antarctica/Vostok, GMT+06:00',
+ value: 'Antarctica/Vostok',
+ },
+ {
+ label: 'Arctic/Longyearbyen, GMT+02:00',
+ value: 'Arctic/Longyearbyen',
+ },
+ {
+ label: 'Asia/Aden, GMT+03:00',
+ value: 'Asia/Aden',
+ },
+ {
+ label: 'Asia/Almaty, GMT+06:00',
+ value: 'Asia/Almaty',
+ },
+ {
+ label: 'Asia/Amman, GMT+03:00',
+ value: 'Asia/Amman',
+ },
+ {
+ label: 'Asia/Anadyr, GMT+12:00',
+ value: 'Asia/Anadyr',
+ },
+ {
+ label: 'Asia/Aqtau, GMT+05:00',
+ value: 'Asia/Aqtau',
+ },
+ {
+ label: 'Asia/Aqtobe, GMT+05:00',
+ value: 'Asia/Aqtobe',
+ },
+ {
+ label: 'Asia/Ashgabat, GMT+05:00',
+ value: 'Asia/Ashgabat',
+ },
+ {
+ label: 'Asia/Ashkhabad, GMT+05:00',
+ value: 'Asia/Ashkhabad',
+ },
+ {
+ label: 'Asia/Atyrau, GMT+05:00',
+ value: 'Asia/Atyrau',
+ },
+ {
+ label: 'Asia/Baghdad, GMT+03:00',
+ value: 'Asia/Baghdad',
+ },
+ {
+ label: 'Asia/Bahrain, GMT+03:00',
+ value: 'Asia/Bahrain',
+ },
+ {
+ label: 'Asia/Baku, GMT+04:00',
+ value: 'Asia/Baku',
+ },
+ {
+ label: 'Asia/Bangkok, GMT+07:00',
+ value: 'Asia/Bangkok',
+ },
+ {
+ label: 'Asia/Barnaul, GMT+07:00',
+ value: 'Asia/Barnaul',
+ },
+ {
+ label: 'Asia/Beirut, GMT+03:00',
+ value: 'Asia/Beirut',
+ },
+ {
+ label: 'Asia/Bishkek, GMT+06:00',
+ value: 'Asia/Bishkek',
+ },
+ {
+ label: 'Asia/Brunei, GMT+08:00',
+ value: 'Asia/Brunei',
+ },
+ {
+ label: 'Asia/Calcutta, GMT+05:30',
+ value: 'Asia/Calcutta',
+ },
+ {
+ label: 'Asia/Chita, GMT+09:00',
+ value: 'Asia/Chita',
+ },
+ {
+ label: 'Asia/Choibalsan, GMT+08:00',
+ value: 'Asia/Choibalsan',
+ },
+ {
+ label: 'Asia/Chongqing, GMT+08:00',
+ value: 'Asia/Chongqing',
+ },
+ {
+ label: 'Asia/Chungking, GMT+08:00',
+ value: 'Asia/Chungking',
+ },
+ {
+ label: 'Asia/Colombo, GMT+05:30',
+ value: 'Asia/Colombo',
+ },
+ {
+ label: 'Asia/Dacca, GMT+06:00',
+ value: 'Asia/Dacca',
+ },
+ {
+ label: 'Asia/Damascus, GMT+03:00',
+ value: 'Asia/Damascus',
+ },
+ {
+ label: 'Asia/Dhaka, GMT+06:00',
+ value: 'Asia/Dhaka',
+ },
+ {
+ label: 'Asia/Dili, GMT+09:00',
+ value: 'Asia/Dili',
+ },
+ {
+ label: 'Asia/Dubai, GMT+04:00',
+ value: 'Asia/Dubai',
+ },
+ {
+ label: 'Asia/Dushanbe, GMT+05:00',
+ value: 'Asia/Dushanbe',
+ },
+ {
+ label: 'Asia/Famagusta, GMT+03:00',
+ value: 'Asia/Famagusta',
+ },
+ {
+ label: 'Asia/Gaza, GMT+03:00',
+ value: 'Asia/Gaza',
+ },
+ {
+ label: 'Asia/Harbin, GMT+08:00',
+ value: 'Asia/Harbin',
+ },
+ {
+ label: 'Asia/Hebron, GMT+03:00',
+ value: 'Asia/Hebron',
+ },
+ {
+ label: 'Asia/Ho_Chi_Minh, GMT+07:00',
+ value: 'Asia/Ho_Chi_Minh',
+ },
+ {
+ label: 'Asia/Hong_Kong, GMT+08:00',
+ value: 'Asia/Hong_Kong',
+ },
+ {
+ label: 'Asia/Hovd, GMT+07:00',
+ value: 'Asia/Hovd',
+ },
+ {
+ label: 'Asia/Irkutsk, GMT+08:00',
+ value: 'Asia/Irkutsk',
+ },
+ {
+ label: 'Asia/Istanbul, GMT+03:00',
+ value: 'Asia/Istanbul',
+ },
+ {
+ label: 'Asia/Jakarta, GMT+07:00',
+ value: 'Asia/Jakarta',
+ },
+ {
+ label: 'Asia/Jayapura, GMT+09:00',
+ value: 'Asia/Jayapura',
+ },
+ {
+ label: 'Asia/Jerusalem, GMT+03:00',
+ value: 'Asia/Jerusalem',
+ },
+ {
+ label: 'Asia/Kabul, GMT+04:30',
+ value: 'Asia/Kabul',
+ },
+ {
+ label: 'Asia/Kamchatka, GMT+12:00',
+ value: 'Asia/Kamchatka',
+ },
+ {
+ label: 'Asia/Karachi, GMT+05:00',
+ value: 'Asia/Karachi',
+ },
+ {
+ label: 'Asia/Kashgar, GMT+06:00',
+ value: 'Asia/Kashgar',
+ },
+ {
+ label: 'Asia/Kathmandu, GMT+05:45',
+ value: 'Asia/Kathmandu',
+ },
+ {
+ label: 'Asia/Katmandu, GMT+05:45',
+ value: 'Asia/Katmandu',
+ },
+ {
+ label: 'Asia/Khandyga, GMT+09:00',
+ value: 'Asia/Khandyga',
+ },
+ {
+ label: 'Asia/Kolkata, GMT+05:30',
+ value: 'Asia/Kolkata',
+ },
+ {
+ label: 'Asia/Krasnoyarsk, GMT+07:00',
+ value: 'Asia/Krasnoyarsk',
+ },
+ {
+ label: 'Asia/Kuala_Lumpur, GMT+08:00',
+ value: 'Asia/Kuala_Lumpur',
+ },
+ {
+ label: 'Asia/Kuching, GMT+08:00',
+ value: 'Asia/Kuching',
+ },
+ {
+ label: 'Asia/Kuwait, GMT+03:00',
+ value: 'Asia/Kuwait',
+ },
+ {
+ label: 'Asia/Macao, GMT+08:00',
+ value: 'Asia/Macao',
+ },
+ {
+ label: 'Asia/Macau, GMT+08:00',
+ value: 'Asia/Macau',
+ },
+ {
+ label: 'Asia/Magadan, GMT+11:00',
+ value: 'Asia/Magadan',
+ },
+ {
+ label: 'Asia/Makassar, GMT+08:00',
+ value: 'Asia/Makassar',
+ },
+ {
+ label: 'Asia/Manila, GMT+08:00',
+ value: 'Asia/Manila',
+ },
+ {
+ label: 'Asia/Muscat, GMT+04:00',
+ value: 'Asia/Muscat',
+ },
+ {
+ label: 'Asia/Nicosia, GMT+03:00',
+ value: 'Asia/Nicosia',
+ },
+ {
+ label: 'Asia/Novokuznetsk, GMT+07:00',
+ value: 'Asia/Novokuznetsk',
+ },
+ {
+ label: 'Asia/Novosibirsk, GMT+07:00',
+ value: 'Asia/Novosibirsk',
+ },
+ {
+ label: 'Asia/Omsk, GMT+06:00',
+ value: 'Asia/Omsk',
+ },
+ {
+ label: 'Asia/Oral, GMT+05:00',
+ value: 'Asia/Oral',
+ },
+ {
+ label: 'Asia/Phnom_Penh, GMT+07:00',
+ value: 'Asia/Phnom_Penh',
+ },
+ {
+ label: 'Asia/Pontianak, GMT+07:00',
+ value: 'Asia/Pontianak',
+ },
+ {
+ label: 'Asia/Pyongyang, GMT+09:00',
+ value: 'Asia/Pyongyang',
+ },
+ {
+ label: 'Asia/Qatar, GMT+03:00',
+ value: 'Asia/Qatar',
+ },
+ {
+ label: 'Asia/Qostanay, GMT+06:00',
+ value: 'Asia/Qostanay',
+ },
+ {
+ label: 'Asia/Qyzylorda, GMT+05:00',
+ value: 'Asia/Qyzylorda',
+ },
+ {
+ label: 'Asia/Rangoon, GMT+06:30',
+ value: 'Asia/Rangoon',
+ },
+ {
+ label: 'Asia/Riyadh, GMT+03:00',
+ value: 'Asia/Riyadh',
+ },
+ {
+ label: 'Asia/Saigon, GMT+07:00',
+ value: 'Asia/Saigon',
+ },
+ {
+ label: 'Asia/Sakhalin, GMT+11:00',
+ value: 'Asia/Sakhalin',
+ },
+ {
+ label: 'Asia/Samarkand, GMT+05:00',
+ value: 'Asia/Samarkand',
+ },
+ {
+ label: 'Asia/Seoul, GMT+09:00',
+ value: 'Asia/Seoul',
+ },
+ {
+ label: 'Asia/Shanghai, GMT+08:00',
+ value: 'Asia/Shanghai',
+ },
+ {
+ label: 'Asia/Singapore, GMT+08:00',
+ value: 'Asia/Singapore',
+ },
+ {
+ label: 'Asia/Srednekolymsk, GMT+11:00',
+ value: 'Asia/Srednekolymsk',
+ },
+ {
+ label: 'Asia/Taipei, GMT+08:00',
+ value: 'Asia/Taipei',
+ },
+ {
+ label: 'Asia/Tashkent, GMT+05:00',
+ value: 'Asia/Tashkent',
+ },
+ {
+ label: 'Asia/Tbilisi, GMT+04:00',
+ value: 'Asia/Tbilisi',
+ },
+ {
+ label: 'Asia/Tehran, GMT+03:30',
+ value: 'Asia/Tehran',
+ },
+ {
+ label: 'Asia/Tel_Aviv, GMT+03:00',
+ value: 'Asia/Tel_Aviv',
+ },
+ {
+ label: 'Asia/Thimbu, GMT+06:00',
+ value: 'Asia/Thimbu',
+ },
+ {
+ label: 'Asia/Thimphu, GMT+06:00',
+ value: 'Asia/Thimphu',
+ },
+ {
+ label: 'Asia/Tokyo, GMT+09:00',
+ value: 'Asia/Tokyo',
+ },
+ {
+ label: 'Asia/Tomsk, GMT+07:00',
+ value: 'Asia/Tomsk',
+ },
+ {
+ label: 'Asia/Ujung_Pandang, GMT+08:00',
+ value: 'Asia/Ujung_Pandang',
+ },
+ {
+ label: 'Asia/Ulaanbaatar, GMT+08:00',
+ value: 'Asia/Ulaanbaatar',
+ },
+ {
+ label: 'Asia/Ulan_Bator, GMT+08:00',
+ value: 'Asia/Ulan_Bator',
+ },
+ {
+ label: 'Asia/Urumqi, GMT+06:00',
+ value: 'Asia/Urumqi',
+ },
+ {
+ label: 'Asia/Ust-Nera, GMT+10:00',
+ value: 'Asia/Ust-Nera',
+ },
+ {
+ label: 'Asia/Vientiane, GMT+07:00',
+ value: 'Asia/Vientiane',
+ },
+ {
+ label: 'Asia/Vladivostok, GMT+10:00',
+ value: 'Asia/Vladivostok',
+ },
+ {
+ label: 'Asia/Yakutsk, GMT+09:00',
+ value: 'Asia/Yakutsk',
+ },
+ {
+ label: 'Asia/Yangon, GMT+06:30',
+ value: 'Asia/Yangon',
+ },
+ {
+ label: 'Asia/Yekaterinburg, GMT+05:00',
+ value: 'Asia/Yekaterinburg',
+ },
+ {
+ label: 'Asia/Yerevan, GMT+04:00',
+ value: 'Asia/Yerevan',
+ },
+ {
+ label: 'Atlantic/Azores, GMT',
+ value: 'Atlantic/Azores',
+ },
+ {
+ label: 'Atlantic/Bermuda, GMT-03:00',
+ value: 'Atlantic/Bermuda',
+ },
+ {
+ label: 'Atlantic/Canary, GMT+01:00',
+ value: 'Atlantic/Canary',
+ },
+ {
+ label: 'Atlantic/Cape_Verde, GMT-01:00',
+ value: 'Atlantic/Cape_Verde',
+ },
+ {
+ label: 'Atlantic/Faeroe, GMT+01:00',
+ value: 'Atlantic/Faeroe',
+ },
+ {
+ label: 'Atlantic/Faroe, GMT+01:00',
+ value: 'Atlantic/Faroe',
+ },
+ {
+ label: 'Atlantic/Jan_Mayen, GMT+02:00',
+ value: 'Atlantic/Jan_Mayen',
+ },
+ {
+ label: 'Atlantic/Madeira, GMT+01:00',
+ value: 'Atlantic/Madeira',
+ },
+ {
+ label: 'Atlantic/Reykjavik, GMT',
+ value: 'Atlantic/Reykjavik',
+ },
+ {
+ label: 'Atlantic/South_Georgia, GMT-02:00',
+ value: 'Atlantic/South_Georgia',
+ },
+ {
+ label: 'Atlantic/St_Helena, GMT',
+ value: 'Atlantic/St_Helena',
+ },
+ {
+ label: 'Atlantic/Stanley, GMT-03:00',
+ value: 'Atlantic/Stanley',
+ },
+ {
+ label: 'Australia/ACT, GMT+10:00',
+ value: 'Australia/ACT',
+ },
+ {
+ label: 'Australia/Adelaide, GMT+09:30',
+ value: 'Australia/Adelaide',
+ },
+ {
+ label: 'Australia/Brisbane, GMT+10:00',
+ value: 'Australia/Brisbane',
+ },
+ {
+ label: 'Australia/Broken_Hill, GMT+09:30',
+ value: 'Australia/Broken_Hill',
+ },
+ {
+ label: 'Australia/Canberra, GMT+10:00',
+ value: 'Australia/Canberra',
+ },
+ {
+ label: 'Australia/Currie, GMT+10:00',
+ value: 'Australia/Currie',
+ },
+ {
+ label: 'Australia/Darwin, GMT+09:30',
+ value: 'Australia/Darwin',
+ },
+ {
+ label: 'Australia/Eucla, GMT+08:45',
+ value: 'Australia/Eucla',
+ },
+ {
+ label: 'Australia/Hobart, GMT+10:00',
+ value: 'Australia/Hobart',
+ },
+ {
+ label: 'Australia/LHI, GMT+10:30',
+ value: 'Australia/LHI',
+ },
+ {
+ label: 'Australia/Lindeman, GMT+10:00',
+ value: 'Australia/Lindeman',
+ },
+ {
+ label: 'Australia/Lord_Howe, GMT+10:30',
+ value: 'Australia/Lord_Howe',
+ },
+ {
+ label: 'Australia/Melbourne, GMT+10:00',
+ value: 'Australia/Melbourne',
+ },
+ {
+ label: 'Australia/NSW, GMT+10:00',
+ value: 'Australia/NSW',
+ },
+ {
+ label: 'Australia/North, GMT+09:30',
+ value: 'Australia/North',
+ },
+ {
+ label: 'Australia/Perth, GMT+08:00',
+ value: 'Australia/Perth',
+ },
+ {
+ label: 'Australia/Queensland, GMT+10:00',
+ value: 'Australia/Queensland',
+ },
+ {
+ label: 'Australia/South, GMT+09:30',
+ value: 'Australia/South',
+ },
+ {
+ label: 'Australia/Sydney, GMT+10:00',
+ value: 'Australia/Sydney',
+ },
+ {
+ label: 'Australia/Tasmania, GMT+10:00',
+ value: 'Australia/Tasmania',
+ },
+ {
+ label: 'Australia/Victoria, GMT+10:00',
+ value: 'Australia/Victoria',
+ },
+ {
+ label: 'Australia/West, GMT+08:00',
+ value: 'Australia/West',
+ },
+ {
+ label: 'Australia/Yancowinna, GMT+09:30',
+ value: 'Australia/Yancowinna',
+ },
+ {
+ label: 'Brazil/Acre, GMT-05:00',
+ value: 'Brazil/Acre',
+ },
+ {
+ label: 'Brazil/DeNoronha, GMT-02:00',
+ value: 'Brazil/DeNoronha',
+ },
+ {
+ label: 'Brazil/East, GMT-03:00',
+ value: 'Brazil/East',
+ },
+ {
+ label: 'Brazil/West, GMT-04:00',
+ value: 'Brazil/West',
+ },
+ {
+ label: 'CET, GMT+02:00',
+ value: 'CET',
+ },
+ {
+ label: 'CST6CDT, GMT-05:00',
+ value: 'CST6CDT',
+ },
+ {
+ label: 'Canada/Atlantic, GMT-03:00',
+ value: 'Canada/Atlantic',
+ },
+ {
+ label: 'Canada/Central, GMT-05:00',
+ value: 'Canada/Central',
+ },
+ {
+ label: 'Canada/Eastern, GMT-04:00',
+ value: 'Canada/Eastern',
+ },
+ {
+ label: 'Canada/Mountain, GMT-06:00',
+ value: 'Canada/Mountain',
+ },
+ {
+ label: 'Canada/Newfoundland, GMT-02:30',
+ value: 'Canada/Newfoundland',
+ },
+ {
+ label: 'Canada/Pacific, GMT-07:00',
+ value: 'Canada/Pacific',
+ },
+ {
+ label: 'Canada/Saskatchewan, GMT-06:00',
+ value: 'Canada/Saskatchewan',
+ },
+ {
+ label: 'Canada/Yukon, GMT-07:00',
+ value: 'Canada/Yukon',
+ },
+ {
+ label: 'Chile/Continental, GMT-04:00',
+ value: 'Chile/Continental',
+ },
+ {
+ label: 'Chile/EasterIsland, GMT-06:00',
+ value: 'Chile/EasterIsland',
+ },
+ {
+ label: 'Cuba, GMT-04:00',
+ value: 'Cuba',
+ },
+ {
+ label: 'EET, GMT+03:00',
+ value: 'EET',
+ },
+ {
+ label: 'EST, GMT-05:00',
+ value: 'EST',
+ },
+ {
+ label: 'EST5EDT, GMT-04:00',
+ value: 'EST5EDT',
+ },
+ {
+ label: 'Egypt, GMT+03:00',
+ value: 'Egypt',
+ },
+ {
+ label: 'Eire, GMT+01:00',
+ value: 'Eire',
+ },
+ {
+ label: 'Etc/GMT, GMT',
+ value: 'Etc/GMT',
+ },
+ {
+ label: 'Etc/GMT+0, GMT',
+ value: 'Etc/GMT+0',
+ },
+ {
+ label: 'Etc/GMT+1, GMT-01:00',
+ value: 'Etc/GMT+1',
+ },
+ {
+ label: 'Etc/GMT+10, GMT-10:00',
+ value: 'Etc/GMT+10',
+ },
+ {
+ label: 'Etc/GMT+11, GMT-11:00',
+ value: 'Etc/GMT+11',
+ },
+ {
+ label: 'Etc/GMT+12, GMT-12:00',
+ value: 'Etc/GMT+12',
+ },
+ {
+ label: 'Etc/GMT+2, GMT-02:00',
+ value: 'Etc/GMT+2',
+ },
+ {
+ label: 'Etc/GMT+3, GMT-03:00',
+ value: 'Etc/GMT+3',
+ },
+ {
+ label: 'Etc/GMT+4, GMT-04:00',
+ value: 'Etc/GMT+4',
+ },
+ {
+ label: 'Etc/GMT+5, GMT-05:00',
+ value: 'Etc/GMT+5',
+ },
+ {
+ label: 'Etc/GMT+6, GMT-06:00',
+ value: 'Etc/GMT+6',
+ },
+ {
+ label: 'Etc/GMT+7, GMT-07:00',
+ value: 'Etc/GMT+7',
+ },
+ {
+ label: 'Etc/GMT+8, GMT-08:00',
+ value: 'Etc/GMT+8',
+ },
+ {
+ label: 'Etc/GMT+9, GMT-09:00',
+ value: 'Etc/GMT+9',
+ },
+ {
+ label: 'Etc/GMT-0, GMT',
+ value: 'Etc/GMT-0',
+ },
+ {
+ label: 'Etc/GMT-1, GMT+01:00',
+ value: 'Etc/GMT-1',
+ },
+ {
+ label: 'Etc/GMT-10, GMT+10:00',
+ value: 'Etc/GMT-10',
+ },
+ {
+ label: 'Etc/GMT-11, GMT+11:00',
+ value: 'Etc/GMT-11',
+ },
+ {
+ label: 'Etc/GMT-12, GMT+12:00',
+ value: 'Etc/GMT-12',
+ },
+ {
+ label: 'Etc/GMT-13, GMT+13:00',
+ value: 'Etc/GMT-13',
+ },
+ {
+ label: 'Etc/GMT-14, GMT+14:00',
+ value: 'Etc/GMT-14',
+ },
+ {
+ label: 'Etc/GMT-2, GMT+02:00',
+ value: 'Etc/GMT-2',
+ },
+ {
+ label: 'Etc/GMT-3, GMT+03:00',
+ value: 'Etc/GMT-3',
+ },
+ {
+ label: 'Etc/GMT-4, GMT+04:00',
+ value: 'Etc/GMT-4',
+ },
+ {
+ label: 'Etc/GMT-5, GMT+05:00',
+ value: 'Etc/GMT-5',
+ },
+ {
+ label: 'Etc/GMT-6, GMT+06:00',
+ value: 'Etc/GMT-6',
+ },
+ {
+ label: 'Etc/GMT-7, GMT+07:00',
+ value: 'Etc/GMT-7',
+ },
+ {
+ label: 'Etc/GMT-8, GMT+08:00',
+ value: 'Etc/GMT-8',
+ },
+ {
+ label: 'Etc/GMT-9, GMT+09:00',
+ value: 'Etc/GMT-9',
+ },
+ {
+ label: 'Etc/GMT0, GMT',
+ value: 'Etc/GMT0',
+ },
+ {
+ label: 'Etc/Greenwich, GMT',
+ value: 'Etc/Greenwich',
+ },
+ {
+ label: 'Etc/UCT, GMT',
+ value: 'Etc/UCT',
+ },
+ {
+ label: 'Etc/UTC, GMT',
+ value: 'Etc/UTC',
+ },
+ {
+ label: 'Etc/Universal, GMT',
+ value: 'Etc/Universal',
+ },
+ {
+ label: 'Etc/Zulu, GMT',
+ value: 'Etc/Zulu',
+ },
+ {
+ label: 'Europe/Amsterdam, GMT+02:00',
+ value: 'Europe/Amsterdam',
+ },
+ {
+ label: 'Europe/Andorra, GMT+02:00',
+ value: 'Europe/Andorra',
+ },
+ {
+ label: 'Europe/Astrakhan, GMT+04:00',
+ value: 'Europe/Astrakhan',
+ },
+ {
+ label: 'Europe/Athens, GMT+03:00',
+ value: 'Europe/Athens',
+ },
+ {
+ label: 'Europe/Belfast, GMT+01:00',
+ value: 'Europe/Belfast',
+ },
+ {
+ label: 'Europe/Belgrade, GMT+02:00',
+ value: 'Europe/Belgrade',
+ },
+ {
+ label: 'Europe/Berlin, GMT+02:00',
+ value: 'Europe/Berlin',
+ },
+ {
+ label: 'Europe/Bratislava, GMT+02:00',
+ value: 'Europe/Bratislava',
+ },
+ {
+ label: 'Europe/Brussels, GMT+02:00',
+ value: 'Europe/Brussels',
+ },
+ {
+ label: 'Europe/Bucharest, GMT+03:00',
+ value: 'Europe/Bucharest',
+ },
+ {
+ label: 'Europe/Budapest, GMT+02:00',
+ value: 'Europe/Budapest',
+ },
+ {
+ label: 'Europe/Busingen, GMT+02:00',
+ value: 'Europe/Busingen',
+ },
+ {
+ label: 'Europe/Chisinau, GMT+03:00',
+ value: 'Europe/Chisinau',
+ },
+ {
+ label: 'Europe/Copenhagen, GMT+02:00',
+ value: 'Europe/Copenhagen',
+ },
+ {
+ label: 'Europe/Dublin, GMT+01:00',
+ value: 'Europe/Dublin',
+ },
+ {
+ label: 'Europe/Gibraltar, GMT+02:00',
+ value: 'Europe/Gibraltar',
+ },
+ {
+ label: 'Europe/Guernsey, GMT+01:00',
+ value: 'Europe/Guernsey',
+ },
+ {
+ label: 'Europe/Helsinki, GMT+03:00',
+ value: 'Europe/Helsinki',
+ },
+ {
+ label: 'Europe/Isle_of_Man, GMT+01:00',
+ value: 'Europe/Isle_of_Man',
+ },
+ {
+ label: 'Europe/Istanbul, GMT+03:00',
+ value: 'Europe/Istanbul',
+ },
+ {
+ label: 'Europe/Jersey, GMT+01:00',
+ value: 'Europe/Jersey',
+ },
+ {
+ label: 'Europe/Kaliningrad, GMT+02:00',
+ value: 'Europe/Kaliningrad',
+ },
+ {
+ label: 'Europe/Kiev, GMT+03:00',
+ value: 'Europe/Kiev',
+ },
+ {
+ label: 'Europe/Kirov, GMT+03:00',
+ value: 'Europe/Kirov',
+ },
+ {
+ label: 'Europe/Kyiv, GMT+03:00',
+ value: 'Europe/Kyiv',
+ },
+ {
+ label: 'Europe/Lisbon, GMT+01:00',
+ value: 'Europe/Lisbon',
+ },
+ {
+ label: 'Europe/Ljubljana, GMT+02:00',
+ value: 'Europe/Ljubljana',
+ },
+ {
+ label: 'Europe/London, GMT+01:00',
+ value: 'Europe/London',
+ },
+ {
+ label: 'Europe/Luxembourg, GMT+02:00',
+ value: 'Europe/Luxembourg',
+ },
+ {
+ label: 'Europe/Madrid, GMT+02:00',
+ value: 'Europe/Madrid',
+ },
+ {
+ label: 'Europe/Malta, GMT+02:00',
+ value: 'Europe/Malta',
+ },
+ {
+ label: 'Europe/Mariehamn, GMT+03:00',
+ value: 'Europe/Mariehamn',
+ },
+ {
+ label: 'Europe/Minsk, GMT+03:00',
+ value: 'Europe/Minsk',
+ },
+ {
+ label: 'Europe/Monaco, GMT+02:00',
+ value: 'Europe/Monaco',
+ },
+ {
+ label: 'Europe/Moscow, GMT+03:00',
+ value: 'Europe/Moscow',
+ },
+ {
+ label: 'Europe/Nicosia, GMT+03:00',
+ value: 'Europe/Nicosia',
+ },
+ {
+ label: 'Europe/Oslo, GMT+02:00',
+ value: 'Europe/Oslo',
+ },
+ {
+ label: 'Europe/Paris, GMT+02:00',
+ value: 'Europe/Paris',
+ },
+ {
+ label: 'Europe/Podgorica, GMT+02:00',
+ value: 'Europe/Podgorica',
+ },
+ {
+ label: 'Europe/Prague, GMT+02:00',
+ value: 'Europe/Prague',
+ },
+ {
+ label: 'Europe/Riga, GMT+03:00',
+ value: 'Europe/Riga',
+ },
+ {
+ label: 'Europe/Rome, GMT+02:00',
+ value: 'Europe/Rome',
+ },
+ {
+ label: 'Europe/Samara, GMT+04:00',
+ value: 'Europe/Samara',
+ },
+ {
+ label: 'Europe/San_Marino, GMT+02:00',
+ value: 'Europe/San_Marino',
+ },
+ {
+ label: 'Europe/Sarajevo, GMT+02:00',
+ value: 'Europe/Sarajevo',
+ },
+ {
+ label: 'Europe/Saratov, GMT+04:00',
+ value: 'Europe/Saratov',
+ },
+ {
+ label: 'Europe/Simferopol, GMT+03:00',
+ value: 'Europe/Simferopol',
+ },
+ {
+ label: 'Europe/Skopje, GMT+02:00',
+ value: 'Europe/Skopje',
+ },
+ {
+ label: 'Europe/Sofia, GMT+03:00',
+ value: 'Europe/Sofia',
+ },
+ {
+ label: 'Europe/Stockholm, GMT+02:00',
+ value: 'Europe/Stockholm',
+ },
+ {
+ label: 'Europe/Tallinn, GMT+03:00',
+ value: 'Europe/Tallinn',
+ },
+ {
+ label: 'Europe/Tirane, GMT+02:00',
+ value: 'Europe/Tirane',
+ },
+ {
+ label: 'Europe/Tiraspol, GMT+03:00',
+ value: 'Europe/Tiraspol',
+ },
+ {
+ label: 'Europe/Ulyanovsk, GMT+04:00',
+ value: 'Europe/Ulyanovsk',
+ },
+ {
+ label: 'Europe/Uzhgorod, GMT+03:00',
+ value: 'Europe/Uzhgorod',
+ },
+ {
+ label: 'Europe/Vaduz, GMT+02:00',
+ value: 'Europe/Vaduz',
+ },
+ {
+ label: 'Europe/Vatican, GMT+02:00',
+ value: 'Europe/Vatican',
+ },
+ {
+ label: 'Europe/Vienna, GMT+02:00',
+ value: 'Europe/Vienna',
+ },
+ {
+ label: 'Europe/Vilnius, GMT+03:00',
+ value: 'Europe/Vilnius',
+ },
+ {
+ label: 'Europe/Volgograd, GMT+03:00',
+ value: 'Europe/Volgograd',
+ },
+ {
+ label: 'Europe/Warsaw, GMT+02:00',
+ value: 'Europe/Warsaw',
+ },
+ {
+ label: 'Europe/Zagreb, GMT+02:00',
+ value: 'Europe/Zagreb',
+ },
+ {
+ label: 'Europe/Zaporozhye, GMT+03:00',
+ value: 'Europe/Zaporozhye',
+ },
+ {
+ label: 'Europe/Zurich, GMT+02:00',
+ value: 'Europe/Zurich',
+ },
+ {
+ label: 'GB, GMT+01:00',
+ value: 'GB',
+ },
+ {
+ label: 'GB-Eire, GMT+01:00',
+ value: 'GB-Eire',
+ },
+ {
+ label: 'GMT, GMT',
+ value: 'GMT',
+ },
+ {
+ label: 'GMT+0, GMT',
+ value: 'GMT+0',
+ },
+ {
+ label: 'GMT-0, GMT',
+ value: 'GMT-0',
+ },
+ {
+ label: 'GMT0, GMT',
+ value: 'GMT0',
+ },
+ {
+ label: 'Greenwich, GMT',
+ value: 'Greenwich',
+ },
+ {
+ label: 'HST, GMT-10:00',
+ value: 'HST',
+ },
+ {
+ label: 'Hongkong, GMT+08:00',
+ value: 'Hongkong',
+ },
+ {
+ label: 'Iceland, GMT',
+ value: 'Iceland',
+ },
+ {
+ label: 'Indian/Antananarivo, GMT+03:00',
+ value: 'Indian/Antananarivo',
+ },
+ {
+ label: 'Indian/Chagos, GMT+06:00',
+ value: 'Indian/Chagos',
+ },
+ {
+ label: 'Indian/Christmas, GMT+07:00',
+ value: 'Indian/Christmas',
+ },
+ {
+ label: 'Indian/Cocos, GMT+06:30',
+ value: 'Indian/Cocos',
+ },
+ {
+ label: 'Indian/Comoro, GMT+03:00',
+ value: 'Indian/Comoro',
+ },
+ {
+ label: 'Indian/Kerguelen, GMT+05:00',
+ value: 'Indian/Kerguelen',
+ },
+ {
+ label: 'Indian/Mahe, GMT+04:00',
+ value: 'Indian/Mahe',
+ },
+ {
+ label: 'Indian/Maldives, GMT+05:00',
+ value: 'Indian/Maldives',
+ },
+ {
+ label: 'Indian/Mauritius, GMT+04:00',
+ value: 'Indian/Mauritius',
+ },
+ {
+ label: 'Indian/Mayotte, GMT+03:00',
+ value: 'Indian/Mayotte',
+ },
+ {
+ label: 'Indian/Reunion, GMT+04:00',
+ value: 'Indian/Reunion',
+ },
+ {
+ label: 'Iran, GMT+03:30',
+ value: 'Iran',
+ },
+ {
+ label: 'Israel, GMT+03:00',
+ value: 'Israel',
+ },
+ {
+ label: 'Jamaica, GMT-05:00',
+ value: 'Jamaica',
+ },
+ {
+ label: 'Japan, GMT+09:00',
+ value: 'Japan',
+ },
+ {
+ label: 'Kwajalein, GMT+12:00',
+ value: 'Kwajalein',
+ },
+ {
+ label: 'Libya, GMT+02:00',
+ value: 'Libya',
+ },
+ {
+ label: 'MET, GMT+02:00',
+ value: 'MET',
+ },
+ {
+ label: 'MST, GMT-07:00',
+ value: 'MST',
+ },
+ {
+ label: 'MST7MDT, GMT-06:00',
+ value: 'MST7MDT',
+ },
+ {
+ label: 'Mexico/BajaNorte, GMT-07:00',
+ value: 'Mexico/BajaNorte',
+ },
+ {
+ label: 'Mexico/BajaSur, GMT-07:00',
+ value: 'Mexico/BajaSur',
+ },
+ {
+ label: 'Mexico/General, GMT-06:00',
+ value: 'Mexico/General',
+ },
+ {
+ label: 'NZ, GMT+12:00',
+ value: 'NZ',
+ },
+ {
+ label: 'NZ-CHAT, GMT+12:45',
+ value: 'NZ-CHAT',
+ },
+ {
+ label: 'Navajo, GMT-06:00',
+ value: 'Navajo',
+ },
+ {
+ label: 'PRC, GMT+08:00',
+ value: 'PRC',
+ },
+ {
+ label: 'PST8PDT, GMT-07:00',
+ value: 'PST8PDT',
+ },
+ {
+ label: 'Pacific/Apia, GMT+13:00',
+ value: 'Pacific/Apia',
+ },
+ {
+ label: 'Pacific/Auckland, GMT+12:00',
+ value: 'Pacific/Auckland',
+ },
+ {
+ label: 'Pacific/Bougainville, GMT+11:00',
+ value: 'Pacific/Bougainville',
+ },
+ {
+ label: 'Pacific/Chatham, GMT+12:45',
+ value: 'Pacific/Chatham',
+ },
+ {
+ label: 'Pacific/Chuuk, GMT+10:00',
+ value: 'Pacific/Chuuk',
+ },
+ {
+ label: 'Pacific/Easter, GMT-06:00',
+ value: 'Pacific/Easter',
+ },
+ {
+ label: 'Pacific/Efate, GMT+11:00',
+ value: 'Pacific/Efate',
+ },
+ {
+ label: 'Pacific/Enderbury, GMT+13:00',
+ value: 'Pacific/Enderbury',
+ },
+ {
+ label: 'Pacific/Fakaofo, GMT+13:00',
+ value: 'Pacific/Fakaofo',
+ },
+ {
+ label: 'Pacific/Fiji, GMT+12:00',
+ value: 'Pacific/Fiji',
+ },
+ {
+ label: 'Pacific/Funafuti, GMT+12:00',
+ value: 'Pacific/Funafuti',
+ },
+ {
+ label: 'Pacific/Galapagos, GMT-06:00',
+ value: 'Pacific/Galapagos',
+ },
+ {
+ label: 'Pacific/Gambier, GMT-09:00',
+ value: 'Pacific/Gambier',
+ },
+ {
+ label: 'Pacific/Guadalcanal, GMT+11:00',
+ value: 'Pacific/Guadalcanal',
+ },
+ {
+ label: 'Pacific/Guam, GMT+10:00',
+ value: 'Pacific/Guam',
+ },
+ {
+ label: 'Pacific/Honolulu, GMT-10:00',
+ value: 'Pacific/Honolulu',
+ },
+ {
+ label: 'Pacific/Johnston, GMT-10:00',
+ value: 'Pacific/Johnston',
+ },
+ {
+ label: 'Pacific/Kanton, GMT+13:00',
+ value: 'Pacific/Kanton',
+ },
+ {
+ label: 'Pacific/Kiritimati, GMT+14:00',
+ value: 'Pacific/Kiritimati',
+ },
+ {
+ label: 'Pacific/Kosrae, GMT+11:00',
+ value: 'Pacific/Kosrae',
+ },
+ {
+ label: 'Pacific/Kwajalein, GMT+12:00',
+ value: 'Pacific/Kwajalein',
+ },
+ {
+ label: 'Pacific/Majuro, GMT+12:00',
+ value: 'Pacific/Majuro',
+ },
+ {
+ label: 'Pacific/Marquesas, GMT-09:30',
+ value: 'Pacific/Marquesas',
+ },
+ {
+ label: 'Pacific/Midway, GMT-11:00',
+ value: 'Pacific/Midway',
+ },
+ {
+ label: 'Pacific/Nauru, GMT+12:00',
+ value: 'Pacific/Nauru',
+ },
+ {
+ label: 'Pacific/Niue, GMT-11:00',
+ value: 'Pacific/Niue',
+ },
+ {
+ label: 'Pacific/Norfolk, GMT+11:00',
+ value: 'Pacific/Norfolk',
+ },
+ {
+ label: 'Pacific/Noumea, GMT+11:00',
+ value: 'Pacific/Noumea',
+ },
+ {
+ label: 'Pacific/Pago_Pago, GMT-11:00',
+ value: 'Pacific/Pago_Pago',
+ },
+ {
+ label: 'Pacific/Palau, GMT+09:00',
+ value: 'Pacific/Palau',
+ },
+ {
+ label: 'Pacific/Pitcairn, GMT-08:00',
+ value: 'Pacific/Pitcairn',
+ },
+ {
+ label: 'Pacific/Pohnpei, GMT+11:00',
+ value: 'Pacific/Pohnpei',
+ },
+ {
+ label: 'Pacific/Ponape, GMT+11:00',
+ value: 'Pacific/Ponape',
+ },
+ {
+ label: 'Pacific/Port_Moresby, GMT+10:00',
+ value: 'Pacific/Port_Moresby',
+ },
+ {
+ label: 'Pacific/Rarotonga, GMT-10:00',
+ value: 'Pacific/Rarotonga',
+ },
+ {
+ label: 'Pacific/Saipan, GMT+10:00',
+ value: 'Pacific/Saipan',
+ },
+ {
+ label: 'Pacific/Samoa, GMT-11:00',
+ value: 'Pacific/Samoa',
+ },
+ {
+ label: 'Pacific/Tahiti, GMT-10:00',
+ value: 'Pacific/Tahiti',
+ },
+ {
+ label: 'Pacific/Tarawa, GMT+12:00',
+ value: 'Pacific/Tarawa',
+ },
+ {
+ label: 'Pacific/Tongatapu, GMT+13:00',
+ value: 'Pacific/Tongatapu',
+ },
+ {
+ label: 'Pacific/Truk, GMT+10:00',
+ value: 'Pacific/Truk',
+ },
+ {
+ label: 'Pacific/Wake, GMT+12:00',
+ value: 'Pacific/Wake',
+ },
+ {
+ label: 'Pacific/Wallis, GMT+12:00',
+ value: 'Pacific/Wallis',
+ },
+ {
+ label: 'Pacific/Yap, GMT+10:00',
+ value: 'Pacific/Yap',
+ },
+ {
+ label: 'Poland, GMT+02:00',
+ value: 'Poland',
+ },
+ {
+ label: 'Portugal, GMT+01:00',
+ value: 'Portugal',
+ },
+ {
+ label: 'ROC, GMT+08:00',
+ value: 'ROC',
+ },
+ {
+ label: 'ROK, GMT+09:00',
+ value: 'ROK',
+ },
+ {
+ label: 'Singapore, GMT+08:00',
+ value: 'Singapore',
+ },
+ {
+ label: 'Turkey, GMT+03:00',
+ value: 'Turkey',
+ },
+ {
+ label: 'UCT, GMT',
+ value: 'UCT',
+ },
+ {
+ label: 'US/Alaska, GMT-08:00',
+ value: 'US/Alaska',
+ },
+ {
+ label: 'US/Aleutian, GMT-09:00',
+ value: 'US/Aleutian',
+ },
+ {
+ label: 'US/Arizona, GMT-07:00',
+ value: 'US/Arizona',
+ },
+ {
+ label: 'US/Central, GMT-05:00',
+ value: 'US/Central',
+ },
+ {
+ label: 'US/East-Indiana, GMT-04:00',
+ value: 'US/East-Indiana',
+ },
+ {
+ label: 'US/Eastern, GMT-04:00',
+ value: 'US/Eastern',
+ },
+ {
+ label: 'US/Hawaii, GMT-10:00',
+ value: 'US/Hawaii',
+ },
+ {
+ label: 'US/Indiana-Starke, GMT-05:00',
+ value: 'US/Indiana-Starke',
+ },
+ {
+ label: 'US/Michigan, GMT-04:00',
+ value: 'US/Michigan',
+ },
+ {
+ label: 'US/Mountain, GMT-06:00',
+ value: 'US/Mountain',
+ },
+ {
+ label: 'US/Pacific, GMT-07:00',
+ value: 'US/Pacific',
+ },
+ {
+ label: 'US/Samoa, GMT-11:00',
+ value: 'US/Samoa',
+ },
+ {
+ label: 'UTC, GMT',
+ value: 'UTC',
+ },
+ {
+ label: 'Universal, GMT',
+ value: 'Universal',
+ },
+ {
+ label: 'W-SU, GMT+03:00',
+ value: 'W-SU',
+ },
+ {
+ label: 'WET, GMT+01:00',
+ value: 'WET',
+ },
+ {
+ label: 'Zulu, GMT',
+ value: 'Zulu',
+ },
+]
diff --git a/packages/constants/src/workspace.ts b/packages/constants/src/workspace.ts
new file mode 100644
index 0000000..88f60f6
--- /dev/null
+++ b/packages/constants/src/workspace.ts
@@ -0,0 +1,216 @@
+// types
+
+// services images
+
+import CSVLogo from 'public/services/csv.svg'
+import ExcelLogo from 'public/services/excel.svg'
+import GithubLogo from 'public/services/github.png'
+import JiraLogo from 'public/services/jira.svg'
+import JSONLogo from 'public/services/json.svg'
+
+import { TStaticViewTypes } from '@prodkt/types'
+
+// icons
+import { SettingIcon } from '@/components/icons/attachment'
+import { Props } from '@/components/icons/types'
+
+export enum EUserWorkspaceRoles {
+ GUEST = 5,
+ VIEWER = 10,
+ MEMBER = 15,
+ ADMIN = 20,
+}
+
+export const ROLE = {
+ 5: 'Guest',
+ 10: 'Viewer',
+ 15: 'Member',
+ 20: 'Admin',
+}
+
+export const ROLE_DETAILS = {
+ 5: {
+ title: 'Guest',
+ description: 'External members of organizations can be invited as guests.',
+ },
+ 10: {
+ title: 'Viewer',
+ description: 'External members of organizations can be invited as guests.',
+ },
+ 15: {
+ title: 'Member',
+ description:
+ 'Ability to read, write, edit, and delete entities inside projects, cycles, and modules',
+ },
+ 20: {
+ title: 'Admin',
+ description: 'All permissions set to true within the workspace.',
+ },
+}
+
+export const ORGANIZATION_SIZE = [
+ 'Just myself',
+ '2-10',
+ '11-50',
+ '51-200',
+ '201-500',
+ '500+',
+]
+
+export const USER_ROLES = [
+ { value: 'Product / Project Manager', label: 'Product / Project Manager' },
+ { value: 'Development / Engineering', label: 'Development / Engineering' },
+ { value: 'Founder / Executive', label: 'Founder / Executive' },
+ { value: 'Freelancer / Consultant', label: 'Freelancer / Consultant' },
+ { value: 'Marketing / Growth', label: 'Marketing / Growth' },
+ {
+ value: 'Sales / Business Development',
+ label: 'Sales / Business Development',
+ },
+ { value: 'Support / Operations', label: 'Support / Operations' },
+ { value: 'Student / Professor', label: 'Student / Professor' },
+ { value: 'Human Resources', label: 'Human Resources' },
+ { value: 'Other', label: 'Other' },
+]
+
+export const IMPORTERS_LIST = [
+ {
+ provider: 'github',
+ type: 'import',
+ title: 'GitHub',
+ description: 'Import issues from GitHub repositories and sync them.',
+ logo: GithubLogo,
+ },
+ {
+ provider: 'jira',
+ type: 'import',
+ title: 'Jira',
+ description: 'Import issues and epics from Jira projects and epics.',
+ logo: JiraLogo,
+ },
+]
+
+export const EXPORTERS_LIST = [
+ {
+ provider: 'csv',
+ type: 'export',
+ title: 'CSV',
+ description: 'Export issues to a CSV file.',
+ logo: CSVLogo,
+ },
+ {
+ provider: 'xlsx',
+ type: 'export',
+ title: 'Excel',
+ description: 'Export issues to a Excel file.',
+ logo: ExcelLogo,
+ },
+ {
+ provider: 'json',
+ type: 'export',
+ title: 'JSON',
+ description: 'Export issues to a JSON file.',
+ logo: JSONLogo,
+ },
+]
+
+export const DEFAULT_GLOBAL_VIEWS_LIST: {
+ key: TStaticViewTypes
+ label: string
+}[] = [
+ {
+ key: 'all-issues',
+ label: 'All issues',
+ },
+ {
+ key: 'assigned',
+ label: 'Assigned',
+ },
+ {
+ key: 'created',
+ label: 'Created',
+ },
+ {
+ key: 'subscribed',
+ label: 'Subscribed',
+ },
+]
+
+export const RESTRICTED_URLS = [
+ '404',
+ 'accounts',
+ 'api',
+ 'create-workspace',
+ 'error',
+ 'god-mode',
+ 'installations',
+ 'invitations',
+ 'onboarding',
+ 'profile',
+ 'spaces',
+ 'workspace-invitations',
+]
+
+export const WORKSPACE_SETTINGS_LINKS: {
+ key: string
+ label: string
+ href: string
+ access: EUserWorkspaceRoles
+ highlight: (pathname: string, baseUrl: string) => boolean
+ Icon: React.FC
+}[] = [
+ {
+ key: 'general',
+ label: 'General',
+ href: `/settings`,
+ access: EUserWorkspaceRoles.GUEST,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'members',
+ label: 'Members',
+ href: `/settings/members`,
+ access: EUserWorkspaceRoles.GUEST,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/members`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'billing-and-plans',
+ label: 'Billing and plans',
+ href: `/settings/billing`,
+ access: EUserWorkspaceRoles.ADMIN,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/billing`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'export',
+ label: 'Exports',
+ href: `/settings/exports`,
+ access: EUserWorkspaceRoles.MEMBER,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/exports`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'webhooks',
+ label: 'Webhooks',
+ href: `/settings/webhooks`,
+ access: EUserWorkspaceRoles.ADMIN,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/webhooks`,
+ Icon: SettingIcon,
+ },
+ {
+ key: 'api-tokens',
+ label: 'API tokens',
+ href: `/settings/api-tokens`,
+ access: EUserWorkspaceRoles.ADMIN,
+ highlight: (pathname: string, baseUrl: string) =>
+ pathname === `${baseUrl}/settings/api-tokens`,
+ Icon: SettingIcon,
+ },
+]
diff --git a/packages/editor/core/.eslintrc.js b/packages/editor/core/.eslintrc.js
new file mode 100644
index 0000000..c8df607
--- /dev/null
+++ b/packages/editor/core/.eslintrc.js
@@ -0,0 +1,4 @@
+module.exports = {
+ root: true,
+ extends: ["custom"],
+};
diff --git a/packages/editor/core/.prettierignore b/packages/editor/core/.prettierignore
new file mode 100644
index 0000000..43e8a7b
--- /dev/null
+++ b/packages/editor/core/.prettierignore
@@ -0,0 +1,6 @@
+.next
+.vercel
+.tubro
+out/
+dis/
+build/
\ No newline at end of file
diff --git a/packages/editor/core/.prettierrc b/packages/editor/core/.prettierrc
new file mode 100644
index 0000000..87d988f
--- /dev/null
+++ b/packages/editor/core/.prettierrc
@@ -0,0 +1,5 @@
+{
+ "printWidth": 120,
+ "tabWidth": 2,
+ "trailingComma": "es5"
+}
diff --git a/packages/editor/core/Readme.md b/packages/editor/core/Readme.md
new file mode 100644
index 0000000..230fab5
--- /dev/null
+++ b/packages/editor/core/Readme.md
@@ -0,0 +1,116 @@
+# @prodkt/editor-core
+
+## Description
+
+The `@prodkt/editor-core` package serves as the foundation for our editor system. It provides the base functionality for our other editor packages, but it will not be used directly in any of the projects but only for extending other editors.
+
+## Utilities
+
+We provide a wide range of utilities for extending the core itself.
+
+1. Merging classes and custom styling
+2. Adding new extensions
+3. Adding custom props
+4. Base menu items, and their commands
+
+This allows for extensive customization and flexibility in the Editors created using our `editor-core` package.
+
+### Here's a detailed overview of what's exported
+
+1. useEditor - A hook that you can use to extend the Prodkt editor.
+
+ | Prop | Type | Description |
+ | ------------------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+ | `extensions` | `Extension[]` | An array of custom extensions you want to add into the editor to extend it's core features |
+ | `editorProps` | `EditorProps` | Extend the editor props by passing in a custom props object |
+ | `uploadFile` | `(file: File) => Promise` | A function that handles file upload. It takes a file as input and handles the process of uploading that file. |
+ | `deleteFile` | `(assetUrlWithWorkspaceId: string) => Promise` | A function that handles deleting an image. It takes the asset url from your bucket and handles the process of deleting that image. |
+ | `value` | `html string` | The initial content of the editor. |
+ | `debouncedUpdatesEnabled` | `boolean` | If set to true, the `onChange` event handler is debounced, meaning it will only be invoked after the specified delay (default 1500ms) once the user has stopped typing. |
+ | `onChange` | `(json: any, html: string) => void` | This function is invoked whenever the content of the editor changes. It is passed the new content in both JSON and HTML formats. |
+ | `setIsSubmitting` | `(isSubmitting: "submitting" \| "submitted" \| "saved") => void` | This function is called to update the submission status. |
+ | `setShouldShowAlert` | `(showAlert: boolean) => void` | This function is used to show or hide an alert in case of content not being "saved". |
+ | `forwardedRef` | `any` | Pass this in whenever you want to control the editor's state from an external component |
+
+2. useReadOnlyEditor - A hook that can be used to extend a Read Only instance of the core editor.
+
+ | Prop | Type | Description |
+ | -------------- | ------------- | ------------------------------------------------------------------------------------------ |
+ | `value` | `string` | The initial content of the editor. |
+ | `forwardedRef` | `any` | Pass this in whenever you want to control the editor's state from an external component |
+ | `extensions` | `Extension[]` | An array of custom extensions you want to add into the editor to extend it's core features |
+ | `editorProps` | `EditorProps` | Extend the editor props by passing in a custom props object |
+
+3. Items and Commands - H1, H2, H3, task list, quote, code block, etc's methods.
+
+4. UI Wrappers
+
+- `EditorContainer` - Wrap your Editor Container with this to apply base classes and styles.
+- `EditorContentWrapper` - Use this to get Editor's Content and base menus.
+
+5. Extending with Custom Styles
+
+```ts
+const customEditorClassNames = getEditorClassNames({
+ noBorder,
+ borderOnFocus,
+ customClassName,
+});
+```
+
+## Core features
+
+- **Content Trimming**: The Editor’s content is now automatically trimmed of empty line breaks from the start and end before submitting it to the backend. This ensures cleaner, more consistent data.
+- **Value Cleaning**: The Editor’s value is cleaned at the editor core level, eliminating the need for additional validation before sending from our app. This results in cleaner code and less potential for errors.
+- **Turbo Pipeline**: Added a turbo pipeline for both dev and build tasks for projects depending on the editor package.
+
+```json
+ "web#develop": {
+ "cache": false,
+ "persistent": true,
+ "dependsOn": [
+ "@prodkt/lite-text-editor#build",
+ "@prodkt/rich-text-editor#build"
+ ]
+ },
+ "space#develop": {
+ "cache": false,
+ "persistent": true,
+ "dependsOn": [
+ "@prodkt/lite-text-editor#build",
+ "@prodkt/rich-text-editor#build"
+ ]
+ },
+ "web#build": {
+ "cache": true,
+ "dependsOn": [
+ "@prodkt/lite-text-editor#build",
+ "@prodkt/rich-text-editor#build"
+ ]
+ },
+ "space#build": {
+ "cache": true,
+ "dependsOn": [
+ "@prodkt/lite-text-editor#build",
+ "@prodkt/rich-text-editor#build"
+ ]
+ },
+
+```
+
+## Base extensions included
+
+- BulletList
+- OrderedList
+- Blockquote
+- Code
+- Gapcursor
+- Link
+- Image
+- Basic Marks
+ - Underline
+ - TextStyle
+ - Color
+- TaskList
+- Markdown
+- Table
diff --git a/packages/editor/core/package.json b/packages/editor/core/package.json
new file mode 100644
index 0000000..e8e44f7
--- /dev/null
+++ b/packages/editor/core/package.json
@@ -0,0 +1,77 @@
+{
+ "name": "@prodkt/editor-core",
+ "version": "0.1.0",
+ "description": "Core Editor that powers Prodkt",
+ "private": true,
+ "main": "./dist/index.mjs",
+ "module": "./dist/index.mjs",
+ "types": "./dist/index.d.mts",
+ "files": [
+ "dist/**/*"
+ ],
+ "exports": {
+ ".": {
+ "types": "./dist/index.d.mts",
+ "import": "./dist/index.mjs",
+ "module": "./dist/index.mjs"
+ }
+ },
+ "scripts": {
+ "build": "tsup --minify",
+ "dev": "tsup --watch",
+ "check-types": "tsc --noEmit",
+ "format": "prettier --write \"**/*.{ts,tsx,md}\""
+ },
+ "peerDependencies": {
+ "next": "12.3.2",
+ "react": "^18.2.0",
+ "react-dom": "18.2.0"
+ },
+ "dependencies": {
+ "@prodkt/ui": "*",
+ "@tiptap/core": "^2.1.13",
+ "@tiptap/extension-blockquote": "^2.1.13",
+ "@tiptap/extension-image": "^2.1.13",
+ "@tiptap/extension-list-item": "^2.1.13",
+ "@tiptap/extension-mention": "^2.1.13",
+ "@tiptap/extension-placeholder": "^2.3.0",
+ "@tiptap/extension-task-item": "^2.1.13",
+ "@tiptap/extension-task-list": "^2.1.13",
+ "@tiptap/extension-text-style": "^2.1.13",
+ "@tiptap/extension-underline": "^2.1.13",
+ "@tiptap/pm": "^2.1.13",
+ "@tiptap/react": "^2.1.13",
+ "@tiptap/starter-kit": "^2.1.13",
+ "@tiptap/suggestion": "^2.0.13",
+ "class-variance-authority": "^0.7.0",
+ "clsx": "^1.2.1",
+ "highlight.js": "^11.8.0",
+ "jsx-dom-cjs": "^8.0.3",
+ "linkifyjs": "^4.1.3",
+ "lowlight": "^3.0.0",
+ "lucide-react": "^0.378.0",
+ "prosemirror-codemark": "^0.4.2",
+ "react-moveable": "^0.54.2",
+ "tailwind-merge": "^1.14.0",
+ "tippy.js": "^6.3.7",
+ "tiptap-markdown": "^0.8.9"
+ },
+ "devDependencies": {
+ "@types/node": "18.15.3",
+ "@types/react": "^18.2.42",
+ "@types/react-dom": "^18.2.17",
+ "eslint-config-custom": "*",
+ "postcss": "^8.4.38",
+ "tailwind-config-custom": "*",
+ "tsconfig": "*",
+ "tsup": "^7.2.0",
+ "typescript": "4.9.5"
+ },
+ "keywords": [
+ "editor",
+ "rich-text",
+ "markdown",
+ "nextjs",
+ "react"
+ ]
+}
diff --git a/packages/editor/core/postcss.config.js b/packages/editor/core/postcss.config.js
new file mode 100644
index 0000000..07aa434
--- /dev/null
+++ b/packages/editor/core/postcss.config.js
@@ -0,0 +1,9 @@
+// If you want to use other PostCSS plugins, see the following:
+// https://tailwindcss.com/docs/using-with-preprocessors
+
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/packages/editor/core/src/helpers/insert-content-at-cursor-position.ts b/packages/editor/core/src/helpers/insert-content-at-cursor-position.ts
new file mode 100644
index 0000000..f17858d
--- /dev/null
+++ b/packages/editor/core/src/helpers/insert-content-at-cursor-position.ts
@@ -0,0 +1,28 @@
+import { Selection } from "@tiptap/pm/state";
+import { Editor } from "@tiptap/react";
+import { MutableRefObject } from "react";
+
+export const insertContentAtSavedSelection = (
+ editorRef: MutableRefObject,
+ content: string,
+ savedSelection: Selection
+) => {
+ if (!editorRef.current || editorRef.current.isDestroyed) {
+ console.error("Editor reference is not available or has been destroyed.");
+ return;
+ }
+
+ if (!savedSelection) {
+ console.error("Saved selection is invalid.");
+ return;
+ }
+
+ const docSize = editorRef.current.state.doc.content.size;
+ const safePosition = Math.max(0, Math.min(savedSelection.anchor, docSize));
+
+ try {
+ editorRef.current.chain().focus().insertContentAt(safePosition, content).run();
+ } catch (error) {
+ console.error("An error occurred while inserting content at saved selection:", error);
+ }
+};
diff --git a/packages/editor/core/src/helpers/scroll-to-node.ts b/packages/editor/core/src/helpers/scroll-to-node.ts
new file mode 100644
index 0000000..abcb132
--- /dev/null
+++ b/packages/editor/core/src/helpers/scroll-to-node.ts
@@ -0,0 +1,38 @@
+import type { Editor } from "@tiptap/react";
+
+export interface IMarking {
+ type: "heading";
+ level: number;
+ text: string;
+ sequence: number;
+}
+
+function findNthH1(editor: Editor, level?: number): number {
+ let pos = 0;
+ editor.state.doc.descendants((node, position) => {
+ // biome-ignore lint/complexity/useLiteralKeys:
+ if (node.type.name === "heading" && node.attrs["level"] === level) {
+ pos = position;
+ return false; // Stop traversal when matching heading is found
+ }
+ return true;
+ });
+ return pos;
+}
+
+function scrollToNode(editor: Editor, pos: number): void {
+ const headingNode = editor.state.doc.nodeAt(pos);
+ if (headingNode) {
+ const headingDOM = editor.view.nodeDOM(pos);
+ if (headingDOM instanceof HTMLElement) {
+ headingDOM.scrollIntoView({ behavior: "smooth" });
+ }
+ }
+}
+
+export function scrollSummary(editor: Editor, marking: IMarking) {
+ if (editor) {
+ const pos = findNthH1(editor, marking.level);
+ scrollToNode(editor, pos);
+ }
+}
diff --git a/packages/editor/core/src/hooks/use-editor.tsx b/packages/editor/core/src/hooks/use-editor.tsx
new file mode 100644
index 0000000..abc481b
--- /dev/null
+++ b/packages/editor/core/src/hooks/use-editor.tsx
@@ -0,0 +1,232 @@
+import { useEditor as useCustomEditor, type Editor } from "@tiptap/react";
+import { useImperativeHandle, useRef, type MutableRefObject, useState, useEffect } from "react";
+import { CoreEditorProps } from "@/ui/props";
+import { CoreEditorExtensions } from "@/ui/extensions";
+import type { EditorProps } from "@tiptap/pm/view";
+import type { DeleteImage } from "@/types/delete-image";
+import type { IMentionHighlight, IMentionSuggestion } from "@/types/mention-suggestion";
+import type { RestoreImage } from "@/types/restore-image";
+import type { UploadImage } from "@/types/upload-image";
+import type { Selection } from "@tiptap/pm/state";
+import { insertContentAtSavedSelection } from "@/helpers/insert-content-at-cursor-position";
+import { type EditorMenuItemNames, getEditorMenuItems } from "@/ui/menus/menu-items";
+import type { EditorRefApi } from "@/types/editor-ref-api";
+import { type IMarking, scrollSummary } from "@/helpers/scroll-to-node";
+
+export type TFileHandler = {
+ cancel: () => void;
+ delete: DeleteImage;
+ upload: UploadImage;
+ restore: RestoreImage;
+};
+
+export interface CustomEditorProps {
+ id?: string;
+ fileHandler: TFileHandler;
+ initialValue?: string;
+ editorClassName: string;
+ // undefined when prop is not passed, null if intentionally passed to stop
+ // swr syncing
+ value?: string | null | undefined;
+ onChange?: (json: object, html: string) => void;
+ // biome-ignore lint/suspicious/noExplicitAny:
+ extensions?: any;
+ editorProps?: EditorProps;
+ forwardedRef?: MutableRefObject;
+ mentionHandler: {
+ highlights: () => Promise;
+ suggestions?: () => Promise;
+ };
+ handleEditorReady?: (value: boolean) => void;
+ placeholder: string | ((isFocused: boolean, value: string) => string) | undefined;
+ tabIndex?: number;
+}
+
+export const useEditor = ({
+ id = "",
+ editorProps = {},
+ initialValue,
+ editorClassName,
+ value,
+ extensions = [],
+ fileHandler,
+ onChange,
+ forwardedRef,
+ tabIndex,
+ handleEditorReady,
+ mentionHandler,
+ placeholder,
+}: CustomEditorProps) => {
+ const editor = useCustomEditor({
+ editorProps: {
+ ...CoreEditorProps(editorClassName),
+ ...editorProps,
+ },
+ extensions: [
+ ...CoreEditorExtensions({
+ mentionConfig: {
+ mentionSuggestions: mentionHandler.suggestions as () => Promise,
+ mentionHighlights: mentionHandler.highlights as () => Promise,
+ },
+ fileConfig: {
+ uploadFile: fileHandler.upload,
+ deleteFile: fileHandler.delete,
+ restoreFile: fileHandler.restore,
+ cancelUploadImage: fileHandler.cancel,
+ },
+ placeholder: placeholder as NonNullable,
+ tabIndex: tabIndex as NonNullable,
+ }),
+ ...extensions,
+ ],
+ content: typeof initialValue === "string" && initialValue.trim() !== "" ? initialValue : "",
+ onCreate: async () => {
+ handleEditorReady?.(true);
+ },
+ onTransaction: async ({ editor }) => {
+ setSavedSelection(editor.state.selection);
+ },
+ onUpdate: async ({ editor }) => {
+ onChange?.(editor.getJSON(), editor.getHTML());
+ },
+ onDestroy: async () => {
+ handleEditorReady?.(false);
+ },
+ });
+
+ const editorRef: MutableRefObject = useRef(null);
+
+ const [savedSelection, setSavedSelection] = useState(null);
+
+ // Inside your component or hook
+ const savedSelectionRef = useRef(savedSelection);
+
+ // Update the ref whenever savedSelection changes
+ useEffect(() => {
+ savedSelectionRef.current = savedSelection;
+ }, [savedSelection]);
+
+ // Effect for syncing SWR data
+ useEffect(() => {
+ // value is null when intentionally passed where syncing is not yet
+ // supported and value is undefined when the data from swr is not populated
+ if (value === null || value === undefined) return;
+ if (
+ editor &&
+ !editor.isDestroyed &&
+ // biome-ignore lint/complexity/useLiteralKeys:
+ !editor.storage["image"].uploadInProgress
+ ) {
+ try {
+ editor.commands.setContent(value, false, {
+ preserveWhitespace: "full",
+ });
+ const currentSavedSelection = savedSelectionRef.current;
+ if (currentSavedSelection) {
+ const docLength = editor.state.doc.content.size;
+ const relativePosition = Math.min(currentSavedSelection.from, docLength - 1);
+ editor.commands.setTextSelection(relativePosition);
+ }
+ } catch (error) {
+ console.error("Error syncing editor content with external value:", error);
+ }
+ }
+ }, [editor, value, id]);
+
+ useImperativeHandle(
+ forwardedRef,
+ () => ({
+ clearEditor: () => {
+ editorRef.current?.commands.clearContent();
+ },
+ setEditorValue: (content: string) => {
+ editorRef.current?.commands.setContent(content);
+ },
+ setEditorValueAtCursorPosition: (content: string) => {
+ if (savedSelection) {
+ insertContentAtSavedSelection(editorRef, content, savedSelection);
+ }
+ },
+ executeMenuItemCommand: (itemName: EditorMenuItemNames) => {
+ const editorItems = getEditorMenuItems(editorRef.current, fileHandler.upload);
+
+ const getEditorMenuItem = (itemName: EditorMenuItemNames) => editorItems.find((item) => item.key === itemName);
+
+ const item = getEditorMenuItem(itemName);
+ if (item) {
+ if (item.key === "image") {
+ item.command(savedSelectionRef.current);
+ } else {
+ item.command();
+ }
+ } else {
+ console.warn(`No command found for item: ${itemName}`);
+ }
+ },
+ isMenuItemActive: (itemName: EditorMenuItemNames): boolean => {
+ const editorItems = getEditorMenuItems(editorRef.current, fileHandler.upload);
+
+ const getEditorMenuItem = (itemName: EditorMenuItemNames) => editorItems.find((item) => item.key === itemName);
+ const item = getEditorMenuItem(itemName);
+ return item ? item.isActive() : false;
+ },
+ onStateChange: (callback: () => void) => {
+ // Subscribe to editor state changes
+ editorRef.current?.on("transaction", () => {
+ callback();
+ });
+ // Return a function to unsubscribe to the continuous transactions of
+ // the editor on unmounting the component that has subscribed to this
+ // method
+ return () => {
+ editorRef.current?.off("transaction");
+ };
+ },
+ getMarkDown: (): string => {
+ const markdownOutput =
+ // biome-ignore lint/complexity/useLiteralKeys:
+ editorRef.current?.storage["markdown"].getMarkdown();
+ return markdownOutput;
+ },
+ getHTML: (): string => {
+ const htmlOutput = editorRef.current?.getHTML() ?? "";
+ return htmlOutput;
+ },
+ scrollSummary: (marking: IMarking): void => {
+ if (!editorRef.current) return;
+ scrollSummary(editorRef.current, marking);
+ },
+ isEditorReadyToDiscard: () =>
+ // biome-ignore lint/complexity/useLiteralKeys:
+ editorRef.current?.storage["image"].uploadInProgress === false,
+ setFocusAtPosition: (position: number) => {
+ if (!editorRef.current || editorRef.current.isDestroyed) {
+ console.error("Editor reference is not available or has been destroyed.");
+ return;
+ }
+ try {
+ const docSize = editorRef.current.state.doc.content.size;
+ const safePosition = Math.max(0, Math.min(position, docSize));
+ editorRef.current
+ .chain()
+ .insertContentAt(safePosition, [{ type: "paragraph" }])
+ .focus()
+ .run();
+ } catch (error) {
+ console.error("An error occurred while setting focus at position:", error);
+ }
+ },
+ }),
+ [editorRef, savedSelection, fileHandler.upload]
+ );
+
+ if (!editor) {
+ return null;
+ }
+
+ // the editorRef is used to access the editor instance from outside the hook
+ // and should only be used after editor is initialized
+ editorRef.current = editor;
+
+ return editor;
+};
diff --git a/packages/editor/core/src/hooks/use-read-only-editor.tsx b/packages/editor/core/src/hooks/use-read-only-editor.tsx
new file mode 100644
index 0000000..74cd8a2
--- /dev/null
+++ b/packages/editor/core/src/hooks/use-read-only-editor.tsx
@@ -0,0 +1,89 @@
+import { useEditor as useCustomEditor, type Editor } from "@tiptap/react";
+import { useImperativeHandle, useRef, type MutableRefObject, useEffect } from "react";
+import { CoreReadOnlyEditorExtensions } from "@/ui/read-only/extensions";
+import { CoreReadOnlyEditorProps } from "@/ui/read-only/props";
+import type { EditorProps } from "@tiptap/pm/view";
+import type { EditorReadOnlyRefApi } from "@/types/editor-ref-api";
+import { type IMarking, scrollSummary } from "@/helpers/scroll-to-node";
+import type { IMentionHighlight } from "@/types/mention-suggestion";
+
+interface CustomReadOnlyEditorProps {
+ initialValue: string;
+ editorClassName: string;
+ forwardedRef?: MutableRefObject;
+ extensions?: any;
+ editorProps?: EditorProps;
+ handleEditorReady?: (value: boolean) => void;
+ mentionHandler: {
+ highlights: () => Promise;
+ };
+}
+
+export const useReadOnlyEditor = ({
+ initialValue,
+ editorClassName,
+ forwardedRef,
+ extensions = [],
+ editorProps = {},
+ handleEditorReady,
+ mentionHandler,
+}: CustomReadOnlyEditorProps) => {
+ const editor = useCustomEditor({
+ editable: false,
+ content: typeof initialValue === "string" && initialValue.trim() !== "" ? initialValue : "",
+ editorProps: {
+ ...CoreReadOnlyEditorProps(editorClassName),
+ ...editorProps,
+ },
+ onCreate: async () => {
+ handleEditorReady?.(true);
+ },
+ extensions: [
+ ...CoreReadOnlyEditorExtensions({
+ mentionHighlights: mentionHandler.highlights,
+ }),
+ ...extensions,
+ ],
+ onDestroy: () => {
+ handleEditorReady?.(false);
+ },
+ });
+
+ // for syncing swr data on tab refocus etc
+ useEffect(() => {
+ if (initialValue === null || initialValue === undefined) return;
+ if (editor && !editor.isDestroyed) editor?.commands.setContent(initialValue);
+ }, [editor, initialValue]);
+
+ const editorRef: MutableRefObject = useRef(null);
+
+ useImperativeHandle(forwardedRef, () => ({
+ clearEditor: () => {
+ editorRef.current?.commands.clearContent();
+ },
+ setEditorValue: (content: string) => {
+ editorRef.current?.commands.setContent(content);
+ },
+ getMarkDown: (): string => {
+ const markdownOutput =
+ // biome-ignore lint/complexity/useLiteralKeys:
+ editorRef.current?.storage["markdown"].getMarkdown();
+ return markdownOutput;
+ },
+ getHTML: (): string => {
+ const htmlOutput = editorRef.current?.getHTML() ?? "";
+ return htmlOutput;
+ },
+ scrollSummary: (marking: IMarking): void => {
+ if (!editorRef.current) return;
+ scrollSummary(editorRef.current, marking);
+ },
+ }));
+
+ if (!editor) {
+ return null;
+ }
+
+ editorRef.current = editor;
+ return editor;
+};
diff --git a/packages/editor/core/src/index.ts b/packages/editor/core/src/index.ts
new file mode 100644
index 0000000..493f02d
--- /dev/null
+++ b/packages/editor/core/src/index.ts
@@ -0,0 +1,34 @@
+// styles
+// import "./styles/tailwind.css";
+import "src/styles/editor.css";
+import "src/styles/table.css";
+import "src/styles/github-dark.css";
+
+export { isCellSelection } from "src/ui/extensions/table/table/utilities/is-cell-selection";
+
+// utils
+export * from "src/lib/utils";
+export * from "src/ui/extensions/table/table";
+export { startImageUpload } from "src/ui/plugins/image/image-upload-handler";
+
+// components
+export { EditorContainer } from "src/ui/components/editor-container";
+export { EditorContentWrapper } from "src/ui/components/editor-content";
+
+// hooks
+export { useEditor } from "src/hooks/use-editor";
+export { useReadOnlyEditor } from "src/hooks/use-read-only-editor";
+
+// helper items
+export * from "src/ui/menus/menu-items";
+export * from "src/lib/editor-commands";
+
+// types
+export type { CustomEditorProps, TFileHandler } from "src/hooks/use-editor";
+export type { DeleteImage } from "src/types/delete-image";
+export type { UploadImage } from "src/types/upload-image";
+export type { EditorRefApi, EditorReadOnlyRefApi } from "src/types/editor-ref-api";
+export type { RestoreImage } from "src/types/restore-image";
+export type { IMentionHighlight, IMentionSuggestion } from "src/types/mention-suggestion";
+export type { ISlashCommandItem, CommandProps } from "src/types/slash-commands-suggestion";
+export type { LucideIconType } from "src/types/lucide-icon";
diff --git a/packages/editor/core/src/lib/editor-commands.ts b/packages/editor/core/src/lib/editor-commands.ts
new file mode 100644
index 0000000..53e20b3
--- /dev/null
+++ b/packages/editor/core/src/lib/editor-commands.ts
@@ -0,0 +1,154 @@
+import type { Editor, Range } from "@tiptap/core";
+import { startImageUpload } from "@/ui/plugins/image/image-upload-handler";
+import { findTableAncestor } from "@/lib/utils";
+import type { Selection } from "@tiptap/pm/state";
+import type { UploadImage } from "@/types/upload-image";
+import { replaceCodeWithText } from "@/ui/extensions/code/utils/replace-code-block-with-text";
+
+export const setText = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).clearNodes().run();
+ else editor.chain().focus().clearNodes().run();
+};
+
+export const toggleHeadingOne = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 1 }).run();
+ else editor.chain().focus().toggleHeading({ level: 1 }).run();
+};
+
+export const toggleHeadingTwo = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 2 }).run();
+ else editor.chain().focus().toggleHeading({ level: 2 }).run();
+};
+
+export const toggleHeadingThree = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 3 }).run();
+ else editor.chain().focus().toggleHeading({ level: 3 }).run();
+};
+
+export const toggleHeadingFour = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 4 }).run();
+ else editor.chain().focus().toggleHeading({ level: 4 }).run();
+};
+
+export const toggleHeadingFive = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 5 }).run();
+ else editor.chain().focus().toggleHeading({ level: 5 }).run();
+};
+
+export const toggleHeadingSix = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).setNode("heading", { level: 6 }).run();
+ else editor.chain().focus().toggleHeading({ level: 6 }).run();
+};
+
+export const toggleBold = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).toggleBold().run();
+ else editor.chain().focus().toggleBold().run();
+};
+
+export const toggleItalic = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).toggleItalic().run();
+ else editor.chain().focus().toggleItalic().run();
+};
+
+export const toggleUnderline = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).toggleUnderline().run();
+ else editor.chain().focus().toggleUnderline().run();
+};
+
+export const toggleCodeBlock = (editor: Editor, range?: Range) => {
+ try {
+ // if it's a code block, replace it with the code with paragraphs
+ if (editor.isActive("codeBlock")) {
+ replaceCodeWithText(editor);
+ return;
+ }
+
+ const { from, to } = range || editor.state.selection;
+ const text = editor.state.doc.textBetween(from, to, "\n");
+ const isMultiline = text.includes("\n");
+
+ // if the selection is not a range i.e. empty, then simply convert it into a code block
+ if (editor.state.selection.empty) {
+ editor.chain().focus().toggleCodeBlock().run();
+ } else if (isMultiline) {
+ // if the selection is multiline, then also replace the text content with
+ // a code block
+ editor.chain().focus().deleteRange({ from, to }).insertContentAt(from, `\`\`\`\n${text}\n\`\`\``).run();
+ } else {
+ // if the selection is single line, then simply convert it into inline
+ // code
+ editor.chain().focus().toggleCode().run();
+ }
+ } catch (error) {
+ console.error("An error occurred while toggling code block:", error);
+ }
+};
+
+export const toggleOrderedList = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).toggleOrderedList().run();
+ else editor.chain().focus().toggleOrderedList().run();
+};
+
+export const toggleBulletList = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).toggleBulletList().run();
+ else editor.chain().focus().toggleBulletList().run();
+};
+
+export const toggleTaskList = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).toggleTaskList().run();
+ else editor.chain().focus().toggleTaskList().run();
+};
+
+export const toggleStrike = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).toggleStrike().run();
+ else editor.chain().focus().toggleStrike().run();
+};
+
+export const toggleBlockquote = (editor: Editor, range?: Range) => {
+ if (range) editor.chain().focus().deleteRange(range).toggleBlockquote().run();
+ else editor.chain().focus().toggleBlockquote().run();
+};
+
+export const insertTableCommand = (editor: Editor, range?: Range) => {
+ if (typeof window !== "undefined") {
+ const selection = window.getSelection();
+ if (selection) {
+ if (selection.rangeCount !== 0) {
+ const range = selection.getRangeAt(0);
+ if (findTableAncestor(range.startContainer)) {
+ return;
+ }
+ }
+ }
+ }
+ if (range) editor.chain().focus().deleteRange(range).clearNodes().insertTable({ rows: 3, cols: 3 }).run();
+ else editor.chain().focus().clearNodes().insertTable({ rows: 3, cols: 3 }).run();
+};
+
+export const unsetLinkEditor = (editor: Editor) => {
+ editor.chain().focus().unsetLink().run();
+};
+
+export const setLinkEditor = (editor: Editor, url: string) => {
+ editor.chain().focus().setLink({ href: url }).run();
+};
+
+export const insertImageCommand = (
+ editor: Editor,
+ uploadFile: UploadImage,
+ savedSelection?: Selection | null,
+ range?: Range
+) => {
+ if (range) editor.chain().focus().deleteRange(range).run();
+ const input = document.createElement("input");
+ input.type = "file";
+ input.accept = ".jpeg, .jpg, .png, .webp, .svg";
+ input.onchange = async () => {
+ if (input.files?.length) {
+ const file = input.files[0] as File;
+ const pos = savedSelection?.anchor ?? editor.view.state.selection.from;
+ startImageUpload(editor, file, editor.view, pos, uploadFile);
+ }
+ };
+ input.click();
+};
diff --git a/packages/editor/core/src/lib/utils.ts b/packages/editor/core/src/lib/utils.ts
new file mode 100644
index 0000000..137c70c
--- /dev/null
+++ b/packages/editor/core/src/lib/utils.ts
@@ -0,0 +1,79 @@
+import { Extensions, generateJSON, getSchema } from "@tiptap/core";
+import { Selection } from "@tiptap/pm/state";
+import { clsx, type ClassValue } from "clsx";
+import { CoreEditorExtensionsWithoutProps } from "src/ui/extensions/core-without-props";
+import { twMerge } from "tailwind-merge";
+interface EditorClassNames {
+ noBorder?: boolean;
+ borderOnFocus?: boolean;
+ containerClassName?: string;
+}
+
+export const getEditorClassNames = ({ noBorder, borderOnFocus, containerClassName }: EditorClassNames) =>
+ cn(
+ "w-full max-w-full sm:rounded-lg focus:outline-none focus:border-0",
+ {
+ "border border-custom-border-200": !noBorder,
+ "focus:border border-custom-border-300": borderOnFocus,
+ },
+ containerClassName
+ );
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
+
+// Helper function to find the parent node of a specific type
+export function findParentNodeOfType(selection: Selection, typeName: string) {
+ let depth = selection.$anchor.depth;
+ while (depth > 0) {
+ const node = selection.$anchor.node(depth);
+ if (node.type.name === typeName) {
+ return { node, pos: selection.$anchor.start(depth) - 1 };
+ }
+ depth--;
+ }
+ return null;
+}
+
+export const findTableAncestor = (node: Node | null): HTMLTableElement | null => {
+ while (node !== null && node.nodeName !== "TABLE") {
+ node = node.parentNode;
+ }
+ return node as HTMLTableElement;
+};
+
+export const getTrimmedHTML = (html: string) => {
+ html = html.replace(/^(<\/p>)+/, "");
+ html = html.replace(/(
<\/p>)+$/, "");
+ return html;
+};
+
+export const isValidHttpUrl = (string: string): boolean => {
+ let url: URL;
+
+ try {
+ url = new URL(string);
+ } catch (_) {
+ return false;
+ }
+
+ return url.protocol === "http:" || url.protocol === "https:";
+};
+
+/**
+ * @description return an object with contentJSON and editorSchema
+ * @description contentJSON- ProseMirror JSON from HTML content
+ * @description editorSchema- editor schema from extensions
+ * @param {string} html
+ * @returns {object} {contentJSON, editorSchema}
+ */
+export const generateJSONfromHTML = (html: string) => {
+ const extensions = CoreEditorExtensionsWithoutProps();
+ const contentJSON = generateJSON(html ?? "
", extensions as Extensions);
+ const editorSchema = getSchema(extensions as Extensions);
+ return {
+ contentJSON,
+ editorSchema,
+ };
+};
diff --git a/packages/editor/core/src/styles/editor.css b/packages/editor/core/src/styles/editor.css
new file mode 100644
index 0000000..f76b6b1
--- /dev/null
+++ b/packages/editor/core/src/styles/editor.css
@@ -0,0 +1,401 @@
+.ProseMirror {
+ --font-size-h1: 1.5rem;
+ --font-size-h2: 1.3125rem;
+ --font-size-h3: 1.125rem;
+ --font-size-h4: 0.9375rem;
+ --font-size-h5: 0.8125rem;
+ --font-size-h6: 0.75rem;
+ --font-size-regular: 0.9375rem;
+ --font-size-list: var(--font-size-regular);
+}
+
+.ProseMirror p.is-editor-empty:first-child::before {
+ content: attr(data-placeholder);
+ float: left;
+ color: rgb(var(--color-text-400));
+ pointer-events: none;
+ height: 0;
+}
+
+/* block quotes */
+.ProseMirror blockquote {
+ font-style: normal;
+ font-weight: 400;
+ border-left: 3px solid rgb(var(--color-border-300));
+}
+
+.ProseMirror blockquote p::before,
+.ProseMirror blockquote p::after {
+ display: none;
+}
+/* end block quotes */
+
+.ProseMirror code::before,
+.ProseMirror code::after {
+ display: none;
+}
+
+.ProseMirror .is-empty::before {
+ content: attr(data-placeholder);
+ float: left;
+ color: rgb(var(--color-text-400));
+ pointer-events: none;
+ height: 0;
+}
+
+/* Custom image styles */
+.ProseMirror img {
+ transition: filter 0.1s ease-in-out;
+ margin-top: 8px;
+ margin-bottom: 0;
+
+ &:hover {
+ cursor: pointer;
+ filter: brightness(90%);
+ }
+
+ &.ProseMirror-selectednode {
+ outline: 3px solid rgba(var(--color-primary-100));
+ filter: brightness(90%);
+ }
+}
+
+/* Custom gap cursor styles */
+.ProseMirror-gapcursor::after {
+ border-top: 1px solid rgb(var(--color-text-100)) !important;
+}
+
+/* to-do list */
+ul[data-type="taskList"] li {
+ font-size: var(--font-size-list);
+ line-height: 1.5;
+}
+
+ul[data-type="taskList"] li > label {
+ position: absolute;
+ left: -5px;
+ margin: 0.1rem 0.15rem 0 0;
+ user-select: none;
+}
+
+ul[data-type="taskList"] li > div {
+ margin-left: 1.15rem;
+}
+
+ul[data-type="taskList"] li > label input[type="checkbox"] {
+ border: 1px solid rgba(var(--color-border-300)) !important;
+ outline: none;
+ border-radius: 2px;
+ transform: scale(1.05);
+}
+
+ul[data-type="taskList"] li > label input[type="checkbox"]:hover {
+ background-color: rgba(var(--color-background-80)) !important;
+}
+
+ul[data-type="taskList"] li > label input[type="checkbox"]:checked {
+ background-color: rgba(var(--color-primary-100)) !important;
+ border-color: rgba(var(--color-primary-100)) !important;
+ color: white !important;
+}
+
+ul[data-type="taskList"] li > label input[type="checkbox"]:checked:hover {
+ background-color: rgba(var(--color-primary-300)) !important;
+ border-color: rgba(var(--color-primary-300)) !important;
+}
+
+@media screen and (max-width: 768px) {
+ ul[data-type="taskList"] li > label {
+ margin-right: 0.5rem;
+ }
+}
+
+/* the p tag just after the ul tag */
+ul[data-type="taskList"] + p {
+ margin-top: 0.4rem !important;
+}
+
+ul[data-type="taskList"] li > label input[type="checkbox"] {
+ position: relative;
+ -webkit-appearance: none;
+ appearance: none;
+ background-color: rgb(var(--color-background-100));
+ margin: 0;
+ cursor: pointer;
+ width: 0.8rem;
+ height: 0.8rem;
+ position: relative;
+ border: 1.5px solid rgb(var(--color-text-100));
+ margin-right: 0.2rem;
+ margin-top: 0.15rem;
+
+ &:hover {
+ background-color: rgb(var(--color-background-80));
+ }
+
+ &:active {
+ background-color: rgb(var(--color-background-90));
+ }
+
+ /* check sign */
+ &::before {
+ content: "";
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 0.5em;
+ height: 0.5em;
+ transform: scale(0);
+ transform-origin: center;
+ transition: 120ms transform ease-in-out;
+ box-shadow: inset 1em 1em;
+ clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
+ }
+
+ &:checked::before {
+ transform: scale(1) translate(-50%, -50%);
+ }
+}
+
+ul[data-type="taskList"] li > div > p {
+ margin-top: 10px;
+}
+
+ul[data-type="taskList"] li[data-checked="true"] > div > p {
+ color: rgb(var(--color-text-400));
+ text-decoration: line-through;
+ text-decoration-thickness: 2px;
+}
+/* end to-do list */
+
+/* Overwrite tippy-box original max-width */
+
+.tippy-box {
+ max-width: 400px !important;
+}
+
+.ProseMirror {
+ position: relative;
+ word-wrap: break-word;
+ white-space: pre-wrap;
+ -moz-tab-size: 4;
+ tab-size: 4;
+ -webkit-user-select: text;
+ -moz-user-select: text;
+ -ms-user-select: text;
+ user-select: text;
+ outline: none;
+ cursor: text;
+ line-height: 1.2;
+ font-family: inherit;
+ font-size: var(--font-size-regular);
+ color: inherit;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ appearance: textfield;
+ -webkit-appearance: textfield;
+ -moz-appearance: textfield;
+}
+
+.fade-in {
+ opacity: 1;
+ transition: opacity 0.3s ease-in;
+}
+
+.fade-out {
+ opacity: 0;
+ transition: opacity 0.2s ease-out;
+}
+
+.img-placeholder {
+ position: relative;
+ width: 35%;
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+
+ &::before {
+ content: "";
+ box-sizing: border-box;
+ position: absolute;
+ top: 50%;
+ left: 45%;
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ border: 3px solid rgba(var(--color-text-200));
+ border-top-color: rgba(var(--color-text-800));
+ animation: spinning 0.6s linear infinite;
+ }
+}
+
+@keyframes spinning {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.resize-cursor {
+ cursor: ew-resize;
+ cursor: col-resize;
+}
+
+.ProseMirror table * .is-empty::before {
+ opacity: 0;
+}
+
+.ProseMirror pre {
+ font-family: JetBrainsMono, monospace;
+ tab-size: 2;
+}
+
+.ProseMirror pre code {
+ background: none;
+ color: inherit;
+ font-size: 0.8rem;
+ padding: 0;
+}
+
+div[data-type="horizontalRule"] {
+ line-height: 0;
+ padding: 0.25rem 0;
+ margin-top: 0;
+ margin-bottom: 0;
+
+ & > div {
+ border-bottom: 2px solid rgb(var(--color-border-200));
+ }
+}
+
+/* image resizer */
+.moveable-control-box {
+ z-index: 10 !important;
+}
+
+/* Cursor styles for the inline code blocks */
+@keyframes blink {
+ 49% {
+ border-color: unset;
+ }
+
+ 50% {
+ border-color: transparent;
+ }
+
+ 99% {
+ border-color: transparent;
+ }
+}
+
+.no-cursor {
+ caret-color: transparent;
+}
+
+div:focus .fake-cursor,
+span:focus .fake-cursor {
+ margin-right: -1px;
+ border-left-width: 1.5px;
+ border-left-style: solid;
+ animation: blink 1s;
+ animation-iteration-count: infinite;
+ position: relative;
+ z-index: 1;
+}
+
+/* numbered, bulleted and to-do lists spacing */
+.prose ol:where(.prose > :first-child):not(:where([class~="not-prose"], [class~="not-prose"] *)),
+.prose
+ ul:not([data-type="taskList"]):where(.prose > :first-child):not(:where([class~="not-prose"], [class~="not-prose"] *)),
+.prose ul[data-type="taskList"]:where(.prose > :first-child) {
+ margin-top: 0.25rem !important;
+ margin-bottom: 1px !important;
+}
+
+.prose ol:not(:where(.prose > :first-child):not(:where([class~="not-prose"], [class~="not-prose"] *))),
+.prose
+ ul:not([data-type="taskList"]):not(
+ :where(.prose > :first-child):not(:where([class~="not-prose"], [class~="not-prose"] *))
+ ),
+.prose ul[data-type="taskList"]:not(:where(.prose > :first-child)) {
+ margin-top: calc(0.25rem + 3px) !important;
+ margin-bottom: 1px !important;
+}
+
+ol ol,
+ol ul:not([data-type="taskList"]),
+ul:not([data-type="taskList"]) ul:not([data-type="taskList"]),
+ul:not([data-type="taskList"]) ol {
+ margin-top: 0.45rem !important;
+}
+
+ul[data-type="taskList"] ul[data-type="taskList"] {
+ margin-top: 0.6rem;
+}
+/* end numbered, bulleted and to-do lists spacing */
+
+/* tailwind typography */
+.prose :where(h1):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
+ margin-top: 2rem;
+ margin-bottom: 4px;
+ font-size: var(--font-size-h1);
+ font-weight: 600;
+ line-height: 1.3;
+}
+
+.prose :where(h2):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
+ margin-top: 1.4rem;
+ margin-bottom: 1px;
+ font-size: var(--font-size-h2);
+ font-weight: 600;
+ line-height: 1.3;
+}
+
+.prose :where(h3):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
+ margin-top: 1rem;
+ margin-bottom: 1px;
+ font-size: var(--font-size-h3);
+ font-weight: 600;
+ line-height: 1.3;
+}
+
+.prose :where(h4):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
+ margin-top: 1rem;
+ margin-bottom: 1px;
+ font-size: var(--font-size-h4);
+ font-weight: 600;
+ line-height: 1.5;
+}
+
+.prose :where(h5):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
+ margin-top: 1rem;
+ margin-bottom: 1px;
+ font-size: var(--font-size-h5);
+ font-weight: 600;
+ line-height: 1.5;
+}
+
+.prose :where(h6):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
+ margin-top: 1rem;
+ margin-bottom: 1px;
+ font-size: var(--font-size-h6);
+ font-weight: 600;
+ line-height: 1.5;
+}
+
+.prose :where(p):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
+ margin-top: 0.25rem;
+ margin-bottom: 1px;
+ padding: 3px 0;
+ font-size: var(--font-size-regular);
+ line-height: 1.5;
+}
+
+.prose :where(ol):not(:where([class~="not-prose"], [class~="not-prose"] *)) li p,
+.prose :where(ul):not(:where([class~="not-prose"], [class~="not-prose"] *)) li p {
+ font-size: var(--font-size-list);
+ line-height: 1.5;
+}
+
+.prose :where(.prose > :first-child):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
+ margin-top: 0;
+}
+/* end tailwind typography */
diff --git a/packages/editor/core/src/styles/github-dark.css b/packages/editor/core/src/styles/github-dark.css
new file mode 100644
index 0000000..9374de4
--- /dev/null
+++ b/packages/editor/core/src/styles/github-dark.css
@@ -0,0 +1,85 @@
+pre code.hljs {
+ display: block;
+ overflow-x: auto;
+ padding: 1em;
+}
+code.hljs {
+ padding: 3px 5px;
+}
+.hljs {
+ color: #c9d1d9;
+ background: #0d1117;
+}
+.hljs-doctag,
+.hljs-keyword,
+.hljs-meta .hljs-keyword,
+.hljs-template-tag,
+.hljs-template-variable,
+.hljs-type,
+.hljs-variable.language_ {
+ color: #ff7b72;
+}
+.hljs-title,
+.hljs-title.class_,
+.hljs-title.class_.inherited__,
+.hljs-title.function_ {
+ color: #d2a8ff;
+}
+.hljs-attr,
+.hljs-attribute,
+.hljs-literal,
+.hljs-meta,
+.hljs-number,
+.hljs-operator,
+.hljs-selector-attr,
+.hljs-selector-class,
+.hljs-selector-id,
+.hljs-variable {
+ color: #79c0ff;
+}
+.hljs-meta .hljs-string,
+.hljs-regexp,
+.hljs-string {
+ color: #a5d6ff;
+}
+.hljs-built_in,
+.hljs-symbol {
+ color: #ffa657;
+}
+.hljs-code,
+.hljs-comment,
+.hljs-formula {
+ color: #8b949e;
+}
+.hljs-name,
+.hljs-quote,
+.hljs-selector-pseudo,
+.hljs-selector-tag {
+ color: #7ee787;
+}
+.hljs-subst {
+ color: #c9d1d9;
+}
+.hljs-section {
+ color: #1f6feb;
+ font-weight: 700;
+}
+.hljs-bullet {
+ color: #f2cc60;
+}
+.hljs-emphasis {
+ color: #c9d1d9;
+ font-style: italic;
+}
+.hljs-strong {
+ color: #c9d1d9;
+ font-weight: 700;
+}
+.hljs-addition {
+ color: #aff5b4;
+ background-color: #033a16;
+}
+.hljs-deletion {
+ color: #ffdcd7;
+ background-color: #67060c;
+}
diff --git a/packages/editor/core/src/styles/table.css b/packages/editor/core/src/styles/table.css
new file mode 100644
index 0000000..d5adac9
--- /dev/null
+++ b/packages/editor/core/src/styles/table.css
@@ -0,0 +1,116 @@
+.table-wrapper {
+ overflow-x: auto;
+ width: fit-content;
+ max-width: 100%;
+}
+
+.table-wrapper table {
+ border-collapse: collapse;
+ table-layout: fixed;
+ margin: 0.5rem 0 1rem 0;
+ border: 1px solid rgba(var(--color-border-200));
+ width: 100%;
+}
+
+.table-wrapper table p {
+ font-size: 14px;
+}
+
+.table-wrapper table td,
+.table-wrapper table th {
+ min-width: 1em;
+ border: 1px solid rgba(var(--color-border-200));
+ padding: 10px 15px;
+ vertical-align: top;
+ box-sizing: border-box;
+ position: relative;
+ transition: background-color 0.3s ease;
+
+ > * {
+ margin-bottom: 0;
+ }
+}
+
+.table-wrapper table th {
+ font-weight: 500;
+ text-align: left;
+ background-color: rgba(var(--color-background-90));
+}
+
+.table-wrapper table .selectedCell {
+ outline: 0.5px solid rgba(var(--color-primary-100));
+}
+
+/* table dropdown */
+.table-wrapper table .column-resize-handle {
+ position: absolute;
+ right: -2px;
+ top: 0;
+ width: 2px;
+ height: 100%;
+ z-index: 5;
+ background-color: rgba(var(--color-primary-100));
+ pointer-events: none;
+}
+
+.table-wrapper .table-controls {
+ position: absolute;
+}
+
+.table-wrapper .table-controls .columns-control,
+.table-wrapper .table-controls .rows-control {
+ transition: opacity ease-in 100ms;
+ position: absolute;
+ z-index: 5;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.table-wrapper .table-controls .columns-control {
+ height: 20px;
+ transform: translateY(-50%);
+}
+
+.table-wrapper .table-controls .columns-control .columns-control-div {
+ color: white;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath fill='%238F95B2' d='M4.5 10.5c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5S6 12.825 6 12s-.675-1.5-1.5-1.5zm15 0c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5S21 12.825 21 12s-.675-1.5-1.5-1.5zm-7.5 0c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5 1.5-.675 1.5-1.5-.675-1.5-1.5-1.5z'/%3E%3C/svg%3E");
+ width: 30px;
+ height: 15px;
+}
+
+.table-wrapper .table-controls .rows-control {
+ width: 20px;
+ transform: translateX(-50%);
+}
+
+.table-wrapper .table-controls .rows-control .rows-control-div {
+ color: white;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath fill='%238F95B2' d='M12 3c-.825 0-1.5.675-1.5 1.5S11.175 6 12 6s1.5-.675 1.5-1.5S12.825 3 12 3zm0 15c-.825 0-1.5.675-1.5 1.5S11.175 21 12 21s1.5-.675 1.5-1.5S12.825 18 12 18zm0-7.5c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5 1.5-.675 1.5-1.5-.675-1.5-1.5-1.5z'/%3E%3C/svg%3E");
+ height: 30px;
+ width: 15px;
+}
+
+.table-wrapper .table-controls .rows-control-div,
+.table-wrapper .table-controls .columns-control-div {
+ background-color: rgba(var(--color-background-80));
+ border: 0.5px solid rgba(var(--color-border-200));
+ border-radius: 4px;
+ background-size: 1.25rem;
+ background-repeat: no-repeat;
+ background-position: center;
+ transition:
+ transform ease-out 100ms,
+ background-color ease-out 100ms;
+ outline: none;
+ box-shadow: rgba(var(--color-shadow-2xs));
+ cursor: pointer;
+}
+
+.resize-cursor .table-wrapper .table-controls .rows-control,
+.table-wrapper.controls--disabled .table-controls .rows-control,
+.resize-cursor .table-wrapper .table-controls .columns-control,
+.table-wrapper.controls--disabled .table-controls .columns-control {
+ opacity: 0;
+ pointer-events: none;
+}
diff --git a/packages/editor/core/src/styles/tailwind.css b/packages/editor/core/src/styles/tailwind.css
new file mode 100644
index 0000000..b5c61c9
--- /dev/null
+++ b/packages/editor/core/src/styles/tailwind.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/packages/editor/core/src/types/delete-image.ts b/packages/editor/core/src/types/delete-image.ts
new file mode 100644
index 0000000..40bfffe
--- /dev/null
+++ b/packages/editor/core/src/types/delete-image.ts
@@ -0,0 +1 @@
+export type DeleteImage = (assetUrlWithWorkspaceId: string) => Promise;
diff --git a/packages/editor/core/src/types/editor-ref-api.ts b/packages/editor/core/src/types/editor-ref-api.ts
new file mode 100644
index 0000000..b15ae94
--- /dev/null
+++ b/packages/editor/core/src/types/editor-ref-api.ts
@@ -0,0 +1,19 @@
+import { IMarking } from "src/helpers/scroll-to-node";
+import { EditorMenuItemNames } from "src/ui/menus/menu-items";
+
+export type EditorReadOnlyRefApi = {
+ getMarkDown: () => string;
+ getHTML: () => string;
+ clearEditor: () => void;
+ setEditorValue: (content: string) => void;
+ scrollSummary: (marking: IMarking) => void;
+};
+
+export interface EditorRefApi extends EditorReadOnlyRefApi {
+ setEditorValueAtCursorPosition: (content: string) => void;
+ executeMenuItemCommand: (itemName: EditorMenuItemNames) => void;
+ isMenuItemActive: (itemName: EditorMenuItemNames) => boolean;
+ onStateChange: (callback: () => void) => () => void;
+ setFocusAtPosition: (position: number) => void;
+ isEditorReadyToDiscard: () => boolean;
+}
diff --git a/packages/editor/core/src/types/lucide-icon.ts b/packages/editor/core/src/types/lucide-icon.ts
new file mode 100644
index 0000000..2211c18
--- /dev/null
+++ b/packages/editor/core/src/types/lucide-icon.ts
@@ -0,0 +1,3 @@
+import { Smile } from "lucide-react";
+
+export type LucideIconType = typeof Smile;
diff --git a/packages/editor/core/src/types/mention-suggestion.ts b/packages/editor/core/src/types/mention-suggestion.ts
new file mode 100644
index 0000000..53377bd
--- /dev/null
+++ b/packages/editor/core/src/types/mention-suggestion.ts
@@ -0,0 +1,18 @@
+import type { Editor, Range } from "@tiptap/react";
+export type IMentionSuggestion = {
+ id: string;
+ type: string;
+ entity_name: string;
+ entity_identifier: string;
+ avatar: string;
+ title: string;
+ subtitle: string;
+ redirect_uri: string;
+};
+
+export type CommandProps = {
+ editor: Editor;
+ range: Range;
+};
+
+export type IMentionHighlight = string;
diff --git a/packages/editor/core/src/types/restore-image.ts b/packages/editor/core/src/types/restore-image.ts
new file mode 100644
index 0000000..9b33177
--- /dev/null
+++ b/packages/editor/core/src/types/restore-image.ts
@@ -0,0 +1 @@
+export type RestoreImage = (assetUrlWithWorkspaceId: string) => Promise;
diff --git a/packages/editor/core/src/types/slash-commands-suggestion.ts b/packages/editor/core/src/types/slash-commands-suggestion.ts
new file mode 100644
index 0000000..34e4510
--- /dev/null
+++ b/packages/editor/core/src/types/slash-commands-suggestion.ts
@@ -0,0 +1,16 @@
+import { ReactNode } from "react";
+import { Editor, Range } from "@tiptap/core";
+
+export type CommandProps = {
+ editor: Editor;
+ range: Range;
+};
+
+export type ISlashCommandItem = {
+ key: string;
+ title: string;
+ description: string;
+ searchTerms: string[];
+ icon: ReactNode;
+ command: ({ editor, range }: CommandProps) => void;
+};
diff --git a/packages/editor/core/src/types/upload-image.ts b/packages/editor/core/src/types/upload-image.ts
new file mode 100644
index 0000000..3cf1408
--- /dev/null
+++ b/packages/editor/core/src/types/upload-image.ts
@@ -0,0 +1 @@
+export type UploadImage = (file: File) => Promise;
diff --git a/packages/editor/core/src/ui/components/editor-container.tsx b/packages/editor/core/src/ui/components/editor-container.tsx
new file mode 100644
index 0000000..cfa80da
--- /dev/null
+++ b/packages/editor/core/src/ui/components/editor-container.tsx
@@ -0,0 +1,70 @@
+import { Editor } from "@tiptap/react";
+import { FC, ReactNode } from "react";
+import { cn } from "src/lib/utils";
+
+interface EditorContainerProps {
+ editor: Editor | null;
+ editorContainerClassName: string;
+ children: ReactNode;
+ hideDragHandle?: () => void;
+}
+
+export const EditorContainer: FC = (props) => {
+ const { editor, editorContainerClassName, hideDragHandle, children } = props;
+
+ const handleContainerClick = () => {
+ if (!editor) return;
+ if (!editor.isEditable) return;
+ try {
+ if (editor.isFocused) return; // If editor is already focused, do nothing
+
+ const { selection } = editor.state;
+ const currentNode = selection.$from.node();
+
+ editor?.chain().focus("end", { scrollIntoView: false }).run(); // Focus the editor at the end
+
+ if (
+ currentNode.content.size === 0 && // Check if the current node is empty
+ !(
+ editor.isActive("orderedList") ||
+ editor.isActive("bulletList") ||
+ editor.isActive("taskItem") ||
+ editor.isActive("table") ||
+ editor.isActive("blockquote") ||
+ editor.isActive("codeBlock")
+ ) // Check if it's an empty node within an orderedList, bulletList, taskItem, table, quote or code block
+ ) {
+ return;
+ }
+
+ // Insert a new paragraph at the end of the document
+ const endPosition = editor?.state.doc.content.size;
+ editor?.chain().insertContentAt(endPosition, { type: "paragraph" }).run();
+
+ // Focus the newly added paragraph for immediate editing
+ editor
+ .chain()
+ .setTextSelection(endPosition + 1)
+ .run();
+ } catch (error) {
+ console.error("An error occurred while handling container click to insert new empty node at bottom:", error);
+ }
+ };
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/packages/editor/core/src/ui/components/editor-content.tsx b/packages/editor/core/src/ui/components/editor-content.tsx
new file mode 100644
index 0000000..a242726
--- /dev/null
+++ b/packages/editor/core/src/ui/components/editor-content.tsx
@@ -0,0 +1,21 @@
+import { Editor, EditorContent } from "@tiptap/react";
+import { FC, ReactNode } from "react";
+import { ImageResizer } from "src/ui/extensions/image/image-resize";
+
+interface EditorContentProps {
+ editor: Editor | null;
+ children?: ReactNode;
+ tabIndex?: number;
+}
+
+export const EditorContentWrapper: FC = (props) => {
+ const { editor, tabIndex, children } = props;
+
+ return (
+ editor?.chain().focus(undefined, { scrollIntoView: false }).run()}>
+
+ {editor?.isActive("image") && editor?.isEditable && }
+ {children}
+
+ );
+};
diff --git a/packages/editor/core/src/ui/extensions/code-inline/index.tsx b/packages/editor/core/src/ui/extensions/code-inline/index.tsx
new file mode 100644
index 0000000..60a1236
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/code-inline/index.tsx
@@ -0,0 +1,96 @@
+import { Mark, markInputRule, markPasteRule, mergeAttributes } from "@tiptap/core";
+
+export interface CodeOptions {
+ HTMLAttributes: Record;
+}
+
+declare module "@tiptap/core" {
+ interface Commands {
+ code: {
+ /**
+ * Set a code mark
+ */
+ setCode: () => ReturnType;
+ /**
+ * Toggle inline code
+ */
+ toggleCode: () => ReturnType;
+ /**
+ * Unset a code mark
+ */
+ unsetCode: () => ReturnType;
+ };
+ }
+}
+
+export const inputRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))$/;
+export const pasteRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))/g;
+
+export const CustomCodeInlineExtension = Mark.create({
+ name: "code",
+
+ addOptions() {
+ return {
+ HTMLAttributes: {
+ class:
+ "rounded bg-custom-background-80 px-1 py-[2px] font-mono font-medium text-orange-500 border-[0.5px] border-custom-border-200",
+ spellcheck: "false",
+ },
+ };
+ },
+
+ excludes: "_",
+
+ code: true,
+
+ exitable: true,
+
+ parseHTML() {
+ return [{ tag: "code" }];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return ["code", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
+ },
+
+ addCommands() {
+ return {
+ setCode:
+ () =>
+ ({ commands }) =>
+ commands.setMark(this.name),
+ toggleCode:
+ () =>
+ ({ commands }) =>
+ commands.toggleMark(this.name),
+ unsetCode:
+ () =>
+ ({ commands }) =>
+ commands.unsetMark(this.name),
+ };
+ },
+
+ addKeyboardShortcuts() {
+ return {
+ "Mod-e": () => this.editor.commands.toggleCode(),
+ };
+ },
+
+ addInputRules() {
+ return [
+ markInputRule({
+ find: inputRegex,
+ type: this.type,
+ }),
+ ];
+ },
+
+ addPasteRules() {
+ return [
+ markPasteRule({
+ find: pasteRegex,
+ type: this.type,
+ }),
+ ];
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/code/code-block-lowlight.ts b/packages/editor/core/src/ui/extensions/code/code-block-lowlight.ts
new file mode 100644
index 0000000..ae44d83
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/code/code-block-lowlight.ts
@@ -0,0 +1,30 @@
+// import CodeBlock, { CodeBlockOptions } from "@tiptap/extension-code-block";
+
+import { CodeBlockOptions, CodeBlock } from "./code-block";
+import { LowlightPlugin } from "./lowlight-plugin";
+
+export interface CodeBlockLowlightOptions extends CodeBlockOptions {
+ lowlight: any;
+ defaultLanguage: string | null | undefined;
+}
+
+export const CodeBlockLowlight = CodeBlock.extend({
+ addOptions() {
+ return {
+ ...this.parent?.(),
+ lowlight: {},
+ defaultLanguage: null,
+ };
+ },
+
+ addProseMirrorPlugins() {
+ return [
+ ...(this.parent?.() || []),
+ LowlightPlugin({
+ name: this.name,
+ lowlight: this.options.lowlight,
+ defaultLanguage: this.options.defaultLanguage,
+ }),
+ ];
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/code/code-block-node-view.tsx b/packages/editor/core/src/ui/extensions/code/code-block-node-view.tsx
new file mode 100644
index 0000000..1d2cd09
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/code/code-block-node-view.tsx
@@ -0,0 +1,59 @@
+import { useState } from "react";
+import { NodeViewWrapper, NodeViewContent } from "@tiptap/react";
+import { common, createLowlight } from "lowlight";
+import ts from "highlight.js/lib/languages/typescript";
+import { CopyIcon, CheckIcon } from "lucide-react";
+import { Node as ProseMirrorNode } from "@tiptap/pm/model";
+import { cn } from "src/lib/utils";
+import { Tooltip } from "@prodkt/ui/primitives";
+
+// we just have ts support for now
+const lowlight = createLowlight(common);
+lowlight.register("ts", ts);
+
+interface CodeBlockComponentProps {
+ node: ProseMirrorNode;
+}
+
+export const CodeBlockComponent: React.FC = ({ node }) => {
+ const [copied, setCopied] = useState(false);
+
+ const copyToClipboard = async (e: React.MouseEvent) => {
+ try {
+ await navigator.clipboard.writeText(node.textContent);
+ setCopied(true);
+ setTimeout(() => setCopied(false), 1000);
+ } catch (error) {
+ setCopied(false);
+ }
+ e.preventDefault();
+ e.stopPropagation();
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/packages/editor/core/src/ui/extensions/code/code-block.ts b/packages/editor/core/src/ui/extensions/code/code-block.ts
new file mode 100644
index 0000000..b2218ee
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/code/code-block.ts
@@ -0,0 +1,346 @@
+import { mergeAttributes, Node, textblockTypeInputRule } from "@tiptap/core";
+import { Plugin, PluginKey } from "@tiptap/pm/state";
+
+export interface CodeBlockOptions {
+ /**
+ * Adds a prefix to language classes that are applied to code tags.
+ * Defaults to `'language-'`.
+ */
+ languageClassPrefix: string;
+ /**
+ * Define whether the node should be exited on triple enter.
+ * Defaults to `true`.
+ */
+ exitOnTripleEnter: boolean;
+ /**
+ * Define whether the node should be exited on arrow down if there is no node after it.
+ * Defaults to `true`.
+ */
+ exitOnArrowDown: boolean;
+ /**
+ * Custom HTML attributes that should be added to the rendered HTML tag.
+ */
+ HTMLAttributes: Record;
+}
+
+declare module "@tiptap/core" {
+ interface Commands {
+ codeBlock: {
+ /**
+ * Set a code block
+ */
+ setCodeBlock: (attributes?: { language: string }) => ReturnType;
+ /**
+ * Toggle a code block
+ */
+ toggleCodeBlock: (attributes?: { language: string }) => ReturnType;
+ };
+ }
+}
+
+export const backtickInputRegex = /^```([a-z]+)?[\s\n]$/;
+export const tildeInputRegex = /^~~~([a-z]+)?[\s\n]$/;
+
+export const CodeBlock = Node.create({
+ name: "codeBlock",
+
+ addOptions() {
+ return {
+ languageClassPrefix: "language-",
+ exitOnTripleEnter: true,
+ exitOnArrowDown: true,
+ HTMLAttributes: {},
+ };
+ },
+ content: "text*",
+
+ marks: "",
+
+ group: "block",
+
+ code: true,
+
+ defining: true,
+
+ addAttributes() {
+ return {
+ language: {
+ default: null,
+ parseHTML: (element) => {
+ const { languageClassPrefix } = this.options;
+ // @ts-expect-error element is a DOM element
+ const classNames = [...(element.firstElementChild?.classList || [])];
+ const languages = classNames
+ .filter((className) => className.startsWith(languageClassPrefix))
+ .map((className) => className.replace(languageClassPrefix, ""));
+ const language = languages[0];
+
+ if (!language) {
+ return null;
+ }
+
+ return language;
+ },
+ rendered: false,
+ },
+ };
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: "pre",
+ preserveWhitespace: "full",
+ },
+ ];
+ },
+
+ renderHTML({ node, HTMLAttributes }) {
+ return [
+ "pre",
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
+ [
+ "code",
+ {
+ class: node.attrs.language ? this.options.languageClassPrefix + node.attrs.language : null,
+ },
+ 0,
+ ],
+ ];
+ },
+
+ addCommands() {
+ return {
+ setCodeBlock:
+ (attributes) =>
+ ({ commands }) =>
+ commands.setNode(this.name, attributes),
+ toggleCodeBlock:
+ (attributes) =>
+ ({ commands }) =>
+ commands.toggleNode(this.name, "paragraph", attributes),
+ };
+ },
+
+ addKeyboardShortcuts() {
+ return {
+ "Mod-Alt-c": () => this.editor.commands.toggleCodeBlock(),
+
+ // remove code block when at start of document or code block is empty
+ Backspace: () => {
+ try {
+ const { empty, $anchor } = this.editor.state.selection;
+ const isAtStart = $anchor.pos === 1;
+
+ if (!empty || $anchor.parent.type.name !== this.name) {
+ return false;
+ }
+
+ if (isAtStart || !$anchor.parent.textContent.length) {
+ return this.editor.commands.clearNodes();
+ }
+
+ return false;
+ } catch (error) {
+ console.error("Error handling Backspace in code block:", error);
+ return false;
+ }
+ },
+
+ // exit node on triple enter
+ Enter: ({ editor }) => {
+ try {
+ if (!this.options.exitOnTripleEnter) {
+ return false;
+ }
+
+ const { state } = editor;
+ const { selection } = state;
+ const { $from, empty } = selection;
+
+ if (!empty || $from.parent.type !== this.type) {
+ return false;
+ }
+
+ const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;
+ const endsWithDoubleNewline = $from.parent.textContent.endsWith("\n\n");
+
+ if (!isAtEnd || !endsWithDoubleNewline) {
+ return false;
+ }
+
+ return editor
+ .chain()
+ .command(({ tr }) => {
+ tr.delete($from.pos - 2, $from.pos);
+
+ return true;
+ })
+ .exitCode()
+ .run();
+ } catch (error) {
+ console.error("Error handling Enter in code block:", error);
+ return false;
+ }
+ },
+
+ // exit node on arrow down
+ ArrowDown: ({ editor }) => {
+ try {
+ if (!this.options.exitOnArrowDown) {
+ return false;
+ }
+
+ const { state } = editor;
+ const { selection, doc } = state;
+ const { $from, empty } = selection;
+
+ if (!empty || $from.parent.type !== this.type) {
+ return false;
+ }
+
+ const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;
+
+ if (!isAtEnd) {
+ return false;
+ }
+
+ const after = $from.after();
+
+ if (after === undefined) {
+ return false;
+ }
+
+ const nodeAfter = doc.nodeAt(after);
+
+ if (nodeAfter) {
+ return false;
+ }
+
+ return editor.commands.exitCode();
+ } catch (error) {
+ console.error("Error handling ArrowDown in code block:", error);
+ return false;
+ }
+ },
+ };
+ },
+
+ addInputRules() {
+ return [
+ textblockTypeInputRule({
+ find: backtickInputRegex,
+ type: this.type,
+ getAttributes: (match) => ({
+ language: match[1],
+ }),
+ }),
+ textblockTypeInputRule({
+ find: tildeInputRegex,
+ type: this.type,
+ getAttributes: (match) => ({
+ language: match[1],
+ }),
+ }),
+ ];
+ },
+ addProseMirrorPlugins() {
+ return [
+ new Plugin({
+ key: new PluginKey("codeBlockVSCodeHandlerCustom"),
+ props: {
+ handlePaste: (view, event) => {
+ try {
+ if (!event.clipboardData) {
+ return false;
+ }
+
+ if (this.editor.isActive(this.type.name)) {
+ return false;
+ }
+
+ if (this.editor.isActive("code")) {
+ // Check if it's an inline code block
+ event.preventDefault();
+ const text = event.clipboardData.getData("text/plain");
+
+ if (!text) {
+ console.error("Pasted text is empty.");
+ return false;
+ }
+
+ const { tr } = view.state;
+ const { $from, $to } = tr.selection;
+
+ if ($from.pos > $to.pos) {
+ console.error("Invalid selection range.");
+ return false;
+ }
+
+ const docSize = tr.doc.content.size;
+ if ($from.pos < 0 || $to.pos > docSize) {
+ console.error("Selection range is out of document bounds.");
+ return false;
+ }
+
+ // Extend the current selection to replace it with the pasted text
+ // wrapped in an inline code mark
+ const codeMark = view.state.schema.marks.code.create();
+ tr.replaceWith($from.pos, $to.pos, view.state.schema.text(text, [codeMark]));
+ view.dispatch(tr);
+ return true;
+ }
+
+ event.preventDefault();
+ const text = event.clipboardData.getData("text/plain");
+ const vscode = event.clipboardData.getData("vscode-editor-data");
+ const vscodeData = vscode ? JSON.parse(vscode) : undefined;
+ const language = vscodeData?.mode;
+
+ if (vscodeData && language) {
+ const { tr } = view.state;
+ const { $from } = tr.selection;
+
+ // Check if the current line is empty
+ const isCurrentLineEmpty = !$from.parent.textContent.trim();
+
+ let insertPos;
+
+ if (isCurrentLineEmpty) {
+ // If the current line is empty, use the current position
+ insertPos = $from.pos - 1;
+ } else {
+ // If the current line is not empty, insert below the current block node
+ insertPos = $from.end($from.depth) + 1;
+ }
+
+ // Ensure insertPos is within document bounds
+ if (insertPos < 0 || insertPos > tr.doc.content.size) {
+ console.error("Invalid insert position.");
+ return false;
+ }
+
+ // Create a new code block node with the pasted content
+ const textNode = view.state.schema.text(text.replace(/\r\n?/g, "\n"));
+ const codeBlock = this.type.create({ language }, textNode);
+ if (insertPos <= tr.doc.content.size) {
+ tr.insert(insertPos, codeBlock);
+ view.dispatch(tr);
+ return true;
+ }
+
+ return false;
+ } else {
+ // TODO: complicated paste logic, to be handled later
+ return false;
+ }
+ } catch (error) {
+ console.error("Error handling paste in CodeBlock extension:", error);
+ return false;
+ }
+ },
+ },
+ }),
+ ];
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/code/index.tsx b/packages/editor/core/src/ui/extensions/code/index.tsx
new file mode 100644
index 0000000..206930a
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/code/index.tsx
@@ -0,0 +1,121 @@
+import { common, createLowlight } from "lowlight";
+import ts from "highlight.js/lib/languages/typescript";
+
+const lowlight = createLowlight(common);
+lowlight.register("ts", ts);
+
+import { Selection } from "@tiptap/pm/state";
+import { ReactNodeViewRenderer } from "@tiptap/react";
+import { CodeBlockComponent } from "./code-block-node-view";
+import { CodeBlockLowlight } from "./code-block-lowlight";
+
+export const CustomCodeBlockExtension = CodeBlockLowlight.extend({
+ addNodeView() {
+ return ReactNodeViewRenderer(CodeBlockComponent);
+ },
+
+ addKeyboardShortcuts() {
+ return {
+ Tab: ({ editor }) => {
+ try {
+ const { state } = editor;
+ const { selection } = state;
+ const { $from, empty } = selection;
+
+ if (!empty || $from.parent.type !== this.type) {
+ return false;
+ }
+
+ // Use ProseMirror's insertText transaction to insert the tab character
+ const tr = state.tr.insertText("\t", $from.pos, $from.pos);
+ editor.view.dispatch(tr);
+
+ return true;
+ } catch (error) {
+ console.error("Error handling Tab in CustomCodeBlockExtension:", error);
+ return false;
+ }
+ },
+ ArrowUp: ({ editor }) => {
+ try {
+ const { state } = editor;
+ const { selection } = state;
+ const { $from, empty } = selection;
+
+ if (!empty || $from.parent.type !== this.type) {
+ return false;
+ }
+
+ const isAtStart = $from.parentOffset === 0;
+
+ if (!isAtStart) {
+ return false;
+ }
+
+ // Check if codeBlock is the first node
+ const isFirstNode = $from.depth === 1 && $from.index($from.depth - 1) === 0;
+
+ if (isFirstNode) {
+ // Insert a new paragraph at the start of the document and move the cursor to it
+ return editor.commands.command(({ tr }) => {
+ const node = editor.schema.nodes.paragraph.create();
+ tr.insert(0, node);
+ tr.setSelection(Selection.near(tr.doc.resolve(1)));
+ return true;
+ });
+ }
+
+ return false;
+ } catch (error) {
+ console.error("Error handling ArrowUp in CustomCodeBlockExtension:", error);
+ return false;
+ }
+ },
+ ArrowDown: ({ editor }) => {
+ try {
+ if (!this.options.exitOnArrowDown) {
+ return false;
+ }
+
+ const { state } = editor;
+ const { selection, doc } = state;
+ const { $from, empty } = selection;
+
+ if (!empty || $from.parent.type !== this.type) {
+ return false;
+ }
+
+ const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;
+
+ if (!isAtEnd) {
+ return false;
+ }
+
+ const after = $from.after();
+
+ if (after === undefined) {
+ return false;
+ }
+
+ const nodeAfter = doc.nodeAt(after);
+
+ if (nodeAfter) {
+ return editor.commands.command(({ tr }) => {
+ tr.setSelection(Selection.near(doc.resolve(after)));
+ return true;
+ });
+ }
+
+ return editor.commands.exitCode();
+ } catch (error) {
+ console.error("Error handling ArrowDown in CustomCodeBlockExtension:", error);
+ return false;
+ }
+ },
+ };
+ },
+}).configure({
+ lowlight,
+ defaultLanguage: "plaintext",
+ exitOnTripleEnter: false,
+});
diff --git a/packages/editor/core/src/ui/extensions/code/lowlight-plugin.ts b/packages/editor/core/src/ui/extensions/code/lowlight-plugin.ts
new file mode 100644
index 0000000..54aa431
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/code/lowlight-plugin.ts
@@ -0,0 +1,153 @@
+import { findChildren } from "@tiptap/core";
+import { Node as ProsemirrorNode } from "@tiptap/pm/model";
+import { Plugin, PluginKey } from "@tiptap/pm/state";
+import { Decoration, DecorationSet } from "@tiptap/pm/view";
+import highlight from "highlight.js/lib/core";
+
+function parseNodes(nodes: any[], className: string[] = []): { text: string; classes: string[] }[] {
+ return nodes
+ .map((node) => {
+ const classes = [...className, ...(node.properties ? node.properties.className : [])];
+
+ if (node.children) {
+ return parseNodes(node.children, classes);
+ }
+
+ return {
+ text: node.value,
+ classes,
+ };
+ })
+ .flat();
+}
+
+function getHighlightNodes(result: any) {
+ // `.value` for lowlight v1, `.children` for lowlight v2
+ return result.value || result.children || [];
+}
+
+function registered(aliasOrLanguage: string) {
+ return Boolean(highlight.getLanguage(aliasOrLanguage));
+}
+
+function getDecorations({
+ doc,
+ name,
+ lowlight,
+ defaultLanguage,
+}: {
+ doc: ProsemirrorNode;
+ name: string;
+ lowlight: any;
+ defaultLanguage: string | null | undefined;
+}) {
+ const decorations: Decoration[] = [];
+
+ findChildren(doc, (node) => node.type.name === name).forEach((block) => {
+ let from = block.pos + 1;
+ const language = block.node.attrs.language || defaultLanguage;
+ const languages = lowlight.listLanguages();
+
+ const nodes =
+ language && (languages.includes(language) || registered(language))
+ ? getHighlightNodes(lowlight.highlight(language, block.node.textContent))
+ : getHighlightNodes(lowlight.highlightAuto(block.node.textContent));
+
+ parseNodes(nodes).forEach((node) => {
+ const to = from + node.text.length;
+
+ if (node.classes.length) {
+ const decoration = Decoration.inline(from, to, {
+ class: node.classes.join(" "),
+ });
+
+ decorations.push(decoration);
+ }
+
+ from = to;
+ });
+ });
+
+ return DecorationSet.create(doc, decorations);
+}
+
+function isFunction(param: () => any) {
+ return typeof param === "function";
+}
+
+export function LowlightPlugin({
+ name,
+ lowlight,
+ defaultLanguage,
+}: {
+ name: string;
+ lowlight: any;
+ defaultLanguage: string | null | undefined;
+}) {
+ if (!["highlight", "highlightAuto", "listLanguages"].every((api) => isFunction(lowlight[api]))) {
+ throw Error("You should provide an instance of lowlight to use the code-block-lowlight extension");
+ }
+
+ const lowlightPlugin: Plugin = new Plugin({
+ key: new PluginKey("lowlight"),
+
+ state: {
+ init: (_, { doc }) =>
+ getDecorations({
+ doc,
+ name,
+ lowlight,
+ defaultLanguage,
+ }),
+ apply: (transaction, decorationSet, oldState, newState) => {
+ const oldNodeName = oldState.selection.$head.parent.type.name;
+ const newNodeName = newState.selection.$head.parent.type.name;
+ const oldNodes = findChildren(oldState.doc, (node) => node.type.name === name);
+ const newNodes = findChildren(newState.doc, (node) => node.type.name === name);
+
+ if (
+ transaction.docChanged &&
+ // Apply decorations if:
+ // selection includes named node,
+ ([oldNodeName, newNodeName].includes(name) ||
+ // OR transaction adds/removes named node,
+ newNodes.length !== oldNodes.length ||
+ // OR transaction has changes that completely encapsulte a node
+ // (for example, a transaction that affects the entire document).
+ // Such transactions can happen during collab syncing via y-prosemirror, for example.
+ transaction.steps.some(
+ (step) =>
+ // @ts-ignore
+ step.from !== undefined &&
+ // @ts-ignore
+ step.to !== undefined &&
+ oldNodes.some(
+ (node) =>
+ // @ts-ignore
+ node.pos >= step.from &&
+ // @ts-ignore
+ node.pos + node.node.nodeSize <= step.to
+ )
+ ))
+ ) {
+ return getDecorations({
+ doc: transaction.doc,
+ name,
+ lowlight,
+ defaultLanguage,
+ });
+ }
+
+ return decorationSet.map(transaction.mapping, transaction.doc);
+ },
+ },
+
+ props: {
+ decorations(state) {
+ return lowlightPlugin.getState(state);
+ },
+ },
+ });
+
+ return lowlightPlugin;
+}
diff --git a/packages/editor/core/src/ui/extensions/code/utils/replace-code-block-with-text.ts b/packages/editor/core/src/ui/extensions/code/utils/replace-code-block-with-text.ts
new file mode 100644
index 0000000..daf2c5f
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/code/utils/replace-code-block-with-text.ts
@@ -0,0 +1,124 @@
+import { Editor, findParentNode } from "@tiptap/core";
+
+type ReplaceCodeBlockParams = {
+ editor: Editor;
+ from: number;
+ to: number;
+ textContent: string;
+ cursorPosInsideCodeblock: number;
+};
+
+export function replaceCodeWithText(editor: Editor): void {
+ try {
+ const { from, to } = editor.state.selection;
+ const cursorPosInsideCodeblock = from;
+ let replaced = false;
+
+ editor.state.doc.nodesBetween(from, to, (node, pos) => {
+ if (node.type === editor.state.schema.nodes.codeBlock) {
+ const startPos = pos;
+ const endPos = pos + node.nodeSize;
+ const textContent = node.textContent;
+
+ if (textContent.length === 0) {
+ editor.chain().focus().toggleCodeBlock().run();
+ } else {
+ transformCodeBlockToParagraphs({
+ editor,
+ from: startPos,
+ to: endPos,
+ textContent,
+ cursorPosInsideCodeblock,
+ });
+ }
+
+ replaced = true;
+ return false;
+ }
+ });
+
+ if (!replaced) {
+ console.log("No code block to replace.");
+ }
+ } catch (error) {
+ console.error("An error occurred while replacing code block content:", error);
+ }
+}
+
+function transformCodeBlockToParagraphs({
+ editor,
+ from,
+ to,
+ textContent,
+ cursorPosInsideCodeblock,
+}: ReplaceCodeBlockParams): void {
+ const { schema } = editor.state;
+ const { paragraph } = schema.nodes;
+ const docSize = editor.state.doc.content.size;
+
+ if (from < 0 || to > docSize || from > to) {
+ console.error("Invalid range for replacement: ", from, to, "in a document of size", docSize);
+ return;
+ }
+
+ // Split the textContent by new lines to handle each line as a separate paragraph for Windows (\r\n) and Unix (\n)
+ const lines = textContent.split(/\r?\n/);
+ const tr = editor.state.tr;
+ let insertPos = from;
+
+ // Remove the code block first
+ tr.delete(from, to);
+
+ // For each line, create a paragraph node and insert it
+ lines.forEach((line) => {
+ // if the line is empty, create a paragraph node with no content
+ const paragraphNode = line.length === 0 ? paragraph.create({}) : paragraph.create({}, schema.text(line));
+ tr.insert(insertPos, paragraphNode);
+ insertPos += paragraphNode.nodeSize;
+ });
+
+ // Now persist the focus to the converted paragraph
+ const parentNodeOffset = findParentNode((node) => node.type === schema.nodes.codeBlock)(editor.state.selection)?.pos;
+
+ if (parentNodeOffset === undefined) throw new Error("Invalid code block offset");
+
+ const lineNumber = getLineNumber(textContent, cursorPosInsideCodeblock, parentNodeOffset);
+ const cursorPosOutsideCodeblock = cursorPosInsideCodeblock + (lineNumber - 1);
+
+ editor.view.dispatch(tr);
+ editor.chain().focus(cursorPosOutsideCodeblock).run();
+}
+
+/**
+ * Calculates the line number where the cursor is located inside the code block.
+ * Assumes the indexing of the content inside the code block is like ProseMirror's indexing.
+ *
+ * @param {string} textContent - The content of the code block.
+ * @param {number} cursorPosition - The absolute cursor position in the document.
+ * @param {number} codeBlockNodePos - The starting position of the code block node in the document.
+ * @returns {number} The 1-based line number where the cursor is located.
+ */
+function getLineNumber(textContent: string, cursorPosition: number, codeBlockNodePos: number): number {
+ // Split the text content into lines, handling both Unix and Windows newlines
+ const lines = textContent.split(/\r?\n/);
+ const cursorPosInsideCodeblockRelative = cursorPosition - codeBlockNodePos;
+
+ let startPosition = 0;
+ let lineNumber = 0;
+
+ for (let i = 0; i < lines.length; i++) {
+ // Calculate the end position of the current line
+ const endPosition = startPosition + lines[i].length + 1; // +1 for the newline character
+
+ // Check if the cursor position is within the current line
+ if (cursorPosInsideCodeblockRelative >= startPosition && cursorPosInsideCodeblockRelative <= endPosition) {
+ lineNumber = i + 1; // Line numbers are 1-based
+ break;
+ }
+
+ // Update the start position for the next line
+ startPosition = endPosition;
+ }
+
+ return lineNumber;
+}
diff --git a/packages/editor/core/src/ui/extensions/core-without-props.tsx b/packages/editor/core/src/ui/extensions/core-without-props.tsx
new file mode 100644
index 0000000..3bb0001
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/core-without-props.tsx
@@ -0,0 +1,121 @@
+import TaskItem from "@tiptap/extension-task-item";
+import TaskList from "@tiptap/extension-task-list";
+import TextStyle from "@tiptap/extension-text-style";
+import TiptapUnderline from "@tiptap/extension-underline";
+import Placeholder from "@tiptap/extension-placeholder";
+import { Markdown } from "tiptap-markdown";
+
+import { Table } from "src/ui/extensions/table/table";
+import { TableCell } from "src/ui/extensions/table/table-cell/table-cell";
+import { TableHeader } from "src/ui/extensions/table/table-header/table-header";
+import { TableRow } from "src/ui/extensions/table/table-row/table-row";
+
+import { isValidHttpUrl } from "src/lib/utils";
+
+import { CustomCodeBlockExtension } from "src/ui/extensions/code";
+import { CustomKeymap } from "src/ui/extensions/keymap";
+import { CustomQuoteExtension } from "src/ui/extensions/quote";
+
+import { CustomLinkExtension } from "src/ui/extensions/custom-link";
+import { CustomCodeInlineExtension } from "src/ui/extensions/code-inline";
+import { CustomTypographyExtension } from "src/ui/extensions/typography";
+import { CustomHorizontalRule } from "src/ui/extensions/horizontal-rule/horizontal-rule";
+import { CustomCodeMarkPlugin } from "src/ui/extensions/custom-code-inline/inline-code-plugin";
+import { MentionsWithoutProps } from "src/ui/mentions/mention-without-props";
+import { ImageExtensionWithoutProps } from "src/ui/extensions/image/image-extension-without-props";
+
+import StarterKit from "@tiptap/starter-kit";
+
+export const CoreEditorExtensionsWithoutProps = () => [
+ StarterKit.configure({
+ bulletList: {
+ HTMLAttributes: {
+ class: "list-disc pl-7 space-y-2",
+ },
+ },
+ orderedList: {
+ HTMLAttributes: {
+ class: "list-decimal pl-7 space-y-2",
+ },
+ },
+ listItem: {
+ HTMLAttributes: {
+ class: "not-prose space-y-2",
+ },
+ },
+ code: false,
+ codeBlock: false,
+ horizontalRule: false,
+ blockquote: false,
+ dropcursor: {
+ color: "rgba(var(--color-text-100))",
+ width: 1,
+ },
+ }),
+ CustomQuoteExtension,
+ CustomHorizontalRule.configure({
+ HTMLAttributes: {
+ class: "my-4 border-custom-border-400",
+ },
+ }),
+ CustomKeymap,
+ // ListKeymap,
+ CustomLinkExtension.configure({
+ openOnClick: true,
+ autolink: true,
+ linkOnPaste: true,
+ protocols: ["http", "https"],
+ validate: (url: string) => isValidHttpUrl(url),
+ HTMLAttributes: {
+ class:
+ "text-custom-primary-300 underline underline-offset-[3px] hover:text-custom-primary-500 transition-colors cursor-pointer",
+ },
+ }),
+ CustomTypographyExtension,
+ ImageExtensionWithoutProps().configure({
+ HTMLAttributes: {
+ class: "rounded-md",
+ },
+ }),
+ TiptapUnderline,
+ TextStyle,
+ TaskList.configure({
+ HTMLAttributes: {
+ class: "not-prose pl-2 space-y-2",
+ },
+ }),
+ TaskItem.configure({
+ HTMLAttributes: {
+ class: "flex",
+ },
+ nested: true,
+ }),
+ CustomCodeBlockExtension.configure({
+ HTMLAttributes: {
+ class: "",
+ },
+ }),
+ CustomCodeMarkPlugin,
+ CustomCodeInlineExtension,
+ Markdown.configure({
+ html: true,
+ transformPastedText: true,
+ }),
+ Table,
+ TableHeader,
+ TableCell,
+ TableRow,
+ MentionsWithoutProps(),
+ Placeholder.configure({
+ placeholder: ({ editor, node }) => {
+ if (node.type.name === "heading") return `Heading ${node.attrs.level}`;
+
+ const shouldHidePlaceholder =
+ editor.isActive("table") || editor.isActive("codeBlock") || editor.isActive("image");
+ if (shouldHidePlaceholder) return "";
+
+ return "Press '/' for commands...";
+ },
+ includeChildren: true,
+ }),
+];
diff --git a/packages/editor/core/src/ui/extensions/custom-code-inline/inline-code-plugin.ts b/packages/editor/core/src/ui/extensions/custom-code-inline/inline-code-plugin.ts
new file mode 100644
index 0000000..3b3cfaa
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/custom-code-inline/inline-code-plugin.ts
@@ -0,0 +1,9 @@
+import { Extension } from "@tiptap/core";
+import codemark from "prosemirror-codemark";
+
+export const CustomCodeMarkPlugin = Extension.create({
+ name: "codemarkPlugin",
+ addProseMirrorPlugins() {
+ return codemark({ markType: this.editor.schema.marks.code });
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/custom-link/helpers/autolink.ts b/packages/editor/core/src/ui/extensions/custom-link/helpers/autolink.ts
new file mode 100644
index 0000000..cf67e13
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/custom-link/helpers/autolink.ts
@@ -0,0 +1,118 @@
+import {
+ combineTransactionSteps,
+ findChildrenInRange,
+ getChangedRanges,
+ getMarksBetween,
+ NodeWithPos,
+} from "@tiptap/core";
+import { MarkType } from "@tiptap/pm/model";
+import { Plugin, PluginKey } from "@tiptap/pm/state";
+import { find } from "linkifyjs";
+
+type AutolinkOptions = {
+ type: MarkType;
+ validate?: (url: string) => boolean;
+};
+
+export function autolink(options: AutolinkOptions): Plugin {
+ return new Plugin({
+ key: new PluginKey("autolink"),
+ appendTransaction: (transactions, oldState, newState) => {
+ const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc);
+ const preventAutolink = transactions.some((transaction) => transaction.getMeta("preventAutolink"));
+
+ if (!docChanges || preventAutolink) {
+ return;
+ }
+
+ const { tr } = newState;
+ const transform = combineTransactionSteps(oldState.doc, [...transactions]);
+ const changes = getChangedRanges(transform);
+
+ changes.forEach(({ newRange }) => {
+ // Now let’s see if we can add new links.
+ const nodesInChangedRanges = findChildrenInRange(newState.doc, newRange, (node) => node.isTextblock);
+
+ let textBlock: NodeWithPos | undefined;
+ let textBeforeWhitespace: string | undefined;
+
+ if (nodesInChangedRanges.length > 1) {
+ // Grab the first node within the changed ranges (ex. the first of two paragraphs when hitting enter).
+ textBlock = nodesInChangedRanges[0];
+ textBeforeWhitespace = newState.doc.textBetween(
+ textBlock.pos,
+ textBlock.pos + textBlock.node.nodeSize,
+ undefined,
+ " "
+ );
+ } else if (
+ nodesInChangedRanges.length &&
+ // We want to make sure to include the block seperator argument to treat hard breaks like spaces.
+ newState.doc.textBetween(newRange.from, newRange.to, " ", " ").endsWith(" ")
+ ) {
+ textBlock = nodesInChangedRanges[0];
+ textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, newRange.to, undefined, " ");
+ }
+
+ if (textBlock && textBeforeWhitespace) {
+ const wordsBeforeWhitespace = textBeforeWhitespace.split(" ").filter((s) => s !== "");
+
+ if (wordsBeforeWhitespace.length <= 0) {
+ return false;
+ }
+
+ const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1];
+ const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace);
+
+ if (!lastWordBeforeSpace) {
+ return false;
+ }
+
+ find(lastWordBeforeSpace)
+ .filter((link) => link.isLink)
+ // Calculate link position.
+ .map((link) => ({
+ ...link,
+ from: lastWordAndBlockOffset + link.start + 1,
+ to: lastWordAndBlockOffset + link.end + 1,
+ }))
+ // ignore link inside code mark
+ .filter((link) => {
+ if (!newState.schema.marks.code) {
+ return true;
+ }
+
+ return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code);
+ })
+ // validate link
+ .filter((link) => {
+ if (options.validate) {
+ return options.validate(link.value);
+ }
+ return true;
+ })
+ // Add link mark.
+ .forEach((link) => {
+ if (getMarksBetween(link.from, link.to, newState.doc).some((item) => item.mark.type === options.type)) {
+ return;
+ }
+
+ tr.addMark(
+ link.from,
+ link.to,
+ options.type.create({
+ href: link.href,
+ })
+ );
+ });
+ }
+ });
+
+ if (!tr.steps.length) {
+ return;
+ }
+
+ return tr;
+ },
+ });
+}
diff --git a/packages/editor/core/src/ui/extensions/custom-link/helpers/clickHandler.ts b/packages/editor/core/src/ui/extensions/custom-link/helpers/clickHandler.ts
new file mode 100644
index 0000000..ec6c540
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/custom-link/helpers/clickHandler.ts
@@ -0,0 +1,46 @@
+import { getAttributes } from "@tiptap/core";
+import { MarkType } from "@tiptap/pm/model";
+import { Plugin, PluginKey } from "@tiptap/pm/state";
+
+type ClickHandlerOptions = {
+ type: MarkType;
+};
+
+export function clickHandler(options: ClickHandlerOptions): Plugin {
+ return new Plugin({
+ key: new PluginKey("handleClickLink"),
+ props: {
+ handleClick: (view, pos, event) => {
+ if (event.button !== 0) {
+ return false;
+ }
+
+ let a = event.target as HTMLElement;
+ const els = [];
+
+ while (a.nodeName !== "DIV") {
+ els.push(a);
+ a = a.parentNode as HTMLElement;
+ }
+
+ if (!els.find((value) => value.nodeName === "A")) {
+ return false;
+ }
+
+ const attrs = getAttributes(view.state, options.type.name);
+ const link = event.target as HTMLLinkElement;
+
+ const href = link?.href ?? attrs.href;
+ const target = link?.target ?? attrs.target;
+
+ if (link && href) {
+ window.open(href, target);
+
+ return true;
+ }
+
+ return false;
+ },
+ },
+ });
+}
diff --git a/packages/editor/core/src/ui/extensions/custom-link/helpers/pasteHandler.ts b/packages/editor/core/src/ui/extensions/custom-link/helpers/pasteHandler.ts
new file mode 100644
index 0000000..475bf28
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/custom-link/helpers/pasteHandler.ts
@@ -0,0 +1,44 @@
+import { Editor } from "@tiptap/core";
+import { MarkType } from "@tiptap/pm/model";
+import { Plugin, PluginKey } from "@tiptap/pm/state";
+import { find } from "linkifyjs";
+
+type PasteHandlerOptions = {
+ editor: Editor;
+ type: MarkType;
+};
+
+export function pasteHandler(options: PasteHandlerOptions): Plugin {
+ return new Plugin({
+ key: new PluginKey("handlePasteLink"),
+ props: {
+ handlePaste: (view, event, slice) => {
+ const { state } = view;
+ const { selection } = state;
+ const { empty } = selection;
+
+ if (empty) {
+ return false;
+ }
+
+ let textContent = "";
+
+ slice.content.forEach((node) => {
+ textContent += node.textContent;
+ });
+
+ const link = find(textContent).find((item) => item.isLink && item.value === textContent);
+
+ if (!textContent || !link) {
+ return false;
+ }
+
+ options.editor.commands.setMark(options.type, {
+ href: link.href,
+ });
+
+ return true;
+ },
+ },
+ });
+}
diff --git a/packages/editor/core/src/ui/extensions/custom-link/index.ts b/packages/editor/core/src/ui/extensions/custom-link/index.ts
new file mode 100644
index 0000000..88e7abf
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/custom-link/index.ts
@@ -0,0 +1,248 @@
+import { Mark, markPasteRule, mergeAttributes, PasteRuleMatch } from "@tiptap/core";
+import { Plugin } from "@tiptap/pm/state";
+import { find, registerCustomProtocol, reset } from "linkifyjs";
+import { autolink } from "./helpers/autolink";
+import { clickHandler } from "./helpers/clickHandler";
+import { pasteHandler } from "./helpers/pasteHandler";
+
+export interface LinkProtocolOptions {
+ scheme: string;
+ optionalSlashes?: boolean;
+}
+
+export const pasteRegex =
+ /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)(?:[-a-zA-Z0-9@:%._+~#=?!&/]*)/gi;
+
+export interface LinkOptions {
+ /**
+ * If enabled, it adds links as you type.
+ */
+ autolink: boolean;
+ /**
+ * An array of custom protocols to be registered with linkifyjs.
+ */
+ protocols: Array;
+ /**
+ * If enabled, links will be opened on click.
+ */
+ openOnClick: boolean;
+ /**
+ * If enabled, links will be inclusive i.e. if you move your cursor to the
+ * link text, and start typing, it'll be a part of the link itself.
+ */
+ inclusive: boolean;
+ /**
+ * Adds a link to the current selection if the pasted content only contains an url.
+ */
+ linkOnPaste: boolean;
+ /**
+ * A list of HTML attributes to be rendered.
+ */
+ HTMLAttributes: Record;
+ /**
+ * A validation function that modifies link verification for the auto linker.
+ * @param url - The url to be validated.
+ * @returns - True if the url is valid, false otherwise.
+ */
+ validate?: (url: string) => boolean;
+}
+
+declare module "@tiptap/core" {
+ interface Commands {
+ link: {
+ /**
+ * Set a link mark
+ */
+ setLink: (attributes: {
+ href: string;
+ target?: string | null;
+ rel?: string | null;
+ class?: string | null;
+ }) => ReturnType;
+ /**
+ * Toggle a link mark
+ */
+ toggleLink: (attributes: {
+ href: string;
+ target?: string | null;
+ rel?: string | null;
+ class?: string | null;
+ }) => ReturnType;
+ /**
+ * Unset a link mark
+ */
+ unsetLink: () => ReturnType;
+ };
+ }
+}
+
+export const CustomLinkExtension = Mark.create({
+ name: "link",
+
+ priority: 1000,
+
+ keepOnSplit: false,
+
+ onCreate() {
+ this.options.protocols.forEach((protocol) => {
+ if (typeof protocol === "string") {
+ registerCustomProtocol(protocol);
+ return;
+ }
+ registerCustomProtocol(protocol.scheme, protocol.optionalSlashes);
+ });
+ },
+
+ onDestroy() {
+ reset();
+ },
+
+ inclusive() {
+ return this.options.inclusive;
+ },
+
+ addOptions() {
+ return {
+ openOnClick: true,
+ linkOnPaste: true,
+ autolink: true,
+ inclusive: false,
+ protocols: [],
+ HTMLAttributes: {
+ target: "_blank",
+ rel: "noopener noreferrer nofollow",
+ class: null,
+ },
+ validate: undefined,
+ };
+ },
+
+ addAttributes() {
+ return {
+ href: {
+ default: null,
+ },
+ target: {
+ default: this.options.HTMLAttributes.target,
+ },
+ rel: {
+ default: this.options.HTMLAttributes.rel,
+ },
+ class: {
+ default: this.options.HTMLAttributes.class,
+ },
+ };
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: "a[href]",
+ getAttrs: (node) => {
+ if (typeof node === "string" || !(node instanceof HTMLElement)) {
+ return null;
+ }
+ const href = node.getAttribute("href")?.toLowerCase() || "";
+ if (href.startsWith("javascript:") || href.startsWith("data:") || href.startsWith("vbscript:")) {
+ return false;
+ }
+ return {};
+ },
+ },
+ ];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ const href = HTMLAttributes.href?.toLowerCase() || "";
+ if (href.startsWith("javascript:") || href.startsWith("data:") || href.startsWith("vbscript:")) {
+ return ["a", mergeAttributes(this.options.HTMLAttributes, { ...HTMLAttributes, href: "" }), 0];
+ }
+ return ["a", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
+ },
+
+ addCommands() {
+ return {
+ setLink:
+ (attributes) =>
+ ({ chain }) =>
+ chain().setMark(this.name, attributes).setMeta("preventAutolink", true).run(),
+
+ toggleLink:
+ (attributes) =>
+ ({ chain }) =>
+ chain()
+ .toggleMark(this.name, attributes, { extendEmptyMarkRange: true })
+ .setMeta("preventAutolink", true)
+ .run(),
+
+ unsetLink:
+ () =>
+ ({ chain }) =>
+ chain().unsetMark(this.name, { extendEmptyMarkRange: true }).setMeta("preventAutolink", true).run(),
+ };
+ },
+
+ addPasteRules() {
+ return [
+ markPasteRule({
+ find: (text) => {
+ const foundLinks: PasteRuleMatch[] = [];
+
+ if (text) {
+ const links = find(text).filter((item) => item.isLink);
+
+ if (links.length) {
+ links.forEach((link) =>
+ foundLinks.push({
+ text: link.value,
+ data: {
+ href: link.href,
+ },
+ index: link.start,
+ })
+ );
+ }
+ }
+
+ return foundLinks;
+ },
+ type: this.type,
+ getAttributes: (match) => ({
+ href: match.data?.href,
+ }),
+ }),
+ ];
+ },
+
+ addProseMirrorPlugins() {
+ const plugins: Plugin[] = [];
+
+ if (this.options.autolink) {
+ plugins.push(
+ autolink({
+ type: this.type,
+ validate: this.options.validate,
+ })
+ );
+ }
+
+ if (this.options.openOnClick) {
+ plugins.push(
+ clickHandler({
+ type: this.type,
+ })
+ );
+ }
+
+ if (this.options.linkOnPaste) {
+ plugins.push(
+ pasteHandler({
+ editor: this.editor,
+ type: this.type,
+ })
+ );
+ }
+
+ return plugins;
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/custom-list-keymap/index.ts b/packages/editor/core/src/ui/extensions/custom-list-keymap/index.ts
new file mode 100644
index 0000000..b91209e
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/custom-list-keymap/index.ts
@@ -0,0 +1 @@
+export * from "./list-keymap";
diff --git a/packages/editor/core/src/ui/extensions/custom-list-keymap/list-helpers.ts b/packages/editor/core/src/ui/extensions/custom-list-keymap/list-helpers.ts
new file mode 100644
index 0000000..d6ddb8c
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/custom-list-keymap/list-helpers.ts
@@ -0,0 +1,371 @@
+import { EditorState } from "@tiptap/pm/state";
+import { Editor, getNodeType, getNodeAtPosition, isAtEndOfNode, isAtStartOfNode, isNodeActive } from "@tiptap/core";
+import { Node, NodeType } from "@tiptap/pm/model";
+
+const findListItemPos = (typeOrName: string | NodeType, state: EditorState) => {
+ const { $from } = state.selection;
+ const nodeType = getNodeType(typeOrName, state.schema);
+
+ let currentNode = null;
+ let currentDepth = $from.depth;
+ let currentPos = $from.pos;
+ let targetDepth: number | null = null;
+
+ while (currentDepth > 0 && targetDepth === null) {
+ currentNode = $from.node(currentDepth);
+
+ if (currentNode.type === nodeType) {
+ targetDepth = currentDepth;
+ } else {
+ currentDepth -= 1;
+ currentPos -= 1;
+ }
+ }
+
+ if (targetDepth === null) {
+ return null;
+ }
+
+ return { $pos: state.doc.resolve(currentPos), depth: targetDepth };
+};
+
+const nextListIsDeeper = (typeOrName: string, state: EditorState) => {
+ const listDepth = getNextListDepth(typeOrName, state);
+ const listItemPos = findListItemPos(typeOrName, state);
+
+ if (!listItemPos || !listDepth) {
+ return false;
+ }
+
+ if (listDepth > listItemPos.depth) {
+ return true;
+ }
+
+ return false;
+};
+
+const getNextListDepth = (typeOrName: string, state: EditorState) => {
+ const listItemPos = findListItemPos(typeOrName, state);
+
+ if (!listItemPos) {
+ return false;
+ }
+
+ const [, depth] = getNodeAtPosition(state, typeOrName, listItemPos.$pos.pos + 4);
+
+ return depth;
+};
+
+const getPrevListDepth = (typeOrName: string, state: EditorState) => {
+ const listItemPos = findListItemPos(typeOrName, state);
+
+ if (!listItemPos) {
+ return false;
+ }
+
+ let depth = 0;
+ const pos = listItemPos.$pos;
+
+ // Adjust the position to ensure we're within the list item, especially for edge cases
+ const resolvedPos = state.doc.resolve(Math.max(pos.pos - 1, 0));
+
+ // Traverse up the document structure from the adjusted position
+ for (let d = resolvedPos.depth; d > 0; d--) {
+ const node = resolvedPos.node(d);
+ if (node.type.name === "bulletList" || node.type.name === "orderedList" || node.type.name === "taskList") {
+ // Increment depth for each list ancestor found
+ depth++;
+ }
+ }
+
+ // Subtract 1 from the calculated depth to get the parent list's depth
+ // This adjustment is necessary because the depth calculation includes the current list
+ // By subtracting 1, we aim to get the depth of the parent list, which helps in identifying if the current list is a sublist
+ depth = depth > 0 ? depth - 1 : 0;
+
+ // Double the depth value to get results as 2, 4, 6, 8, etc.
+ depth = depth * 2;
+
+ return depth;
+};
+
+export const handleBackspace = (editor: Editor, name: string, parentListTypes: string[]) => {
+ // this is required to still handle the undo handling
+ if (editor.commands.undoInputRule()) {
+ return true;
+ }
+ // Check if a node range is selected, and if so, fall back to default backspace functionality
+ const { from, to } = editor.state.selection;
+ if (from !== to) {
+ // A range is selected, not just a cursor position; fall back to default behavior
+ return false; // Let the editor handle backspace by default
+ }
+
+ // if the current item is NOT inside a list item &
+ // the previous item is a list (orderedList or bulletList)
+ // move the cursor into the list and delete the current item
+ if (!isNodeActive(editor.state, name) && hasListBefore(editor.state, name, parentListTypes)) {
+ const { $anchor } = editor.state.selection;
+
+ const $listPos = editor.state.doc.resolve($anchor.before() - 1);
+
+ const listDescendants: Array<{ node: Node; pos: number }> = [];
+
+ $listPos.node().descendants((node, pos) => {
+ if (node.type.name === name) {
+ listDescendants.push({ node, pos });
+ }
+ });
+
+ const lastItem = listDescendants.at(-1);
+
+ if (!lastItem) {
+ return false;
+ }
+
+ const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1);
+
+ // Check if positions are within the valid range
+ const startPos = $anchor.start() - 1;
+ const endPos = $anchor.end() + 1;
+ if (startPos < 0 || endPos > editor.state.doc.content.size) {
+ return false; // Invalid position, abort operation
+ }
+
+ return editor.chain().cut({ from: startPos, to: endPos }, $lastItemPos.end()).joinForward().run();
+ }
+
+ // if the cursor is not inside the current node type
+ // do nothing and proceed
+ if (!isNodeActive(editor.state, name)) {
+ return false;
+ }
+
+ // if the cursor is not at the start of a node
+ // do nothing and proceed
+ if (!isAtStartOfNode(editor.state)) {
+ return false;
+ }
+
+ // is the paragraph node inside of the current list item (maybe with a hard break)
+ const isParaSibling = isCurrentParagraphASibling(editor.state);
+ const isCurrentListItemSublist = prevListIsHigher(name, editor.state);
+ const listItemPos = findListItemPos(name, editor.state);
+ const nextListItemIsSibling = nextListIsSibling(name, editor.state);
+
+ if (!listItemPos) {
+ return false;
+ }
+
+ const currentNode = listItemPos.$pos.node(listItemPos.depth);
+ const currentListItemHasSubList = listItemHasSubList(name, editor.state, currentNode);
+
+ if (currentListItemHasSubList && isCurrentListItemSublist && isParaSibling) {
+ return false;
+ }
+
+ if (currentListItemHasSubList && isCurrentListItemSublist) {
+ editor.chain().liftListItem(name).run();
+ return editor.commands.joinItemBackward();
+ }
+
+ if (isCurrentListItemSublist && nextListItemIsSibling) {
+ return false;
+ }
+
+ if (isCurrentListItemSublist) {
+ return false;
+ }
+
+ if (currentListItemHasSubList) {
+ return false;
+ }
+
+ if (hasListItemBefore(name, editor.state)) {
+ return editor.chain().liftListItem(name).run();
+ }
+
+ if (!currentListItemHasSubList) {
+ return false;
+ }
+
+ // otherwise in the end, a backspace should
+ // always just lift the list item if
+ // joining / merging is not possible
+ return editor.chain().liftListItem(name).run();
+};
+
+export const handleDelete = (editor: Editor, name: string) => {
+ // if the cursor is not inside the current node type
+ // do nothing and proceed
+ if (!isNodeActive(editor.state, name)) {
+ return false;
+ }
+
+ // if the cursor is not at the end of a node
+ // do nothing and proceed
+ if (!isAtEndOfNode(editor.state, name)) {
+ return false;
+ }
+
+ // check if the next node is a list with a deeper depth
+ if (nextListIsDeeper(name, editor.state)) {
+ return editor
+ .chain()
+ .focus(editor.state.selection.from + 4)
+ .lift(name)
+ .joinBackward()
+ .run();
+ }
+
+ if (nextListIsHigher(name, editor.state)) {
+ return editor.chain().joinForward().joinBackward().run();
+ }
+
+ return editor.commands.joinItemForward();
+};
+
+const hasListBefore = (editorState: EditorState, name: string, parentListTypes: string[]) => {
+ const { $anchor } = editorState.selection;
+
+ const previousNodePos = Math.max(0, $anchor.pos - 2);
+
+ const previousNode = editorState.doc.resolve(previousNodePos).node();
+
+ if (!previousNode || !parentListTypes.includes(previousNode.type.name)) {
+ return false;
+ }
+
+ return true;
+};
+
+const prevListIsHigher = (typeOrName: string, state: EditorState) => {
+ const listDepth = getPrevListDepth(typeOrName, state);
+ const listItemPos = findListItemPos(typeOrName, state);
+
+ if (!listItemPos || !listDepth) {
+ return false;
+ }
+
+ if (listDepth < listItemPos.depth) {
+ return true;
+ }
+
+ return false;
+};
+
+const nextListIsSibling = (typeOrName: string, state: EditorState) => {
+ const listDepth = getNextListDepth(typeOrName, state);
+ const listItemPos = findListItemPos(typeOrName, state);
+
+ if (!listItemPos || !listDepth) {
+ return false;
+ }
+
+ if (listDepth === listItemPos.depth) {
+ return true;
+ }
+
+ return false;
+};
+
+export const nextListIsHigher = (typeOrName: string, state: EditorState) => {
+ const listDepth = getNextListDepth(typeOrName, state);
+ const listItemPos = findListItemPos(typeOrName, state);
+
+ if (!listItemPos || !listDepth) {
+ return false;
+ }
+
+ if (listDepth < listItemPos.depth) {
+ return true;
+ }
+
+ return false;
+};
+
+const listItemHasSubList = (typeOrName: string, state: EditorState, node?: Node) => {
+ if (!node) {
+ return false;
+ }
+
+ const nodeType = getNodeType(typeOrName, state.schema);
+
+ let hasSubList = false;
+
+ node.descendants((child) => {
+ if (child.type === nodeType) {
+ hasSubList = true;
+ }
+ });
+
+ return hasSubList;
+};
+
+const isCurrentParagraphASibling = (state: EditorState): boolean => {
+ const { $from } = state.selection;
+ const listItemNode = $from.node(-1); // Get the parent node of the current selection, assuming it's a list item.
+ const currentParagraphNode = $from.parent; // Get the current node where the selection is.
+
+ // Ensure we're in a paragraph and the parent is a list item.
+ if (
+ currentParagraphNode.type.name === "paragraph" &&
+ (listItemNode.type.name === "listItem" || listItemNode.type.name === "taskItem")
+ ) {
+ let paragraphNodesCount = 0;
+ listItemNode.forEach((child) => {
+ if (child.type.name === "paragraph") {
+ paragraphNodesCount++;
+ }
+ });
+
+ // If there are more than one paragraph nodes, the current paragraph is a sibling.
+ return paragraphNodesCount > 1;
+ }
+
+ return false;
+};
+
+export function isCursorInSubList(editor: Editor) {
+ const { selection } = editor.state;
+ const { $from } = selection;
+
+ // Check if the current node is a list item
+ const listItem = editor.schema.nodes.listItem;
+ const taskItem = editor.schema.nodes.taskItem;
+
+ // Traverse up the document tree from the current position
+ for (let depth = $from.depth; depth > 0; depth--) {
+ const node = $from.node(depth);
+ if (node.type === listItem || node.type === taskItem) {
+ // If the parent of the list item is also a list, it's a sub-list
+ const parent = $from.node(depth - 1);
+ if (
+ parent &&
+ (parent.type === editor.schema.nodes.bulletList ||
+ parent.type === editor.schema.nodes.orderedList ||
+ parent.type === editor.schema.nodes.taskList)
+ ) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+const hasListItemBefore = (typeOrName: string, state: EditorState): boolean => {
+ const { $anchor } = state.selection;
+
+ const $targetPos = state.doc.resolve($anchor.pos - 2);
+
+ if ($targetPos.index() === 0) {
+ return false;
+ }
+
+ if ($targetPos.nodeBefore?.type.name !== typeOrName) {
+ return false;
+ }
+
+ return true;
+};
diff --git a/packages/editor/core/src/ui/extensions/custom-list-keymap/list-keymap.ts b/packages/editor/core/src/ui/extensions/custom-list-keymap/list-keymap.ts
new file mode 100644
index 0000000..f2b6dd9
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/custom-list-keymap/list-keymap.ts
@@ -0,0 +1,128 @@
+import { Extension } from "@tiptap/core";
+
+import { handleBackspace, handleDelete } from "src/ui/extensions/custom-list-keymap/list-helpers";
+
+export type ListKeymapOptions = {
+ listTypes: Array<{
+ itemName: string;
+ wrapperNames: string[];
+ }>;
+};
+
+export const ListKeymap = ({ tabIndex }: { tabIndex?: number }) =>
+ Extension.create({
+ name: "listKeymap",
+
+ addOptions() {
+ return {
+ listTypes: [
+ {
+ itemName: "listItem",
+ wrapperNames: ["bulletList", "orderedList"],
+ },
+ {
+ itemName: "taskItem",
+ wrapperNames: ["taskList"],
+ },
+ ],
+ };
+ },
+
+ addKeyboardShortcuts() {
+ return {
+ Tab: () => {
+ if (this.editor.isActive("listItem") || this.editor.isActive("taskItem")) {
+ if (this.editor.commands.sinkListItem("listItem")) {
+ return true;
+ } else if (this.editor.commands.sinkListItem("taskItem")) {
+ return true;
+ }
+ return true;
+ }
+ // if tabIndex is set, we don't want to handle Tab key
+ if (tabIndex !== undefined && tabIndex !== null) {
+ return false;
+ }
+ return true;
+ },
+ "Shift-Tab": () => {
+ if (this.editor.commands.liftListItem("listItem")) {
+ return true;
+ } else if (this.editor.commands.liftListItem("taskItem")) {
+ return true;
+ }
+ return true;
+ },
+ Delete: ({ editor }) => {
+ try {
+ let handled = false;
+
+ this.options.listTypes.forEach(({ itemName }) => {
+ if (editor.state.schema.nodes[itemName] === undefined) {
+ return;
+ }
+
+ if (handleDelete(editor, itemName)) {
+ handled = true;
+ }
+ });
+
+ return handled;
+ } catch (e) {
+ console.log("Error in handling Delete:", e);
+ return false;
+ }
+ },
+ "Mod-Delete": ({ editor }) => {
+ let handled = false;
+
+ this.options.listTypes.forEach(({ itemName }) => {
+ if (editor.state.schema.nodes[itemName] === undefined) {
+ return;
+ }
+
+ if (handleDelete(editor, itemName)) {
+ handled = true;
+ }
+ });
+
+ return handled;
+ },
+ Backspace: ({ editor }) => {
+ try {
+ let handled = false;
+
+ this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
+ if (editor.state.schema.nodes[itemName] === undefined) {
+ return;
+ }
+
+ if (handleBackspace(editor, itemName, wrapperNames)) {
+ handled = true;
+ }
+ });
+
+ return handled;
+ } catch (e) {
+ console.log("Error in handling Backspace:", e);
+ return false;
+ }
+ },
+ "Mod-Backspace": ({ editor }) => {
+ let handled = false;
+
+ this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
+ if (editor.state.schema.nodes[itemName] === undefined) {
+ return;
+ }
+
+ if (handleBackspace(editor, itemName, wrapperNames)) {
+ handled = true;
+ }
+ });
+
+ return handled;
+ },
+ };
+ },
+ });
diff --git a/packages/editor/core/src/ui/extensions/drop.tsx b/packages/editor/core/src/ui/extensions/drop.tsx
new file mode 100644
index 0000000..4bf4e26
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/drop.tsx
@@ -0,0 +1,45 @@
+import { Extension } from "@tiptap/core";
+import { Plugin, PluginKey } from "prosemirror-state";
+import { UploadImage } from "src/types/upload-image";
+import { startImageUpload } from "src/ui/plugins/image/image-upload-handler";
+
+export const DropHandlerExtension = (uploadFile: UploadImage) =>
+ Extension.create({
+ name: "dropHandler",
+ priority: 1000,
+
+ addProseMirrorPlugins() {
+ return [
+ new Plugin({
+ key: new PluginKey("drop-handler-plugin"),
+ props: {
+ handlePaste: (view, event) => {
+ if (event.clipboardData && event.clipboardData.files && event.clipboardData.files[0]) {
+ event.preventDefault();
+ const file = event.clipboardData.files[0];
+ const pos = view.state.selection.from;
+ startImageUpload(this.editor, file, view, pos, uploadFile);
+ return true;
+ }
+ return false;
+ },
+ handleDrop: (view, event, _slice, moved) => {
+ if (!moved && event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files[0]) {
+ event.preventDefault();
+ const file = event.dataTransfer.files[0];
+ const coordinates = view.posAtCoords({
+ left: event.clientX,
+ top: event.clientY,
+ });
+ if (coordinates) {
+ startImageUpload(this.editor, file, view, coordinates.pos - 1, uploadFile);
+ }
+ return true;
+ }
+ return false;
+ },
+ },
+ }),
+ ];
+ },
+ });
diff --git a/packages/editor/core/src/ui/extensions/horizontal-rule/horizontal-rule.ts b/packages/editor/core/src/ui/extensions/horizontal-rule/horizontal-rule.ts
new file mode 100644
index 0000000..b9be1a3
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/horizontal-rule/horizontal-rule.ts
@@ -0,0 +1,122 @@
+import { isNodeSelection, mergeAttributes, Node, nodeInputRule } from "@tiptap/core";
+import { NodeSelection, TextSelection } from "@tiptap/pm/state";
+
+export interface HorizontalRuleOptions {
+ HTMLAttributes: Record;
+}
+
+declare module "@tiptap/core" {
+ interface Commands {
+ horizontalRule: {
+ /**
+ * Add a horizontal rule
+ */
+ setHorizontalRule: () => ReturnType;
+ };
+ }
+}
+
+export const CustomHorizontalRule = Node.create({
+ name: "horizontalRule",
+
+ addOptions() {
+ return {
+ HTMLAttributes: {},
+ };
+ },
+
+ group: "block",
+
+ parseHTML() {
+ return [
+ {
+ tag: `div[data-type="${this.name}"]`,
+ },
+ { tag: "hr" },
+ ];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return [
+ "div",
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
+ "data-type": this.name,
+ }),
+ ["div", {}],
+ ];
+ },
+
+ addCommands() {
+ return {
+ setHorizontalRule:
+ () =>
+ ({ chain, state }) => {
+ const { selection } = state;
+ const { $from: $originFrom, $to: $originTo } = selection;
+
+ const currentChain = chain();
+
+ if ($originFrom.parentOffset === 0) {
+ currentChain.insertContentAt(
+ {
+ from: Math.max($originFrom.pos - 1, 0),
+ to: $originTo.pos,
+ },
+ {
+ type: this.name,
+ }
+ );
+ } else if (isNodeSelection(selection)) {
+ currentChain.insertContentAt($originTo.pos, {
+ type: this.name,
+ });
+ } else {
+ currentChain.insertContent({ type: this.name });
+ }
+
+ return (
+ currentChain
+ // set cursor after horizontal rule
+ .command(({ tr, dispatch }) => {
+ if (dispatch) {
+ const { $to } = tr.selection;
+ const posAfter = $to.end();
+
+ if ($to.nodeAfter) {
+ if ($to.nodeAfter.isTextblock) {
+ tr.setSelection(TextSelection.create(tr.doc, $to.pos + 1));
+ } else if ($to.nodeAfter.isBlock) {
+ tr.setSelection(NodeSelection.create(tr.doc, $to.pos));
+ } else {
+ tr.setSelection(TextSelection.create(tr.doc, $to.pos));
+ }
+ } else {
+ // add node after horizontal rule if it’s the end of the document
+ const node = $to.parent.type.contentMatch.defaultType?.create();
+
+ if (node) {
+ tr.insert(posAfter, node);
+ tr.setSelection(TextSelection.create(tr.doc, posAfter + 1));
+ }
+ }
+
+ tr.scrollIntoView();
+ }
+
+ return true;
+ })
+ .run()
+ );
+ },
+ };
+ },
+
+ addInputRules() {
+ return [
+ nodeInputRule({
+ find: /^(?:---|—-|___\s|\*\*\*\s)$/,
+ type: this.type,
+ }),
+ ];
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/image/image-extension-without-props.tsx b/packages/editor/core/src/ui/extensions/image/image-extension-without-props.tsx
new file mode 100644
index 0000000..838a6a1
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/image/image-extension-without-props.tsx
@@ -0,0 +1,33 @@
+import ImageExt from "@tiptap/extension-image";
+import { insertLineBelowImageAction } from "./utilities/insert-line-below-image";
+import { insertLineAboveImageAction } from "./utilities/insert-line-above-image";
+
+export const ImageExtensionWithoutProps = () =>
+ ImageExt.extend({
+ addKeyboardShortcuts() {
+ return {
+ ArrowDown: insertLineBelowImageAction,
+ ArrowUp: insertLineAboveImageAction,
+ };
+ },
+
+ // storage to keep track of image states Map
+ addStorage() {
+ return {
+ images: new Map(),
+ uploadInProgress: false,
+ };
+ },
+
+ addAttributes() {
+ return {
+ ...this.parent?.(),
+ width: {
+ default: "35%",
+ },
+ height: {
+ default: null,
+ },
+ };
+ },
+ });
diff --git a/packages/editor/core/src/ui/extensions/image/image-resize.tsx b/packages/editor/core/src/ui/extensions/image/image-resize.tsx
new file mode 100644
index 0000000..7f61cc9
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/image/image-resize.tsx
@@ -0,0 +1,76 @@
+import { Editor } from "@tiptap/react";
+import { useState } from "react";
+import Moveable from "react-moveable";
+
+export const ImageResizer = ({ editor }: { editor: Editor }) => {
+ const updateMediaSize = () => {
+ const imageInfo = document.querySelector(".ProseMirror-selectednode") as HTMLImageElement;
+ if (imageInfo) {
+ const selection = editor.state.selection;
+
+ // Use the style width/height if available, otherwise fall back to the element's natural width/height
+ const width = imageInfo.style.width
+ ? Number(imageInfo.style.width.replace("px", ""))
+ : imageInfo.getAttribute("width");
+ const height = imageInfo.style.height
+ ? Number(imageInfo.style.height.replace("px", ""))
+ : imageInfo.getAttribute("height");
+
+ editor.commands.setImage({
+ src: imageInfo.src,
+ width: width,
+ height: height,
+ } as any);
+ editor.commands.setNodeSelection(selection.from);
+ }
+ };
+
+ const [aspectRatio, setAspectRatio] = useState(1);
+
+ return (
+ <>
+ {
+ const imageInfo = document.querySelector(".ProseMirror-selectednode") as HTMLImageElement;
+ if (imageInfo) {
+ const originalWidth = Number(imageInfo.width);
+ const originalHeight = Number(imageInfo.height);
+ setAspectRatio(originalWidth / originalHeight);
+ }
+ }}
+ onResize={({ target, width, height, delta }) => {
+ if (delta[0] || delta[1]) {
+ let newWidth, newHeight;
+ if (delta[0]) {
+ // Width change detected
+ newWidth = Math.max(width, 100);
+ newHeight = newWidth / aspectRatio;
+ } else if (delta[1]) {
+ // Height change detected
+ newHeight = Math.max(height, 100);
+ newWidth = newHeight * aspectRatio;
+ }
+ target.style.width = `${newWidth}px`;
+ target.style.height = `${newHeight}px`;
+ }
+ }}
+ onResizeEnd={() => {
+ updateMediaSize();
+ }}
+ scalable
+ renderDirections={["se"]}
+ onScale={({ target, transform }) => {
+ target.style.transform = transform;
+ }}
+ />
+ >
+ );
+};
diff --git a/packages/editor/core/src/ui/extensions/image/index.tsx b/packages/editor/core/src/ui/extensions/image/index.tsx
new file mode 100644
index 0000000..7ea12fb
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/image/index.tsx
@@ -0,0 +1,64 @@
+import { UploadImagesPlugin } from "src/ui/plugins/image/upload-image";
+import ImageExt from "@tiptap/extension-image";
+import { TrackImageDeletionPlugin } from "src/ui/plugins/image/delete-image";
+import { DeleteImage } from "src/types/delete-image";
+import { RestoreImage } from "src/types/restore-image";
+import { insertLineBelowImageAction } from "./utilities/insert-line-below-image";
+import { insertLineAboveImageAction } from "./utilities/insert-line-above-image";
+import { TrackImageRestorationPlugin } from "src/ui/plugins/image/restore-image";
+import { IMAGE_NODE_TYPE } from "src/ui/plugins/image/constants";
+import { ImageExtensionStorage } from "src/ui/plugins/image/types/image-node";
+
+export const ImageExtension = (deleteImage: DeleteImage, restoreImage: RestoreImage, cancelUploadImage?: () => void) =>
+ ImageExt.extend({
+ addKeyboardShortcuts() {
+ return {
+ ArrowDown: insertLineBelowImageAction,
+ ArrowUp: insertLineAboveImageAction,
+ };
+ },
+ addProseMirrorPlugins() {
+ return [
+ UploadImagesPlugin(this.editor, cancelUploadImage),
+ TrackImageDeletionPlugin(this.editor, deleteImage),
+ TrackImageRestorationPlugin(this.editor, restoreImage),
+ ];
+ },
+
+ onCreate(this) {
+ const imageSources = new Set();
+ this.editor.state.doc.descendants((node) => {
+ if (node.type.name === IMAGE_NODE_TYPE) {
+ imageSources.add(node.attrs.src);
+ }
+ });
+ imageSources.forEach(async (src) => {
+ try {
+ const assetUrlWithWorkspaceId = new URL(src).pathname.substring(1);
+ await restoreImage(assetUrlWithWorkspaceId);
+ } catch (error) {
+ console.error("Error restoring image: ", error);
+ }
+ });
+ },
+
+ // storage to keep track of image states Map
+ addStorage() {
+ return {
+ deletedImageSet: new Map(),
+ uploadInProgress: false,
+ };
+ },
+
+ addAttributes() {
+ return {
+ ...this.parent?.(),
+ width: {
+ default: "35%",
+ },
+ height: {
+ default: null,
+ },
+ };
+ },
+ });
diff --git a/packages/editor/core/src/ui/extensions/image/read-only-image.tsx b/packages/editor/core/src/ui/extensions/image/read-only-image.tsx
new file mode 100644
index 0000000..8112eba
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/image/read-only-image.tsx
@@ -0,0 +1,15 @@
+import Image from "@tiptap/extension-image";
+
+export const ReadOnlyImageExtension = Image.extend({
+ addAttributes() {
+ return {
+ ...this.parent?.(),
+ width: {
+ default: "35%",
+ },
+ height: {
+ default: null,
+ },
+ };
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/image/utilities/insert-line-above-image.ts b/packages/editor/core/src/ui/extensions/image/utilities/insert-line-above-image.ts
new file mode 100644
index 0000000..205ec96
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/image/utilities/insert-line-above-image.ts
@@ -0,0 +1,52 @@
+import { Node as ProseMirrorNode } from "@tiptap/pm/model";
+import { KeyboardShortcutCommand } from "@tiptap/core";
+
+export const insertLineAboveImageAction: KeyboardShortcutCommand = ({ editor }) => {
+ try {
+ const { selection, doc } = editor.state;
+ const { $from, $to } = selection;
+
+ let imageNode: ProseMirrorNode | null = null;
+ let imagePos: number | null = null;
+
+ // Check if the selection itself is an image node
+ doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
+ if (node.type.name === "image") {
+ imageNode = node;
+ imagePos = pos;
+ return false; // Stop iterating once an image node is found
+ }
+ return true;
+ });
+
+ if (imageNode === null || imagePos === null) return false;
+
+ // Since we want to insert above the image, we use the imagePos directly
+ const insertPos = imagePos;
+
+ const docSize = editor.state.doc.content.size;
+
+ if (insertPos < 0 || insertPos > docSize) return false;
+
+ // Check for an existing node immediately before the image
+ if (insertPos === 0) {
+ // If the previous node doesn't exist or isn't a paragraph, create and insert a new empty node there
+ editor.chain().insertContentAt(insertPos, { type: "paragraph" }).run();
+ editor.chain().setTextSelection(insertPos).run();
+ } else {
+ const prevNode = doc.nodeAt(insertPos);
+
+ if (prevNode && prevNode.type.name === "paragraph") {
+ // If the previous node is a paragraph, move the cursor there
+ editor.chain().setTextSelection(insertPos).run();
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+ } catch (error) {
+ console.error("An error occurred while inserting a line above the image:", error);
+ return false;
+ }
+};
diff --git a/packages/editor/core/src/ui/extensions/image/utilities/insert-line-below-image.ts b/packages/editor/core/src/ui/extensions/image/utilities/insert-line-below-image.ts
new file mode 100644
index 0000000..fe06ea0
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/image/utilities/insert-line-below-image.ts
@@ -0,0 +1,51 @@
+import { Node as ProseMirrorNode } from "@tiptap/pm/model";
+import { KeyboardShortcutCommand } from "@tiptap/core";
+
+export const insertLineBelowImageAction: KeyboardShortcutCommand = ({ editor }) => {
+ try {
+ const { selection, doc } = editor.state;
+ const { $from, $to } = selection;
+
+ let imageNode: ProseMirrorNode | null = null;
+ let imagePos: number | null = null;
+
+ // Check if the selection itself is an image node
+ doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
+ if (node.type.name === "image") {
+ imageNode = node;
+ imagePos = pos;
+ return false; // Stop iterating once an image node is found
+ }
+ return true;
+ });
+
+ if (imageNode === null || imagePos === null) return false;
+
+ const guaranteedImageNode: ProseMirrorNode = imageNode;
+ const nextNodePos = imagePos + guaranteedImageNode.nodeSize;
+
+ // Check for an existing node immediately after the image
+ const nextNode = doc.nodeAt(nextNodePos);
+
+ if (nextNode && nextNode.type.name === "paragraph") {
+ // If the next node is a paragraph, move the cursor there
+ const endOfParagraphPos = nextNodePos + nextNode.nodeSize - 1;
+ editor.chain().setTextSelection(endOfParagraphPos).run();
+ } else if (!nextNode) {
+ // If the next node doesn't exist i.e. we're at the end of the document, create and insert a new empty node there
+ editor.chain().insertContentAt(nextNodePos, { type: "paragraph" }).run();
+ editor
+ .chain()
+ .setTextSelection(nextNodePos + 1)
+ .run();
+ } else {
+ // If the next node is not a paragraph, do not proceed
+ return false;
+ }
+
+ return true;
+ } catch (error) {
+ console.error("An error occurred while inserting a line below the image:", error);
+ return false;
+ }
+};
diff --git a/packages/editor/core/src/ui/extensions/index.tsx b/packages/editor/core/src/ui/extensions/index.tsx
new file mode 100644
index 0000000..2507aca
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/index.tsx
@@ -0,0 +1,160 @@
+import TaskItem from "@tiptap/extension-task-item";
+import TaskList from "@tiptap/extension-task-list";
+import TextStyle from "@tiptap/extension-text-style";
+import TiptapUnderline from "@tiptap/extension-underline";
+import Placeholder from "@tiptap/extension-placeholder";
+import StarterKit from "@tiptap/starter-kit";
+import { Markdown } from "tiptap-markdown";
+
+import { Table } from "src/ui/extensions/table/table";
+import { TableCell } from "src/ui/extensions/table/table-cell/table-cell";
+import { TableHeader } from "src/ui/extensions/table/table-header/table-header";
+import { TableRow } from "src/ui/extensions/table/table-row/table-row";
+
+import { ImageExtension } from "src/ui/extensions/image";
+
+import { isValidHttpUrl } from "src/lib/utils";
+import { Mentions } from "src/ui/mentions";
+
+import { CustomCodeBlockExtension } from "src/ui/extensions/code";
+import { ListKeymap } from "src/ui/extensions/custom-list-keymap";
+import { CustomKeymap } from "src/ui/extensions/keymap";
+import { CustomQuoteExtension } from "src/ui/extensions/quote";
+
+import { DeleteImage } from "src/types/delete-image";
+import { IMentionHighlight, IMentionSuggestion } from "src/types/mention-suggestion";
+import { RestoreImage } from "src/types/restore-image";
+import { CustomLinkExtension } from "src/ui/extensions/custom-link";
+import { CustomCodeInlineExtension } from "src/ui/extensions/code-inline";
+import { CustomTypographyExtension } from "src/ui/extensions/typography";
+import { CustomHorizontalRule } from "src/ui/extensions/horizontal-rule/horizontal-rule";
+import { CustomCodeMarkPlugin } from "src/ui/extensions/custom-code-inline/inline-code-plugin";
+import { UploadImage } from "src/types/upload-image";
+import { DropHandlerExtension } from "src/ui/extensions/drop";
+
+type TArguments = {
+ mentionConfig: {
+ mentionSuggestions?: () => Promise;
+ mentionHighlights?: () => Promise;
+ };
+ fileConfig: {
+ deleteFile: DeleteImage;
+ restoreFile: RestoreImage;
+ cancelUploadImage?: () => void;
+ uploadFile: UploadImage;
+ };
+ placeholder?: string | ((isFocused: boolean, value: string) => string);
+ tabIndex?: number;
+};
+
+export const CoreEditorExtensions = ({
+ mentionConfig,
+ fileConfig: { deleteFile, restoreFile, cancelUploadImage, uploadFile },
+ placeholder,
+ tabIndex,
+}: TArguments) => [
+ StarterKit.configure({
+ bulletList: {
+ HTMLAttributes: {
+ class: "list-disc pl-7 space-y-2",
+ },
+ },
+ orderedList: {
+ HTMLAttributes: {
+ class: "list-decimal pl-7 space-y-2",
+ },
+ },
+ listItem: {
+ HTMLAttributes: {
+ class: "not-prose space-y-2",
+ },
+ },
+ code: false,
+ codeBlock: false,
+ horizontalRule: false,
+ blockquote: false,
+ dropcursor: {
+ color: "rgba(var(--color-text-100))",
+ width: 1,
+ },
+ }),
+ CustomQuoteExtension,
+ DropHandlerExtension(uploadFile),
+ CustomHorizontalRule.configure({
+ HTMLAttributes: {
+ class: "my-4 border-custom-border-400",
+ },
+ }),
+ CustomKeymap,
+ ListKeymap({ tabIndex }),
+ CustomLinkExtension.configure({
+ openOnClick: true,
+ autolink: true,
+ linkOnPaste: true,
+ protocols: ["http", "https"],
+ validate: (url: string) => isValidHttpUrl(url),
+ HTMLAttributes: {
+ class:
+ "text-custom-primary-300 underline underline-offset-[3px] hover:text-custom-primary-500 transition-colors cursor-pointer",
+ },
+ }),
+ CustomTypographyExtension,
+ ImageExtension(deleteFile, restoreFile, cancelUploadImage).configure({
+ HTMLAttributes: {
+ class: "rounded-md",
+ },
+ }),
+ TiptapUnderline,
+ TextStyle,
+ TaskList.configure({
+ HTMLAttributes: {
+ class: "not-prose pl-2 space-y-2",
+ },
+ }),
+ TaskItem.configure({
+ HTMLAttributes: {
+ class: "relative",
+ },
+ nested: true,
+ }),
+ CustomCodeBlockExtension.configure({
+ HTMLAttributes: {
+ class: "",
+ },
+ }),
+ CustomCodeMarkPlugin,
+ CustomCodeInlineExtension,
+ Markdown.configure({
+ html: true,
+ transformPastedText: true,
+ }),
+ Table,
+ TableHeader,
+ TableCell,
+ TableRow,
+ Mentions({
+ mentionSuggestions: mentionConfig.mentionSuggestions,
+ mentionHighlights: mentionConfig.mentionHighlights,
+ readonly: false,
+ }),
+ Placeholder.configure({
+ placeholder: ({ editor, node }) => {
+ if (node.type.name === "heading") return `Heading ${node.attrs.level}`;
+
+ if (editor.storage.image.uploadInProgress) return "";
+
+ const shouldHidePlaceholder =
+ editor.isActive("table") || editor.isActive("codeBlock") || editor.isActive("image");
+
+ if (shouldHidePlaceholder) return "";
+
+ if (placeholder) {
+ if (typeof placeholder === "string") return placeholder;
+ else return placeholder(editor.isFocused, editor.getHTML());
+ }
+
+ return "Press '/' for commands...";
+ },
+ includeChildren: true,
+ }),
+];
diff --git a/packages/editor/core/src/ui/extensions/keymap.tsx b/packages/editor/core/src/ui/extensions/keymap.tsx
new file mode 100644
index 0000000..43b4e34
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/keymap.tsx
@@ -0,0 +1,126 @@
+import { Extension } from "@tiptap/core";
+import { Plugin, PluginKey, Transaction } from "@tiptap/pm/state";
+import { canJoin } from "@tiptap/pm/transform";
+import { NodeType } from "@tiptap/pm/model";
+
+declare module "@tiptap/core" {
+ // eslint-disable-next-line no-unused-vars
+ interface Commands {
+ customkeymap: {
+ /**
+ * Select text between node boundaries
+ */
+ selectTextWithinNodeBoundaries: () => ReturnType;
+ };
+ }
+}
+
+function autoJoin(tr: Transaction, newTr: Transaction, nodeTypes: NodeType[]) {
+ // Find all ranges where we might want to join.
+ const ranges: Array = [];
+ for (let i = 0; i < tr.mapping.maps.length; i++) {
+ const map = tr.mapping.maps[i];
+ for (let j = 0; j < ranges.length; j++) ranges[j] = map.map(ranges[j]);
+ map.forEach((_s, _e, from, to) => ranges.push(from, to));
+ }
+
+ // Figure out which joinable points exist inside those ranges,
+ // by checking all node boundaries in their parent nodes.
+ const joinable: number[] = [];
+ for (let i = 0; i < ranges.length; i += 2) {
+ const from = ranges[i],
+ to = ranges[i + 1];
+ const $from = tr.doc.resolve(from),
+ depth = $from.sharedDepth(to),
+ parent = $from.node(depth);
+ for (let index = $from.indexAfter(depth), pos = $from.after(depth + 1); pos <= to; ++index) {
+ const after = parent.maybeChild(index);
+ if (!after) break;
+ if (index && joinable.indexOf(pos) == -1) {
+ const before = parent.child(index - 1);
+ if (before.type == after.type && nodeTypes.includes(before.type)) joinable.push(pos);
+ }
+ pos += after.nodeSize;
+ }
+ }
+
+ let joined = false;
+
+ // Join the joinable points
+ joinable.sort((a, b) => a - b);
+ for (let i = joinable.length - 1; i >= 0; i--) {
+ if (canJoin(tr.doc, joinable[i])) {
+ newTr.join(joinable[i]);
+ joined = true;
+ }
+ }
+
+ return joined;
+}
+
+export const CustomKeymap = Extension.create({
+ name: "CustomKeymap",
+
+ addCommands() {
+ return {
+ selectTextWithinNodeBoundaries:
+ () =>
+ ({ editor, commands }) => {
+ const { state } = editor;
+ const { tr } = state;
+ const startNodePos = tr.selection.$from.start();
+ const endNodePos = tr.selection.$to.end();
+ return commands.setTextSelection({
+ from: startNodePos,
+ to: endNodePos,
+ });
+ },
+ };
+ },
+
+ addProseMirrorPlugins() {
+ return [
+ new Plugin({
+ key: new PluginKey("ordered-list-merging"),
+ appendTransaction(transactions, oldState, newState) {
+ // Create a new transaction.
+ const newTr = newState.tr;
+
+ const joinableNodes = [
+ newState.schema.nodes["orderedList"],
+ newState.schema.nodes["taskList"],
+ newState.schema.nodes["bulletList"],
+ ];
+
+ let joined = false;
+ for (const transaction of transactions) {
+ const anotherJoin = autoJoin(transaction, newTr, joinableNodes);
+ joined = anotherJoin || joined;
+ }
+ if (joined) {
+ return newTr;
+ }
+ },
+ }),
+ ];
+ },
+ addKeyboardShortcuts() {
+ return {
+ "Mod-a": ({ editor }) => {
+ const { state } = editor;
+ const { tr } = state;
+ const startSelectionPos = tr.selection.from;
+ const endSelectionPos = tr.selection.to;
+ const startNodePos = tr.selection.$from.start();
+ const endNodePos = tr.selection.$to.end();
+ const isCurrentTextSelectionNotExtendedToNodeBoundaries =
+ startSelectionPos > startNodePos || endSelectionPos < endNodePos;
+ if (isCurrentTextSelectionNotExtendedToNodeBoundaries) {
+ editor.chain().selectTextWithinNodeBoundaries().run();
+ return true;
+ }
+ return false;
+ },
+ };
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/quote/index.tsx b/packages/editor/core/src/ui/extensions/quote/index.tsx
new file mode 100644
index 0000000..4ae81ff
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/quote/index.tsx
@@ -0,0 +1,30 @@
+import Blockquote from "@tiptap/extension-blockquote";
+
+export const CustomQuoteExtension = Blockquote.extend({
+ addKeyboardShortcuts() {
+ return {
+ Enter: () => {
+ try {
+ const { $from, $to, $head } = this.editor.state.selection;
+ const parent = $head.node(-1);
+
+ if (!parent) return false;
+
+ if (parent.type.name !== "blockquote") {
+ return false;
+ }
+ if ($from.pos !== $to.pos) return false;
+ // if ($head.parentOffset < $head.parent.content.size) return false;
+
+ // this.editor.commands.insertContentAt(parent.ne);
+ this.editor.chain().splitBlock().lift(this.name).run();
+
+ return true;
+ } catch (error) {
+ console.error("Error handling Enter in blockquote:", error);
+ return false;
+ }
+ },
+ };
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/table/table-cell/index.ts b/packages/editor/core/src/ui/extensions/table/table-cell/index.ts
new file mode 100644
index 0000000..68a25a9
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/table/table-cell/index.ts
@@ -0,0 +1 @@
+export { TableCell } from "./table-cell";
diff --git a/packages/editor/core/src/ui/extensions/table/table-cell/table-cell.ts b/packages/editor/core/src/ui/extensions/table/table-cell/table-cell.ts
new file mode 100644
index 0000000..403bd3f
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/table/table-cell/table-cell.ts
@@ -0,0 +1,61 @@
+import { mergeAttributes, Node } from "@tiptap/core";
+
+export interface TableCellOptions {
+ HTMLAttributes: Record;
+}
+
+export const TableCell = Node.create({
+ name: "tableCell",
+
+ addOptions() {
+ return {
+ HTMLAttributes: {},
+ };
+ },
+
+ content: "block+",
+
+ addAttributes() {
+ return {
+ colspan: {
+ default: 1,
+ },
+ rowspan: {
+ default: 1,
+ },
+ colwidth: {
+ default: null,
+ parseHTML: (element) => {
+ const colwidth = element.getAttribute("colwidth");
+ const value = colwidth ? [parseInt(colwidth, 10)] : null;
+
+ return value;
+ },
+ },
+ background: {
+ default: null,
+ },
+ textColor: {
+ default: null,
+ },
+ };
+ },
+
+ tableRole: "cell",
+
+ isolating: true,
+
+ parseHTML() {
+ return [{ tag: "td" }];
+ },
+
+ renderHTML({ node, HTMLAttributes }) {
+ return [
+ "td",
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
+ style: `background-color: ${node.attrs.background}; color: ${node.attrs.textColor}`,
+ }),
+ 0,
+ ];
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/table/table-header/index.ts b/packages/editor/core/src/ui/extensions/table/table-header/index.ts
new file mode 100644
index 0000000..290f37d
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/table/table-header/index.ts
@@ -0,0 +1 @@
+export { TableHeader } from "./table-header";
diff --git a/packages/editor/core/src/ui/extensions/table/table-header/table-header.ts b/packages/editor/core/src/ui/extensions/table/table-header/table-header.ts
new file mode 100644
index 0000000..bd994f4
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/table/table-header/table-header.ts
@@ -0,0 +1,58 @@
+import { mergeAttributes, Node } from "@tiptap/core";
+
+export interface TableHeaderOptions {
+ HTMLAttributes: Record;
+}
+
+export const TableHeader = Node.create({
+ name: "tableHeader",
+
+ addOptions() {
+ return {
+ HTMLAttributes: {},
+ };
+ },
+
+ content: "paragraph+",
+
+ addAttributes() {
+ return {
+ colspan: {
+ default: 1,
+ },
+ rowspan: {
+ default: 1,
+ },
+ colwidth: {
+ default: null,
+ parseHTML: (element) => {
+ const colwidth = element.getAttribute("colwidth");
+ const value = colwidth ? [parseInt(colwidth, 10)] : null;
+
+ return value;
+ },
+ },
+ background: {
+ default: "none",
+ },
+ };
+ },
+
+ tableRole: "header_cell",
+
+ isolating: true,
+
+ parseHTML() {
+ return [{ tag: "th" }];
+ },
+
+ renderHTML({ node, HTMLAttributes }) {
+ return [
+ "th",
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
+ style: `background-color: ${node.attrs.background}`,
+ }),
+ 0,
+ ];
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/table/table-row/index.ts b/packages/editor/core/src/ui/extensions/table/table-row/index.ts
new file mode 100644
index 0000000..24dafb7
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/table/table-row/index.ts
@@ -0,0 +1 @@
+export { TableRow } from "./table-row";
diff --git a/packages/editor/core/src/ui/extensions/table/table-row/table-row.ts b/packages/editor/core/src/ui/extensions/table/table-row/table-row.ts
new file mode 100644
index 0000000..f961c05
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/table/table-row/table-row.ts
@@ -0,0 +1,44 @@
+import { mergeAttributes, Node } from "@tiptap/core";
+
+export interface TableRowOptions {
+ HTMLAttributes: Record;
+}
+
+export const TableRow = Node.create({
+ name: "tableRow",
+
+ addOptions() {
+ return {
+ HTMLAttributes: {},
+ };
+ },
+
+ addAttributes() {
+ return {
+ background: {
+ default: null,
+ },
+ textColor: {
+ default: null,
+ },
+ };
+ },
+
+ content: "(tableCell | tableHeader)*",
+
+ tableRole: "row",
+
+ parseHTML() {
+ return [{ tag: "tr" }];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ const style = HTMLAttributes.background
+ ? `background-color: ${HTMLAttributes.background}; color: ${HTMLAttributes.textColor}`
+ : "";
+
+ const attributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { style });
+
+ return ["tr", attributes, 0];
+ },
+});
diff --git a/packages/editor/core/src/ui/extensions/table/table/icons.ts b/packages/editor/core/src/ui/extensions/table/table/icons.ts
new file mode 100644
index 0000000..51c7784
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/table/table/icons.ts
@@ -0,0 +1,51 @@
+export const icons = {
+ colorPicker: ``,
+ deleteColumn: ``,
+ deleteRow: ``,
+ insertLeftTableIcon: `
+`,
+ insertRightTableIcon: `
+`,
+ insertTopTableIcon: `
+`,
+ toggleColumnHeader: ``,
+ toggleRowHeader: ``,
+ insertBottomTableIcon: `
+`,
+};
diff --git a/packages/editor/core/src/ui/extensions/table/table/index.ts b/packages/editor/core/src/ui/extensions/table/table/index.ts
new file mode 100644
index 0000000..8efc431
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/table/table/index.ts
@@ -0,0 +1 @@
+export { Table } from "./table";
diff --git a/packages/editor/core/src/ui/extensions/table/table/table-controls.ts b/packages/editor/core/src/ui/extensions/table/table/table-controls.ts
new file mode 100644
index 0000000..34ad93f
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/table/table/table-controls.ts
@@ -0,0 +1,112 @@
+import { Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
+import { findParentNode } from "@tiptap/core";
+import { DecorationSet, Decoration } from "@tiptap/pm/view";
+
+const key = new PluginKey("tableControls");
+
+export function tableControls() {
+ return new Plugin({
+ key,
+ state: {
+ init() {
+ return new TableControlsState();
+ },
+ apply(tr, prev) {
+ return prev.apply(tr);
+ },
+ },
+ props: {
+ handleDOMEvents: {
+ mousemove: (view, event) => {
+ const pluginState = key.getState(view.state);
+
+ if (!(event.target as HTMLElement).closest(".table-wrapper") && pluginState.values.hoveredTable) {
+ return view.dispatch(
+ view.state.tr.setMeta(key, {
+ setHoveredTable: null,
+ setHoveredCell: null,
+ })
+ );
+ }
+
+ const pos = view.posAtCoords({
+ left: event.clientX,
+ top: event.clientY,
+ });
+
+ if (!pos || pos.pos < 0 || pos.pos > view.state.doc.content.size) return;
+
+ const table = findParentNode((node) => node.type.name === "table")(
+ TextSelection.create(view.state.doc, pos.pos)
+ );
+ const cell = findParentNode((node) => node.type.name === "tableCell" || node.type.name === "tableHeader")(
+ TextSelection.create(view.state.doc, pos.pos)
+ );
+
+ if (!table || !cell) return;
+
+ if (pluginState.values.hoveredCell?.pos !== cell.pos) {
+ return view.dispatch(
+ view.state.tr.setMeta(key, {
+ setHoveredTable: table,
+ setHoveredCell: cell,
+ })
+ );
+ }
+ },
+ },
+ decorations: (state) => {
+ const pluginState = key.getState(state);
+ if (!pluginState) {
+ return null;
+ }
+
+ const { hoveredTable, hoveredCell } = pluginState.values;
+ const docSize = state.doc.content.size;
+ if (hoveredTable && hoveredCell && hoveredTable.pos < docSize && hoveredCell.pos < docSize) {
+ const decorations = [
+ Decoration.node(
+ hoveredTable.pos,
+ hoveredTable.pos + hoveredTable.node.nodeSize,
+ {},
+ {
+ hoveredTable,
+ hoveredCell,
+ }
+ ),
+ ];
+
+ return DecorationSet.create(state.doc, decorations);
+ }
+
+ return null;
+ },
+ },
+ });
+}
+
+class TableControlsState {
+ values;
+
+ constructor(props = {}) {
+ this.values = {
+ hoveredTable: null,
+ hoveredCell: null,
+ ...props,
+ };
+ }
+
+ apply(tr: any) {
+ const actions = tr.getMeta(key);
+
+ if (actions?.setHoveredTable !== undefined) {
+ this.values.hoveredTable = actions.setHoveredTable;
+ }
+
+ if (actions?.setHoveredCell !== undefined) {
+ this.values.hoveredCell = actions.setHoveredCell;
+ }
+
+ return this;
+ }
+}
diff --git a/packages/editor/core/src/ui/extensions/table/table/table-view.tsx b/packages/editor/core/src/ui/extensions/table/table/table-view.tsx
new file mode 100644
index 0000000..d4dfcf5
--- /dev/null
+++ b/packages/editor/core/src/ui/extensions/table/table/table-view.tsx
@@ -0,0 +1,491 @@
+import { h } from "jsx-dom-cjs";
+import { Node as ProseMirrorNode, ResolvedPos } from "@tiptap/pm/model";
+import { Decoration, NodeView } from "@tiptap/pm/view";
+import tippy, { Instance, Props } from "tippy.js";
+
+import { Editor } from "@tiptap/core";
+import { CellSelection, TableMap, updateColumnsOnResize } from "@tiptap/pm/tables";
+
+import { icons } from "src/ui/extensions/table/table/icons";
+
+type ToolboxItem = {
+ label: string;
+ icon: string;
+ action: (args: any) => void;
+};
+
+export function updateColumns(
+ node: ProseMirrorNode,
+ colgroup: HTMLElement,
+ table: HTMLElement,
+ cellMinWidth: number,
+ overrideCol?: number,
+ overrideValue?: any
+) {
+ let totalWidth = 0;
+ let fixedWidth = true;
+ let nextDOM = colgroup.firstChild as HTMLElement;
+ const row = node.firstChild;
+
+ if (!row) return;
+
+ for (let i = 0, col = 0; i < row.childCount; i += 1) {
+ const { colspan, colwidth } = row.child(i).attrs;
+
+ for (let j = 0; j < colspan; j += 1, col += 1) {
+ const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j];
+ const cssWidth = hasWidth ? `${hasWidth}px` : "";
+
+ totalWidth += hasWidth || cellMinWidth;
+
+ if (!hasWidth) {
+ fixedWidth = false;
+ }
+
+ if (!nextDOM) {
+ colgroup.appendChild(document.createElement("col")).style.width = cssWidth;
+ } else {
+ if (nextDOM.style.width !== cssWidth) {
+ nextDOM.style.width = cssWidth;
+ }
+
+ nextDOM = nextDOM.nextSibling as HTMLElement;
+ }
+ }
+ }
+
+ while (nextDOM) {
+ const after = nextDOM.nextSibling;
+
+ nextDOM.parentNode?.removeChild(nextDOM);
+ nextDOM = after as HTMLElement;
+ }
+
+ if (fixedWidth) {
+ table.style.width = `${totalWidth}px`;
+ table.style.minWidth = "";
+ } else {
+ table.style.width = "";
+ table.style.minWidth = `${totalWidth}px`;
+ }
+}
+
+const defaultTippyOptions: Partial = {
+ allowHTML: true,
+ arrow: false,
+ trigger: "click",
+ animation: "scale-subtle",
+ theme: "light-border no-padding",
+ interactive: true,
+ hideOnClick: true,
+ placement: "right",
+};
+
+function setCellsBackgroundColor(editor: Editor, color: { backgroundColor: string; textColor: string }) {
+ return editor
+ .chain()
+ .focus()
+ .updateAttributes("tableCell", {
+ background: color.backgroundColor,
+ textColor: color.textColor,
+ })
+ .run();
+}
+
+function setTableRowBackgroundColor(editor: Editor, color: { backgroundColor: string; textColor: string }) {
+ const { state, dispatch } = editor.view;
+ const { selection } = state;
+ if (!(selection instanceof CellSelection)) {
+ return false;
+ }
+
+ // Get the position of the hovered cell in the selection to determine the row.
+ const hoveredCell = selection.$headCell || selection.$anchorCell;
+
+ // Find the depth of the table row node
+ let rowDepth = hoveredCell.depth;
+ while (rowDepth > 0 && hoveredCell.node(rowDepth).type.name !== "tableRow") {
+ rowDepth--;
+ }
+
+ // If we couldn't find a tableRow node, we can't set the background color
+ if (hoveredCell.node(rowDepth).type.name !== "tableRow") {
+ return false;
+ }
+
+ // Get the position where the table row starts
+ const rowStartPos = hoveredCell.start(rowDepth);
+
+ // Create a transaction that sets the background color on the tableRow node.
+ const tr = state.tr.setNodeMarkup(rowStartPos - 1, null, {
+ ...hoveredCell.node(rowDepth).attrs,
+ background: color.backgroundColor,
+ textColor: color.textColor,
+ });
+
+ dispatch(tr);
+ return true;
+}
+
+const columnsToolboxItems: ToolboxItem[] = [
+ {
+ label: "Toggle column header",
+ icon: icons.toggleColumnHeader,
+ action: ({ editor }: { editor: Editor }) => editor.chain().focus().toggleHeaderColumn().run(),
+ },
+ {
+ label: "Add column before",
+ icon: icons.insertLeftTableIcon,
+ action: ({ editor }: { editor: Editor }) => editor.chain().focus().addColumnBefore().run(),
+ },
+ {
+ label: "Add column after",
+ icon: icons.insertRightTableIcon,
+ action: ({ editor }: { editor: Editor }) => editor.chain().focus().addColumnAfter().run(),
+ },
+ {
+ label: "Pick color",
+ icon: "", // No icon needed for color picker
+ action: (args: any) => {}, // Placeholder action; actual color picking is handled in `createToolbox`
+ },
+ {
+ label: "Delete column",
+ icon: icons.deleteColumn,
+ action: ({ editor }: { editor: Editor }) => editor.chain().focus().deleteColumn().run(),
+ },
+];
+
+const rowsToolboxItems: ToolboxItem[] = [
+ {
+ label: "Toggle row header",
+ icon: icons.toggleRowHeader,
+ action: ({ editor }: { editor: Editor }) => editor.chain().focus().toggleHeaderRow().run(),
+ },
+ {
+ label: "Add row above",
+ icon: icons.insertTopTableIcon,
+ action: ({ editor }: { editor: Editor }) => editor.chain().focus().addRowBefore().run(),
+ },
+ {
+ label: "Add row below",
+ icon: icons.insertBottomTableIcon,
+ action: ({ editor }: { editor: Editor }) => editor.chain().focus().addRowAfter().run(),
+ },
+ {
+ label: "Pick color",
+ icon: "",
+ action: (args: any) => {}, // Placeholder action; actual color picking is handled in `createToolbox`
+ },
+ {
+ label: "Delete row",
+ icon: icons.deleteRow,
+ action: ({ editor }: { editor: Editor }) => editor.chain().focus().deleteRow().run(),
+ },
+];
+
+function createToolbox({
+ triggerButton,
+ items,
+ tippyOptions,
+ onSelectColor,
+ onClickItem,
+ colors,
+}: {
+ triggerButton: Element | null;
+ items: ToolboxItem[];
+ tippyOptions: any;
+ onClickItem: (item: ToolboxItem) => void;
+ onSelectColor: (color: { backgroundColor: string; textColor: string }) => void;
+ colors: { [key: string]: { backgroundColor: string; textColor: string; icon?: string } };
+}): Instance {
+ // @ts-expect-error
+ const toolbox = tippy(triggerButton, {
+ content: h(
+ "div",
+ {
+ className:
+ "rounded-md border-[0.5px] border-custom-border-300 bg-custom-background-100 px-2 py-2.5 text-xs shadow-custom-shadow-rg min-w-[12rem] whitespace-nowrap",
+ },
+ items.map((item) => {
+ if (item.label === "Pick color") {
+ return h("div", { className: "flex flex-col" }, [
+ h("hr", { className: "my-2 border-custom-border-200" }),
+ h("div", { className: "text-custom-text-200 text-sm" }, item.label),
+ h(
+ "div",
+ { className: "grid grid-cols-6 gap-x-1 gap-y-2.5 mt-2" },
+ Object.entries(colors).map(([colorName, colorValue]) =>
+ h("div", {
+ className: "grid place-items-center size-6 rounded cursor-pointer",
+ style: `background-color: ${colorValue.backgroundColor};color: ${colorValue.textColor || "inherit"};`,
+ innerHTML:
+ colorValue.icon ?? `