tweakcn icon indicating copy to clipboard operation
tweakcn copied to clipboard

Missing CSS variables from the copy-pastable theme code as compared to the cli command.

Open virtuallyunknown opened this issue 7 months ago • 6 comments

Greetings! I have a question.

I have a theme I want to export, it's the Supabase theme with a few modifications. When you click on the {} code button on the website, I have two ways of importing the generated theme code to my project. Either via a cli command or by manually copy pasting the generated index.css file.

When I run the cli command, all seems to work as expected and the theme is imported properly. But if I compare the CSS content that gets generated by it versus the index.css file which you can copy paste, there are lots of missing CSS variables.

 :root {
   --background: oklch(0.99 0 0);
   --foreground: oklch(0.20 0 0);
   --card: oklch(0.99 0 0);
   --card-foreground: oklch(0.20 0 0);
   --popover: oklch(0.99 0 0);
   --popover-foreground: oklch(0.44 0 0);
   --primary: oklch(0.83 0.13 160.91);
   --primary-foreground: oklch(0.26 0.01 166.46);
   --secondary: oklch(0.99 0 0);
   --secondary-foreground: oklch(0.20 0 0);
   --muted: oklch(0.95 0 0);
   --muted-foreground: oklch(0.24 0 0);
   --accent: oklch(0.95 0 0);
   --accent-foreground: oklch(0.24 0 0);
   --destructive: oklch(0.55 0.19 32.73);
   --destructive-foreground: oklch(0.99 0.00 17.21);
   --border: oklch(0.90 0 0);
   --input: oklch(0.97 0 0);
   --ring: oklch(0.83 0.13 160.91);
   --chart-1: oklch(0.83 0.13 160.91);
   --chart-2: oklch(0.62 0.19 259.81);
   --chart-3: oklch(0.61 0.22 292.72);
   --chart-4: oklch(0.77 0.16 70.08);
   --chart-5: oklch(0.70 0.15 162.48);
   --sidebar: oklch(0.99 0 0);
   --sidebar-foreground: oklch(0.55 0 0);
   --sidebar-primary: oklch(0.83 0.13 160.91);
   --sidebar-primary-foreground: oklch(0.26 0.01 166.46);
   --sidebar-accent: oklch(0.95 0 0);
   --sidebar-accent-foreground: oklch(0.24 0 0);
   --sidebar-border: oklch(0.90 0 0);
   --sidebar-ring: oklch(0.83 0.13 160.91);
   --font-sans: Outfit, sans-serif;
   --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
   --font-mono: monospace;
   --radius: 0.5rem;
   --shadow-2xs: 0px 1px 3px 0px hsl(0 0% 0% / 0.09);
   --shadow-xs: 0px 1px 3px 0px hsl(0 0% 0% / 0.09);
   --shadow-sm: 0px 1px 3px 0px hsl(0 0% 0% / 0.17), 0px 1px 2px -1px hsl(0 0% 0% / 0.17);
   --shadow: 0px 1px 3px 0px hsl(0 0% 0% / 0.17), 0px 1px 2px -1px hsl(0 0% 0% / 0.17);
   --shadow-md: 0px 1px 3px 0px hsl(0 0% 0% / 0.17), 0px 2px 4px -1px hsl(0 0% 0% / 0.17);
   --shadow-lg: 0px 1px 3px 0px hsl(0 0% 0% / 0.17), 0px 4px 6px -1px hsl(0 0% 0% / 0.17);
   --shadow-xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.17), 0px 8px 10px -1px hsl(0 0% 0% / 0.17);
   --shadow-2xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.43);
   --tracking-normal: 0.025em;
-  --shadow-color: #000000;
-  --shadow-opacity: 0.17;
-  --shadow-blur: 3px;
-  --shadow-spread: 0px;
-  --shadow-offset-x: 0px;
-  --shadow-offset-y: 1px;
-  --letter-spacing: 0.025em;
-  --spacing: 0.25rem;
 }
 
 .dark {
   --background: oklch(0.18 0 0);
   --foreground: oklch(0.93 0.01 255.51);
   --card: oklch(0.20 0 0);
   --card-foreground: oklch(0.93 0.01 255.51);
   --popover: oklch(0.26 0 0);
   --popover-foreground: oklch(0.73 0 0);
   --primary: oklch(0.61 0.16 255.34);
   --primary-foreground: oklch(0.92 0.01 167.16);
   --secondary: oklch(0.26 0 0);
   --secondary-foreground: oklch(0.99 0 0);
   --muted: oklch(0.24 0 0);
   --muted-foreground: oklch(0.71 0 0);
   --accent: oklch(0.31 0 0);
   --accent-foreground: oklch(0.99 0 0);
   --destructive: oklch(0.31 0.09 29.79);
   --destructive-foreground: oklch(0.94 0.00 34.31);
   --border: oklch(0.28 0 0);
   --input: oklch(0.26 0 0);
   --ring: oklch(0.80 0.18 151.71);
   --chart-1: oklch(0.80 0.18 151.71);
   --chart-2: oklch(0.71 0.14 254.62);
   --chart-3: oklch(0.71 0.16 293.54);
   --chart-4: oklch(0.84 0.16 84.43);
   --chart-5: oklch(0.78 0.13 181.91);
   --sidebar: oklch(0.18 0 0);
   --sidebar-foreground: oklch(0.63 0 0);
   --sidebar-primary: oklch(0.44 0.10 156.76);
   --sidebar-primary-foreground: oklch(0.92 0.01 167.16);
   --sidebar-accent: oklch(0.31 0 0);
   --sidebar-accent-foreground: oklch(0.99 0 0);
   --sidebar-border: oklch(0.28 0 0);
   --sidebar-ring: oklch(0.80 0.18 151.71);
   --font-sans: Outfit, sans-serif;
   --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
   --font-mono: monospace;
   --radius: 0.5rem;
   --shadow-2xs: 0px 1px 3px 0px hsl(0 0% 0% / 0.09);
   --shadow-xs: 0px 1px 3px 0px hsl(0 0% 0% / 0.09);
   --shadow-sm: 0px 1px 3px 0px hsl(0 0% 0% / 0.17), 0px 1px 2px -1px hsl(0 0% 0% / 0.17);
   --shadow: 0px 1px 3px 0px hsl(0 0% 0% / 0.17), 0px 1px 2px -1px hsl(0 0% 0% / 0.17);
   --shadow-md: 0px 1px 3px 0px hsl(0 0% 0% / 0.17), 0px 2px 4px -1px hsl(0 0% 0% / 0.17);
   --shadow-lg: 0px 1px 3px 0px hsl(0 0% 0% / 0.17), 0px 4px 6px -1px hsl(0 0% 0% / 0.17);
   --shadow-xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.17), 0px 8px 10px -1px hsl(0 0% 0% / 0.17);
   --shadow-2xl: 0px 1px 3px 0px hsl(0 0% 0% / 0.43);
-  --shadow-color: #000000;
-  --shadow-opacity: 0.17;
-  --shadow-blur: 3px;
-  --shadow-spread: 0px;
-  --shadow-offset-x: 0px;
-  --shadow-offset-y: 1px;
-  --letter-spacing: 0.025em;
-  --spacing: 0.25rem;
 }
 
 @theme inline {
   --color-background: var(--background);
   --color-foreground: var(--foreground);
   --color-card: var(--card);
   --color-card-foreground: var(--card-foreground);
   --color-popover: var(--popover);
   --color-popover-foreground: var(--popover-foreground);
   --color-primary: var(--primary);
   --color-primary-foreground: var(--primary-foreground);
   --color-secondary: var(--secondary);
   --color-secondary-foreground: var(--secondary-foreground);
   --color-muted: var(--muted);
   --color-muted-foreground: var(--muted-foreground);
   --color-accent: var(--accent);
   --color-accent-foreground: var(--accent-foreground);
   --color-destructive: var(--destructive);
   --color-destructive-foreground: var(--destructive-foreground);
   --color-border: var(--border);
   --color-input: var(--input);
   --color-ring: var(--ring);
   --color-chart-1: var(--chart-1);
   --color-chart-2: var(--chart-2);
   --color-chart-3: var(--chart-3);
   --color-chart-4: var(--chart-4);
   --color-chart-5: var(--chart-5);
   --color-sidebar: var(--sidebar);
   --color-sidebar-foreground: var(--sidebar-foreground);
   --color-sidebar-primary: var(--sidebar-primary);
   --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
   --color-sidebar-accent: var(--sidebar-accent);
   --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
   --color-sidebar-border: var(--sidebar-border);
   --color-sidebar-ring: var(--sidebar-ring);
 
-  --font-sans: Outfit, sans-serif;
-  --font-mono: monospace;
-  --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
+  --font-sans: var(--font-sans);
+  --font-mono: var(--font-mono);
+  --font-serif: var(--font-serif);
 
   --radius-sm: calc(var(--radius) - 4px);
   --radius-md: calc(var(--radius) - 2px);
   --radius-lg: var(--radius);
   --radius-xl: calc(var(--radius) + 4px);
 
   --shadow-2xs: var(--shadow-2xs);
   --shadow-xs: var(--shadow-xs);
   --shadow-sm: var(--shadow-sm);
   --shadow: var(--shadow);
   --shadow-md: var(--shadow-md);
   --shadow-lg: var(--shadow-lg);
   --shadow-xl: var(--shadow-xl);
   --shadow-2xl: var(--shadow-2xl);
 
   --tracking-tighter: calc(var(--tracking-normal) - 0.05em);
   --tracking-tight: calc(var(--tracking-normal) - 0.025em);
   --tracking-normal: var(--tracking-normal);
   --tracking-wide: calc(var(--tracking-normal) + 0.025em);
   --tracking-wider: calc(var(--tracking-normal) + 0.05em);
   --tracking-widest: calc(var(--tracking-normal) + 0.1em);
-  --radius: 0.5rem;
-  --spacing: var(--spacing);
-  --letter-spacing: var(--letter-spacing);
-  --shadow-offset-y: var(--shadow-offset-y);
-  --shadow-offset-x: var(--shadow-offset-x);
-  --shadow-spread: var(--shadow-spread);
-  --shadow-blur: var(--shadow-blur);
-  --shadow-opacity: var(--shadow-opacity);
-  --color-shadow-color: var(--shadow-color);
 }
 
 body {
   letter-spacing: var(--tracking-normal);
-}
-
-@layer base {
-  * {
-      @apply border-border outline-ring/50;
-  }
-  body {
-      @apply bg-background text-foreground;
-  letter-spacing: var(--tracking-normal);
-  }
 }

virtuallyunknown avatar May 14 '25 13:05 virtuallyunknown

Thanks for bringing this to notice. These variables are used internally and don't need to be exported. The variables present from the Copy command are correct.

jnsahaj avatar May 15 '25 09:05 jnsahaj

Thanks for bringing this to notice. These variables are used internally and don't need to be exported. The variables present from the Copy command are correct.

You're absolutely right. Some of my shadows weren't working properly, but apparently that's because I wasn't applying this in my project's index.css

@layer base {
    * {
        @apply border-border outline-ring/50;
    }
}

I'm still new to tailwindcss v4, so I completely overlooked this, my bad.

If you allow me a quick follow-up question, I wanted to ask, is there an easy way to convert and use these themes as tailwind v3 themes that I'm not aware of? For example, in tailwind v4, the theme is ready to be used right as you import it. But in v3, I am doing something like this in my config file:

/** @type {import('tailwindcss').Config} */
export default {
    content: [
        "./index.html",
        "./src/**/*.{js,ts,jsx,tsx}",
    ],
    theme: {
        extend: {
            colors: {
                'background': 'rgb(var(--background) / <alpha-value>)',
                'foreground': 'rgb(var(--foreground) / <alpha-value>)',
                'card': 'rgb(var(--card) / <alpha-value>)',
                'card-foreground': 'rgb(var(--card-foreground) / <alpha-value>)',
                'popover': 'rgb(var(--popover) / <alpha-value>)',
                'popover-foreground': 'rgb(var(--popover-foreground) / <alpha-value>)',
                'primary': "rgb(var(--primary) / <alpha-value>)",
                'primary-foreground': 'rgb(var(--primary-foreground) / <alpha-value>)',
                'secondary': 'rgb(var(--secondary) / <alpha-value>)',
                'secondary-foreground': 'rgb(var(--secondary-foreground) / <alpha-value>)',
                'muted': 'rgb(var(--muted) / <alpha-value>)',
                'muted-foreground': 'rgb(var(--muted-foreground) / <alpha-value>)',
                'accent': 'rgb(var(--accent) / <alpha-value>)',
                'accent-foreground': 'rgb(var(--accent-foreground) / <alpha-value>)',
                'destructive': 'rgb(var(--destructive) / <alpha-value>)',
                'destructive-foreground': 'rgb(var(--destructive-foreground) / <alpha-value>)',
                'border': 'rgb(var(--border) / <alpha-value>)',
                'input': 'rgb(var(--input) / <alpha-value>)',
                'ring': 'rgb(var(--ring) / <alpha-value>)',
                'chart-1': 'rgb(var(--chart-1) / <alpha-value>)',
                'chart-2': 'rgb(var(--chart-2) / <alpha-value>)',
                'chart-3': 'rgb(var(--chart-3) / <alpha-value>)',
                'chart-4': 'rgb(var(--chart-4) / <alpha-value>)',
                'chart-5': 'rgb(var(--chart-5) / <alpha-value>)',
                'sidebar': 'rgb(var(--sidebar) / <alpha-value>)',
                'sidebar-foreground': 'rgb(var(--sidebar-foreground) / <alpha-value>)',
                'sidebar-primary': 'rgb(var(--sidebar-primary) / <alpha-value>)',
                'sidebar-primary-foreground': 'rgb(var(--sidebar-primary-foreground) / <alpha-value>)',
                'sidebar-accent': 'rgb(var(--sidebar-accent) / <alpha-value>)',
                'sidebar-accent-foreground': 'rgb(var(--sidebar-accent-foreground) / <alpha-value>)',
                'sidebar-border': 'rgb(var(--sidebar-border) / <alpha-value>)',
                'sidebar-ring': 'rgb(var(--sidebar-ring) / <alpha-value>)',
            },
            fontFamily: {
                sans: ['var(--font-sans)'],
                serif: ['var(--font-serif)'],
                mono: ['var(--font-mono)'],
            },
            boxShadow: {
                'DEFAULT': 'var(--shadow)',
                '2xl': 'var(--shadow-2xl)',
                'xl': 'var(--shadow-xl)',
                'lg': 'var(--shadow-lg)',
                'md': 'var(--shadow-md)',
                'sm': 'var(--shadow-sm)',
                'xs': 'var(--shadow-xs)',
                '2xs': 'var(--shadow-2xs)',
            },
            letterSpacing: {
                'tighter': 'calc(var(--tracking-normal) - 0.05em)',
                'tight': 'calc(var(--tracking-normal) - 0.025em)',
                'wide': 'calc(var(--tracking-normal) + 0.025em)',
                'wider': 'calc(var(--tracking-normal) + 0.05em)',
                'widest': 'calc(var(--tracking-normal) + 0.1em)',
                'normal': 'var(--tracking-normal)',
            },
        },
    },
    plugins: [],
}

Basically I'm re-creating all the utility classes myself, but there is a high chance I might be missing some, and I also have to convert the RGB color values from the CSS variables to plain color channels (from rgb(1,2,3) to 1 2 3) in order to support the opacity modifier syntax, as explained here and here.

So yeah, I'm basically just asking if there is an easier way to go about this. But if this is outside the scope of this project, I totally understand, feel free to ignore this reply.

Cheers!

virtuallyunknown avatar May 15 '25 13:05 virtuallyunknown

I planned to include the generated tailwind.config.ts file (similar to @theme inline for v4) but never got around to it. Will get this done :)

jnsahaj avatar May 20 '25 07:05 jnsahaj

I planned to include the generated tailwind.config.ts file (similar to @theme inline for v4) but never got around to it. Will get this done :)

Ah cheers man, can't wait for that and the other things on the roadmap such as community themes. Great work, and thanks for building this great tool!

EDIT: If you have a generated tailwind.config.ts file for v3, would you mind showing an example one so I can see how some of the utility classes are constructed?

virtuallyunknown avatar May 20 '25 17:05 virtuallyunknown

I had a problem of copying the HSL config (Tailwind.css 4). I had to remove the hsl() brackets in order for the theme to work. Just figured it might help someone :)

david1542 avatar May 26 '25 16:05 david1542

HSL in Tailwind v3 is formatted without brackets

jnsahaj avatar May 26 '25 16:05 jnsahaj