feat: tailwind v4, shadcn, expressive-code

This commit is contained in:
enscribe 2025-02-18 15:09:38 -08:00
parent f51601c21a
commit 513aa6a8b5
17 changed files with 1614 additions and 2480 deletions

View file

@ -1,10 +1,43 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import 'tailwindcss';
@plugin '@tailwindcss/typography';
@plugin 'tailwindcss-animate';
@custom-variant dark (&:is(.dark *));
@theme inline {
--font-sans: Geist, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
--font-mono: Geist Mono, ui-monospace, SFMono-Regular, Menlo, Monaco,
Consolas, 'Liberation Mono', 'Courier New', monospace;
--color-background: var(--background);
--color-foreground: var(--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-additive: var(--additive);
--color-additive-foreground: var(--additive-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-ring: var(--ring);
}
@font-face {
font-family: 'Geist';
src: url('/fonts/GeistVF.woff2') format('woff2');
src: url('/fonts/GeistVF.woff2') format('woff2-variations');
font-weight: 100 900;
font-style: normal;
font-display: swap;
@ -12,54 +45,57 @@
@font-face {
font-family: 'Geist Mono';
src: url('/fonts/GeistMonoVF.woff2') format('woff2');
src: url('/fonts/GeistMonoVF.woff2') format('woff2-variations');
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 80.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 80.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 80.1%;
--accent-foreground: 0 0% 9%;
--additive: 112 50% 36%;
--additive-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--ring: 0 0% 3.9%;
}
.dark {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--additive: 112 50% 36%;
--additive-foreground: 0 0% 9%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--ring: 0 0% 83.1%;
}
:root {
--background: hsl(0 0% 100%);
--foreground: hsl(0 0% 3.9%);
--primary: hsl(0 0% 9%);
--primary-foreground: hsl(0 0% 98%);
--secondary: hsl(0 0% 80.1%);
--secondary-foreground: hsl(0 0% 9%);
--muted: hsl(0 0% 80.1%);
--muted-foreground: hsl(0 0% 45.1%);
--accent: hsl(0 0% 80.1%);
--accent-foreground: hsl(0 0% 9%);
--additive: hsl(112 50% 36%);
--additive-foreground: hsl(0 0% 9%);
--destructive: hsl(0 84.2% 60.2%);
--destructive-foreground: hsl(0 0% 98%);
--border: hsl(0 0% 89.8%);
--ring: hsl(0 0% 3.9%);
}
.dark {
--background: hsl(0 0% 3.9%);
--foreground: hsl(0 0% 98%);
--primary: hsl(0 0% 98%);
--primary-foreground: hsl(0 0% 9%);
--secondary: hsl(0 0% 14.9%);
--secondary-foreground: hsl(0 0% 98%);
--muted: hsl(0 0% 14.9%);
--muted-foreground: hsl(0 0% 63.9%);
--accent: hsl(0 0% 14.9%);
--accent-foreground: hsl(0 0% 98%);
--additive: hsl(112 50% 36%);
--additive-foreground: hsl(0 0% 9%);
--destructive: hsl(0 62.8% 30.6%);
--destructive-foreground: hsl(0 0% 98%);
--border: hsl(0 0% 14.9%);
--ring: hsl(0 0% 83.1%);
}
@layer base {
*,
*::before,
*::after {
@apply border-border;
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-border, currentColor);
}
html {
@ -77,13 +113,16 @@
.disable-transitions,
.disable-transitions * {
@apply !transition-none;
@apply transition-none!;
}
}
@layer components {
article {
@apply prose-headings:scroll-mt-20 prose-headings:break-words first:prose-headings:mt-0 prose-p:break-words prose-a:!break-words prose-a:!decoration-muted-foreground prose-a:underline-offset-[3px] prose-a:transition-colors hover:prose-a:!decoration-foreground prose-pre:!px-0 prose-img:mx-auto;
@apply prose-headings:scroll-mt-20 prose-headings:break-words [&>section]:first:prose-headings:mt-0!;
@apply prose-p:break-words;
@apply prose-a:break-words! prose-a:decoration-muted-foreground! prose-a:underline-offset-[3px] prose-a:transition-colors prose-a:hover:decoration-foreground!;
@apply prose-pre:px-0! prose-img:mx-auto;
.katex-display {
@apply overflow-x-auto overflow-y-hidden py-4;
@ -93,99 +132,15 @@
mark {
@apply bg-transparent;
}
/* Blanket syntax highlighting */
code[data-theme*=' '] {
span {
color: var(--shiki-light);
}
.dark & span {
color: var(--shiki-dark);
}
/* Adjacent expressive-code blocks */
div.expressive-code:has(+ div.expressive-code) {
@apply mb-4;
}
/* Inline code */
:not(pre) > code {
@apply relative rounded bg-muted/50 px-[0.3rem] py-[0.2rem] font-mono text-sm font-medium;
}
/* Code blocks */
figure[data-rehype-pretty-code-figure] {
@apply relative;
/* Code block titles */
[data-rehype-pretty-code-title] {
@apply break-words rounded-t-xl border-x border-t px-4 py-2 text-sm font-medium text-foreground;
/* Remove top margin from code block if a title is present */
& + pre {
@apply mt-0 rounded-t-none;
}
}
/* Shadcn-like scrollbar */
pre::-webkit-scrollbar {
@apply h-2.5 w-2.5;
}
pre::-webkit-scrollbar-track {
@apply bg-transparent;
}
pre::-webkit-scrollbar-thumb {
@apply rounded-full bg-border bg-clip-padding p-px;
}
/* Code block styles */
pre {
@apply static max-h-[600px] overflow-auto rounded-xl border bg-secondary/20 py-4 text-sm leading-loose;
/* Code block content */
> code {
@apply whitespace-pre-wrap;
counter-reset: line;
/* For code blocks with line numbers */
&[data-line-numbers] {
> [data-line]::before {
counter-increment: line;
content: counter(line);
@apply mr-4 inline-block w-4 text-right text-muted-foreground;
}
}
/* For each line in the code block */
> [data-line] {
@apply px-4;
}
/* Highlighted lines */
[data-highlighted-line] {
@apply bg-foreground/10;
}
/* Highlighted characters */
[data-highlighted-chars] > span {
@apply bg-muted-foreground/40 py-[7px];
}
/* Diff lines */
.diff {
&.add {
@apply bg-additive/15;
}
&.remove {
@apply bg-destructive/15;
}
}
/* Copy button */
> button:has(> span) {
@apply right-0.5 top-[3px] m-0 size-8 rounded-md bg-background p-1 backdrop-blur-none transition-all;
}
}
}
@apply bg-muted/50 relative rounded-sm px-[0.3rem] py-[0.2rem] font-mono text-sm font-medium before:content-none! after:content-none!;
}
}
}