From 2ce572a5399f2a6aa86ce9dbc80f04c9e1b45af6 Mon Sep 17 00:00:00 2001 From: Karol Chudzik Date: Tue, 12 Nov 2024 21:25:35 +0100 Subject: [PATCH] feat(markdown-renderer): add syntax highlighting --- apps/www/package.json | 2 +- apps/www/public/r/index.json | 21 +- apps/www/public/r/markdown-renderer.json | 23 +- .../registry/default/ui/markdown-renderer.tsx | 98 +++++- apps/www/registry/index.ts | 18 +- pnpm-lock.yaml | 298 ++---------------- tailwind.config.cjs | 6 + 7 files changed, 184 insertions(+), 282 deletions(-) diff --git a/apps/www/package.json b/apps/www/package.json index b8c6f3fd..30630098 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -64,6 +64,7 @@ "remark-code-import": "^1.2.0", "remark-gfm": "^4.0.0", "remeda": "^2.14.0", + "shiki": "^1.22.0", "sonner": "^1.2.3", "tailwind-merge": "^1.12.0", "ts-morph": "^22.0.0", @@ -79,7 +80,6 @@ "postcss": "^8.4.24", "remark": "^14.0.3", "rimraf": "^4.1.3", - "shiki": "^1.10.1", "tailwindcss": "3.4.6", "typescript": "^5.5.3", "unist-builder": "3.0.0", diff --git a/apps/www/public/r/index.json b/apps/www/public/r/index.json index d81401ed..f4277c57 100644 --- a/apps/www/public/r/index.json +++ b/apps/www/public/r/index.json @@ -51,14 +51,31 @@ "type": "registry:ui", "dependencies": [ "react-markdown", - "remark-gfm" + "remark-gfm", + "shiki" ], "files": [ { "path": "ui/markdown-renderer.tsx", "type": "registry:ui" } - ] + ], + "tailwind": { + "config": { + "theme": { + "extend": { + "colors": { + "shiki": { + "light": "var(--shiki-light)", + "light-bg": "var(--shiki-light-bg)", + "dark": "var(--shiki-dark)", + "dark-bg": "var(--shiki-dark-bg)" + } + } + } + } + } + } }, { "name": "message-input", diff --git a/apps/www/public/r/markdown-renderer.json b/apps/www/public/r/markdown-renderer.json index c8439ee9..71ee837a 100644 --- a/apps/www/public/r/markdown-renderer.json +++ b/apps/www/public/r/markdown-renderer.json @@ -3,14 +3,31 @@ "type": "registry:ui", "dependencies": [ "react-markdown", - "remark-gfm" + "remark-gfm", + "shiki" ], "files": [ { "path": "ui/markdown-renderer.tsx", - "content": "import React from \"react\"\nimport Markdown from \"react-markdown\"\nimport remarkGfm from \"remark-gfm\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CopyButton } from \"@/registry/default/ui/copy-button\"\n\ninterface MarkdownRendererProps {\n children: string\n}\n\nexport function MarkdownRenderer({ children }: MarkdownRendererProps) {\n return (\n \n {children}\n \n )\n}\n\nconst CodeBlock = ({ children, className, ...restProps }: any) => {\n const code =\n typeof children === \"string\"\n ? children\n : childrenTakeAllStringContents(children)\n\n return (\n
\n \n {children}\n \n\n
\n \n
\n
\n )\n}\n\nfunction childrenTakeAllStringContents(element: any): string {\n if (typeof element === \"string\") {\n return element\n }\n\n if (element?.props?.children) {\n let children = element.props.children\n\n if (Array.isArray(children)) {\n return children\n .map((child) => childrenTakeAllStringContents(child))\n .join(\"\")\n } else {\n return childrenTakeAllStringContents(children)\n }\n }\n\n return \"\"\n}\n\nconst COMPONENTS = {\n h1: withClass(\"h1\", \"text-2xl font-semibold\"),\n h2: withClass(\"h2\", \"font-semibold text-xl\"),\n h3: withClass(\"h3\", \"font-semibold text-lg\"),\n h4: withClass(\"h4\", \"font-semibold text-base\"),\n h5: withClass(\"h5\", \"font-medium\"),\n strong: withClass(\"strong\", \"font-semibold\"),\n a: withClass(\"a\", \"text-primary underline underline-offset-2\"),\n blockquote: withClass(\"blockquote\", \"border-l-2 border-primary pl-4\"),\n code: ({ children, className, node, ...rest }: any) => {\n const match = /language-(\\w+)/.exec(className || \"\")\n return match ? (\n \n {children}\n \n ) : (\n &]:bg-background/50 font-mono [:not(pre)>&]:rounded-md [:not(pre)>&]:px-1 [:not(pre)>&]:py-0.5\"\n )}\n {...rest}\n >\n {children}\n \n )\n },\n pre: ({ children }: any) => children,\n ol: withClass(\"ol\", \"list-decimal space-y-2 pl-6\"),\n ul: withClass(\"ul\", \"list-disc space-y-2 pl-6\"),\n li: withClass(\"li\", \"my-1.5\"),\n table: withClass(\n \"table\",\n \"w-full border-collapse overflow-y-auto rounded-md border border-foreground/20\"\n ),\n th: withClass(\n \"th\",\n \"border border-foreground/20 px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\"\n ),\n td: withClass(\n \"td\",\n \"border border-foreground/20 px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n ),\n tr: withClass(\"tr\", \"m-0 border-t p-0 even:bg-muted\"),\n p: withClass(\"p\", \"whitespace-pre-wrap\"),\n hr: withClass(\"hr\", \"border-foreground/20\"),\n}\n\nfunction withClass(Tag: keyof JSX.IntrinsicElements, classes: string) {\n const Component = ({ node, ...props }: any) => (\n \n )\n Component.displayName = Tag\n return Component\n}\n\nexport default MarkdownRenderer\n", + "content": "import React, { Suspense } from \"react\"\nimport Markdown from \"react-markdown\"\nimport remarkGfm from \"remark-gfm\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CopyButton } from \"@/registry/default/ui/copy-button\"\n\ninterface MarkdownRendererProps {\n children: string\n}\n\nexport function MarkdownRenderer({ children }: MarkdownRendererProps) {\n return (\n \n {children}\n \n )\n}\n\nconst shikiPromise = import(\"shiki\")\ninterface HighlightedPre extends React.HTMLAttributes {\n children: string\n language: string\n}\n\nconst HighlightedPre = React.memo(\n async ({ children, language, ...props }: HighlightedPre) => {\n const { codeToTokens, bundledLanguages } = await shikiPromise\n\n if (!(language in bundledLanguages)) {\n return
{children}
\n }\n\n const { tokens } = await codeToTokens(children, {\n lang: language as keyof typeof bundledLanguages,\n defaultColor: false,\n themes: {\n light: \"github-light\",\n dark: \"github-dark\",\n },\n })\n\n return (\n
\n        \n          {tokens.map((line, lineIndex) => (\n            <>\n              \n                {line.map((token, tokenIndex) => {\n                  const style =\n                    typeof token.htmlStyle === \"string\"\n                      ? undefined\n                      : token.htmlStyle\n\n                  return (\n                    \n                      {token.content}\n                    \n                  )\n                })}\n              \n              {\"\\n\"}\n            \n          ))}\n        \n      
\n )\n }\n)\nHighlightedPre.displayName = \"HighlightedCode\"\n\ninterface CodeBlockProps extends React.HTMLAttributes {\n children: React.ReactNode\n className?: string\n language: string\n}\n\nconst CodeBlock = ({\n children,\n className,\n language,\n ...restProps\n}: CodeBlockProps) => {\n const code =\n typeof children === \"string\"\n ? children\n : childrenTakeAllStringContents(children)\n\n const preClass = cn(\n \"overflow-x-scroll rounded-md border bg-background/50 p-4 font-mono text-sm [scrollbar-width:none]\",\n className\n )\n\n return (\n
\n \n {children}\n \n }\n >\n \n {code}\n \n \n\n
\n \n
\n
\n )\n}\n\nfunction childrenTakeAllStringContents(element: any): string {\n if (typeof element === \"string\") {\n return element\n }\n\n if (element?.props?.children) {\n let children = element.props.children\n\n if (Array.isArray(children)) {\n return children\n .map((child) => childrenTakeAllStringContents(child))\n .join(\"\")\n } else {\n return childrenTakeAllStringContents(children)\n }\n }\n\n return \"\"\n}\n\nconst COMPONENTS = {\n h1: withClass(\"h1\", \"text-2xl font-semibold\"),\n h2: withClass(\"h2\", \"font-semibold text-xl\"),\n h3: withClass(\"h3\", \"font-semibold text-lg\"),\n h4: withClass(\"h4\", \"font-semibold text-base\"),\n h5: withClass(\"h5\", \"font-medium\"),\n strong: withClass(\"strong\", \"font-semibold\"),\n a: withClass(\"a\", \"text-primary underline underline-offset-2\"),\n blockquote: withClass(\"blockquote\", \"border-l-2 border-primary pl-4\"),\n code: ({ children, className, node, ...rest }: any) => {\n const match = /language-(\\w+)/.exec(className || \"\")\n return match ? (\n \n {children}\n \n ) : (\n &]:rounded-md [:not(pre)>&]:bg-background/50 [:not(pre)>&]:px-1 [:not(pre)>&]:py-0.5\"\n )}\n {...rest}\n >\n {children}\n \n )\n },\n pre: ({ children }: any) => children,\n ol: withClass(\"ol\", \"list-decimal space-y-2 pl-6\"),\n ul: withClass(\"ul\", \"list-disc space-y-2 pl-6\"),\n li: withClass(\"li\", \"my-1.5\"),\n table: withClass(\n \"table\",\n \"w-full border-collapse overflow-y-auto rounded-md border border-foreground/20\"\n ),\n th: withClass(\n \"th\",\n \"border border-foreground/20 px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right\"\n ),\n td: withClass(\n \"td\",\n \"border border-foreground/20 px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right\"\n ),\n tr: withClass(\"tr\", \"m-0 border-t p-0 even:bg-muted\"),\n p: withClass(\"p\", \"whitespace-pre-wrap\"),\n hr: withClass(\"hr\", \"border-foreground/20\"),\n}\n\nfunction withClass(Tag: keyof JSX.IntrinsicElements, classes: string) {\n const Component = ({ node, ...props }: any) => (\n \n )\n Component.displayName = Tag\n return Component\n}\n\nexport default MarkdownRenderer\n", "type": "registry:ui", "target": "" } - ] + ], + "tailwind": { + "config": { + "theme": { + "extend": { + "colors": { + "shiki": { + "light": "var(--shiki-light)", + "light-bg": "var(--shiki-light-bg)", + "dark": "var(--shiki-dark)", + "dark-bg": "var(--shiki-dark-bg)" + } + } + } + } + } + } } \ No newline at end of file diff --git a/apps/www/registry/default/ui/markdown-renderer.tsx b/apps/www/registry/default/ui/markdown-renderer.tsx index 3049a679..72dcae7f 100644 --- a/apps/www/registry/default/ui/markdown-renderer.tsx +++ b/apps/www/registry/default/ui/markdown-renderer.tsx @@ -1,4 +1,4 @@ -import React from "react" +import React, { Suspense } from "react" import Markdown from "react-markdown" import remarkGfm from "remark-gfm" @@ -21,23 +21,97 @@ export function MarkdownRenderer({ children }: MarkdownRendererProps) { ) } -const CodeBlock = ({ children, className, ...restProps }: any) => { +const shikiPromise = import("shiki") +interface HighlightedPre extends React.HTMLAttributes { + children: string + language: string +} + +const HighlightedPre = React.memo( + async ({ children, language, ...props }: HighlightedPre) => { + const { codeToTokens, bundledLanguages } = await shikiPromise + + if (!(language in bundledLanguages)) { + return
{children}
+ } + + const { tokens } = await codeToTokens(children, { + lang: language as keyof typeof bundledLanguages, + defaultColor: false, + themes: { + light: "github-light", + dark: "github-dark", + }, + }) + + return ( +
+        
+          {tokens.map((line, lineIndex) => (
+            <>
+              
+                {line.map((token, tokenIndex) => {
+                  const style =
+                    typeof token.htmlStyle === "string"
+                      ? undefined
+                      : token.htmlStyle
+
+                  return (
+                    
+                      {token.content}
+                    
+                  )
+                })}
+              
+              {"\n"}
+            
+          ))}
+        
+      
+ ) + } +) +HighlightedPre.displayName = "HighlightedCode" + +interface CodeBlockProps extends React.HTMLAttributes { + children: React.ReactNode + className?: string + language: string +} + +const CodeBlock = ({ + children, + className, + language, + ...restProps +}: CodeBlockProps) => { const code = typeof children === "string" ? children : childrenTakeAllStringContents(children) + const preClass = cn( + "overflow-x-scroll rounded-md border bg-background/50 p-4 font-mono text-sm [scrollbar-width:none]", + className + ) + return (
-
+            {children}
+          
+ } > - {children} - + + {code} + +
@@ -78,13 +152,13 @@ const COMPONENTS = { code: ({ children, className, node, ...rest }: any) => { const match = /language-(\w+)/.exec(className || "") return match ? ( - + {children} ) : ( &]:bg-background/50 font-mono [:not(pre)>&]:rounded-md [:not(pre)>&]:px-1 [:not(pre)>&]:py-0.5" + "font-mono [:not(pre)>&]:rounded-md [:not(pre)>&]:bg-background/50 [:not(pre)>&]:px-1 [:not(pre)>&]:py-0.5" )} {...rest} > diff --git a/apps/www/registry/index.ts b/apps/www/registry/index.ts index 45de2c7d..6b0ca9cb 100644 --- a/apps/www/registry/index.ts +++ b/apps/www/registry/index.ts @@ -49,7 +49,23 @@ export const registry: Registry = [ name: "markdown-renderer", type: "registry:ui", files: ["ui/markdown-renderer.tsx"], - dependencies: ["react-markdown", "remark-gfm"], + dependencies: ["react-markdown", "remark-gfm", "shiki"], + tailwind: { + config: { + theme: { + extend: { + colors: { + shiki: { + light: "var(--shiki-light)", + "light-bg": "var(--shiki-light-bg)", + dark: "var(--shiki-dark)", + "dark-bg": "var(--shiki-dark-bg)", + }, + }, + }, + }, + }, + }, }, { name: "message-input", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 38715717..f320366d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -155,10 +155,10 @@ importers: version: 1.0.0(@types/react-dom@18.2.22)(@types/react@18.2.67)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) contentlayer2: specifier: ^0.4.6 - version: 0.4.6(esbuild@0.17.19)(markdown-wasm@1.2.0) + version: 0.4.6(esbuild@0.21.5)(markdown-wasm@1.2.0) esbuild: specifier: ^0.17.3 - version: 0.17.19 + version: 0.21.5 framer-motion: specifier: ^11.11.9 version: 11.11.9(@emotion/is-prop-valid@1.3.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -179,7 +179,7 @@ importers: version: 14.3.0-canary.43(@babel/core@7.24.6)(@opentelemetry/api@1.8.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) next-contentlayer2: specifier: ^0.4.6 - version: 0.4.6(contentlayer2@0.4.6(esbuild@0.17.19)(markdown-wasm@1.2.0))(esbuild@0.17.19)(markdown-wasm@1.2.0)(next@14.3.0-canary.43(@babel/core@7.24.6)(@opentelemetry/api@1.8.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 0.4.6(contentlayer2@0.4.6(esbuild@0.21.5)(markdown-wasm@1.2.0))(esbuild@0.21.5)(markdown-wasm@1.2.0)(next@14.3.0-canary.43(@babel/core@7.24.6)(@opentelemetry/api@1.8.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) next-themes: specifier: ^0.2.1 version: 0.2.1(next@14.3.0-canary.43(@babel/core@7.24.6)(@opentelemetry/api@1.8.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -213,6 +213,9 @@ importers: remeda: specifier: ^2.14.0 version: 2.14.0 + shiki: + specifier: ^1.22.0 + version: 1.22.0 sonner: specifier: ^1.2.3 version: 1.2.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -253,9 +256,6 @@ importers: rimraf: specifier: ^4.1.3 version: 4.1.3 - shiki: - specifier: ^1.10.1 - version: 1.22.0 tailwindcss: specifier: 3.4.6 version: 3.4.6(ts-node@10.9.2(@types/node@17.0.45)(typescript@5.5.3)) @@ -549,12 +549,6 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.17.19': - resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.18.20': resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -567,12 +561,6 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm@0.17.19': - resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.18.20': resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -585,12 +573,6 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-x64@0.17.19': - resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -603,12 +585,6 @@ packages: cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.17.19': - resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -621,12 +597,6 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.17.19': - resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -639,12 +609,6 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.17.19': - resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -657,12 +621,6 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.17.19': - resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -675,12 +633,6 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.17.19': - resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -693,12 +645,6 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.17.19': - resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -711,12 +657,6 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.17.19': - resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -729,12 +669,6 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.17.19': - resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -747,12 +681,6 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.17.19': - resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -765,12 +693,6 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.17.19': - resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -783,12 +705,6 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.17.19': - resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -801,12 +717,6 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.17.19': - resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -819,12 +729,6 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.17.19': - resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -837,12 +741,6 @@ packages: cpu: [x64] os: [linux] - '@esbuild/netbsd-x64@0.17.19': - resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -855,12 +753,6 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/openbsd-x64@0.17.19': - resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -873,12 +765,6 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.17.19': - resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -891,12 +777,6 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.17.19': - resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.18.20': resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -909,12 +789,6 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.17.19': - resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -927,12 +801,6 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.17.19': - resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -3067,11 +2935,6 @@ packages: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} - esbuild@0.17.19: - resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} - engines: {node: '>=12'} - hasBin: true - esbuild@0.18.20: resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} engines: {node: '>=12'} @@ -5820,9 +5683,9 @@ snapshots: dependencies: conventional-changelog-conventionalcommits: 5.0.0 - '@contentlayer2/cli@0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0)': + '@contentlayer2/cli@0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0)': dependencies: - '@contentlayer2/core': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) + '@contentlayer2/core': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) '@contentlayer2/utils': 0.4.3 clipanion: 3.2.1(typanion@3.14.0) typanion: 3.14.0 @@ -5832,22 +5695,22 @@ snapshots: - markdown-wasm - supports-color - '@contentlayer2/client@0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0)': + '@contentlayer2/client@0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0)': dependencies: - '@contentlayer2/core': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) + '@contentlayer2/core': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) transitivePeerDependencies: - '@effect-ts/otel-node' - esbuild - markdown-wasm - supports-color - '@contentlayer2/core@0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0)': + '@contentlayer2/core@0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0)': dependencies: '@contentlayer2/utils': 0.4.3 camel-case: 4.1.2 comment-json: 4.2.3 gray-matter: 4.0.3 - mdx-bundler: 10.0.2(esbuild@0.17.19) + mdx-bundler: 10.0.2(esbuild@0.21.5) rehype-stringify: 10.0.0 remark-frontmatter: 5.0.0 remark-parse: 11.0.0 @@ -5856,15 +5719,15 @@ snapshots: type-fest: 4.21.0 unified: 11.0.5 optionalDependencies: - esbuild: 0.17.19 + esbuild: 0.21.5 markdown-wasm: 1.2.0 transitivePeerDependencies: - '@effect-ts/otel-node' - supports-color - '@contentlayer2/source-files@0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0)': + '@contentlayer2/source-files@0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0)': dependencies: - '@contentlayer2/core': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) + '@contentlayer2/core': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) '@contentlayer2/utils': 0.4.3 chokidar: 3.6.0 fast-glob: 3.3.2 @@ -5881,10 +5744,10 @@ snapshots: - markdown-wasm - supports-color - '@contentlayer2/source-remote-files@0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0)': + '@contentlayer2/source-remote-files@0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0)': dependencies: - '@contentlayer2/core': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) - '@contentlayer2/source-files': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) + '@contentlayer2/core': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) + '@contentlayer2/source-files': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) '@contentlayer2/utils': 0.4.3 transitivePeerDependencies: - '@effect-ts/otel-node' @@ -5951,11 +5814,11 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@esbuild-plugins/node-resolve@0.2.2(esbuild@0.17.19)': + '@esbuild-plugins/node-resolve@0.2.2(esbuild@0.21.5)': dependencies: '@types/resolve': 1.20.6 debug: 4.3.5 - esbuild: 0.17.19 + esbuild: 0.21.5 escape-string-regexp: 4.0.0 resolve: 1.22.8 transitivePeerDependencies: @@ -5964,198 +5827,132 @@ snapshots: '@esbuild/aix-ppc64@0.21.5': optional: true - '@esbuild/android-arm64@0.17.19': - optional: true - '@esbuild/android-arm64@0.18.20': optional: true '@esbuild/android-arm64@0.21.5': optional: true - '@esbuild/android-arm@0.17.19': - optional: true - '@esbuild/android-arm@0.18.20': optional: true '@esbuild/android-arm@0.21.5': optional: true - '@esbuild/android-x64@0.17.19': - optional: true - '@esbuild/android-x64@0.18.20': optional: true '@esbuild/android-x64@0.21.5': optional: true - '@esbuild/darwin-arm64@0.17.19': - optional: true - '@esbuild/darwin-arm64@0.18.20': optional: true '@esbuild/darwin-arm64@0.21.5': optional: true - '@esbuild/darwin-x64@0.17.19': - optional: true - '@esbuild/darwin-x64@0.18.20': optional: true '@esbuild/darwin-x64@0.21.5': optional: true - '@esbuild/freebsd-arm64@0.17.19': - optional: true - '@esbuild/freebsd-arm64@0.18.20': optional: true '@esbuild/freebsd-arm64@0.21.5': optional: true - '@esbuild/freebsd-x64@0.17.19': - optional: true - '@esbuild/freebsd-x64@0.18.20': optional: true '@esbuild/freebsd-x64@0.21.5': optional: true - '@esbuild/linux-arm64@0.17.19': - optional: true - '@esbuild/linux-arm64@0.18.20': optional: true '@esbuild/linux-arm64@0.21.5': optional: true - '@esbuild/linux-arm@0.17.19': - optional: true - '@esbuild/linux-arm@0.18.20': optional: true '@esbuild/linux-arm@0.21.5': optional: true - '@esbuild/linux-ia32@0.17.19': - optional: true - '@esbuild/linux-ia32@0.18.20': optional: true '@esbuild/linux-ia32@0.21.5': optional: true - '@esbuild/linux-loong64@0.17.19': - optional: true - '@esbuild/linux-loong64@0.18.20': optional: true '@esbuild/linux-loong64@0.21.5': optional: true - '@esbuild/linux-mips64el@0.17.19': - optional: true - '@esbuild/linux-mips64el@0.18.20': optional: true '@esbuild/linux-mips64el@0.21.5': optional: true - '@esbuild/linux-ppc64@0.17.19': - optional: true - '@esbuild/linux-ppc64@0.18.20': optional: true '@esbuild/linux-ppc64@0.21.5': optional: true - '@esbuild/linux-riscv64@0.17.19': - optional: true - '@esbuild/linux-riscv64@0.18.20': optional: true '@esbuild/linux-riscv64@0.21.5': optional: true - '@esbuild/linux-s390x@0.17.19': - optional: true - '@esbuild/linux-s390x@0.18.20': optional: true '@esbuild/linux-s390x@0.21.5': optional: true - '@esbuild/linux-x64@0.17.19': - optional: true - '@esbuild/linux-x64@0.18.20': optional: true '@esbuild/linux-x64@0.21.5': optional: true - '@esbuild/netbsd-x64@0.17.19': - optional: true - '@esbuild/netbsd-x64@0.18.20': optional: true '@esbuild/netbsd-x64@0.21.5': optional: true - '@esbuild/openbsd-x64@0.17.19': - optional: true - '@esbuild/openbsd-x64@0.18.20': optional: true '@esbuild/openbsd-x64@0.21.5': optional: true - '@esbuild/sunos-x64@0.17.19': - optional: true - '@esbuild/sunos-x64@0.18.20': optional: true '@esbuild/sunos-x64@0.21.5': optional: true - '@esbuild/win32-arm64@0.17.19': - optional: true - '@esbuild/win32-arm64@0.18.20': optional: true '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/win32-ia32@0.17.19': - optional: true - '@esbuild/win32-ia32@0.18.20': optional: true '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/win32-x64@0.17.19': - optional: true - '@esbuild/win32-x64@0.18.20': optional: true @@ -6382,11 +6179,11 @@ snapshots: dependencies: tslib: 2.6.2 - '@mdx-js/esbuild@3.0.1(esbuild@0.17.19)': + '@mdx-js/esbuild@3.0.1(esbuild@0.21.5)': dependencies: '@mdx-js/mdx': 3.0.1 '@types/unist': 3.0.2 - esbuild: 0.17.19 + esbuild: 0.21.5 vfile: 6.0.1 vfile-message: 4.0.2 transitivePeerDependencies: @@ -8120,13 +7917,13 @@ snapshots: concat-map@0.0.1: {} - contentlayer2@0.4.6(esbuild@0.17.19)(markdown-wasm@1.2.0): + contentlayer2@0.4.6(esbuild@0.21.5)(markdown-wasm@1.2.0): dependencies: - '@contentlayer2/cli': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) - '@contentlayer2/client': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) - '@contentlayer2/core': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) - '@contentlayer2/source-files': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) - '@contentlayer2/source-remote-files': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) + '@contentlayer2/cli': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) + '@contentlayer2/client': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) + '@contentlayer2/core': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) + '@contentlayer2/source-files': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) + '@contentlayer2/source-remote-files': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) '@contentlayer2/utils': 0.4.3 transitivePeerDependencies: - '@effect-ts/otel-node' @@ -8388,31 +8185,6 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.0.4 - esbuild@0.17.19: - optionalDependencies: - '@esbuild/android-arm': 0.17.19 - '@esbuild/android-arm64': 0.17.19 - '@esbuild/android-x64': 0.17.19 - '@esbuild/darwin-arm64': 0.17.19 - '@esbuild/darwin-x64': 0.17.19 - '@esbuild/freebsd-arm64': 0.17.19 - '@esbuild/freebsd-x64': 0.17.19 - '@esbuild/linux-arm': 0.17.19 - '@esbuild/linux-arm64': 0.17.19 - '@esbuild/linux-ia32': 0.17.19 - '@esbuild/linux-loong64': 0.17.19 - '@esbuild/linux-mips64el': 0.17.19 - '@esbuild/linux-ppc64': 0.17.19 - '@esbuild/linux-riscv64': 0.17.19 - '@esbuild/linux-s390x': 0.17.19 - '@esbuild/linux-x64': 0.17.19 - '@esbuild/netbsd-x64': 0.17.19 - '@esbuild/openbsd-x64': 0.17.19 - '@esbuild/sunos-x64': 0.17.19 - '@esbuild/win32-arm64': 0.17.19 - '@esbuild/win32-ia32': 0.17.19 - '@esbuild/win32-x64': 0.17.19 - esbuild@0.18.20: optionalDependencies: '@esbuild/android-arm': 0.18.20 @@ -9728,13 +9500,13 @@ snapshots: mdn-data@2.0.30: {} - mdx-bundler@10.0.2(esbuild@0.17.19): + mdx-bundler@10.0.2(esbuild@0.21.5): dependencies: '@babel/runtime': 7.24.6 - '@esbuild-plugins/node-resolve': 0.2.2(esbuild@0.17.19) + '@esbuild-plugins/node-resolve': 0.2.2(esbuild@0.21.5) '@fal-works/esbuild-plugin-global-externals': 2.1.2 - '@mdx-js/esbuild': 3.0.1(esbuild@0.17.19) - esbuild: 0.17.19 + '@mdx-js/esbuild': 3.0.1(esbuild@0.21.5) + esbuild: 0.21.5 gray-matter: 4.0.3 remark-frontmatter: 5.0.0 remark-mdx-frontmatter: 4.0.0 @@ -10203,11 +9975,11 @@ snapshots: netmask@2.0.2: {} - next-contentlayer2@0.4.6(contentlayer2@0.4.6(esbuild@0.17.19)(markdown-wasm@1.2.0))(esbuild@0.17.19)(markdown-wasm@1.2.0)(next@14.3.0-canary.43(@babel/core@7.24.6)(@opentelemetry/api@1.8.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + next-contentlayer2@0.4.6(contentlayer2@0.4.6(esbuild@0.21.5)(markdown-wasm@1.2.0))(esbuild@0.21.5)(markdown-wasm@1.2.0)(next@14.3.0-canary.43(@babel/core@7.24.6)(@opentelemetry/api@1.8.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: - '@contentlayer2/core': 0.4.3(esbuild@0.17.19)(markdown-wasm@1.2.0) + '@contentlayer2/core': 0.4.3(esbuild@0.21.5)(markdown-wasm@1.2.0) '@contentlayer2/utils': 0.4.3 - contentlayer2: 0.4.6(esbuild@0.17.19)(markdown-wasm@1.2.0) + contentlayer2: 0.4.6(esbuild@0.21.5)(markdown-wasm@1.2.0) next: 14.3.0-canary.43(@babel/core@7.24.6)(@opentelemetry/api@1.8.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) diff --git a/tailwind.config.cjs b/tailwind.config.cjs index b59bcc0c..278e45fb 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -57,6 +57,12 @@ module.exports = { border: "hsl(var(--sidebar-border))", ring: "hsl(var(--sidebar-ring))", }, + shiki: { + light: "var(--shiki-light)", + "light-bg": "var(--shiki-light-bg)", + dark: "var(--shiki-dark)", + "dark-bg": "var(--shiki-dark-bg)", + }, }, borderRadius: { xl: "calc(var(--radius) + 4px)",