feat: comprehensive code block CSS

- Borderless container with subtle shadow
- VS Code filename header with dot indicators
- Line numbers via CSS counter
- Copy button (hover-visible)
- Highlighted line accent stripe
- Highlighted chars background
- Shiki dual theme token color switching
- Light and dark mode overrides for all code elements
This commit is contained in:
2026-06-01 22:40:39 -05:00
parent bf93e2cf45
commit a024cc5369

View File

@@ -123,6 +123,131 @@
--shadow-card: 0 1px 4px oklch(1 0 0 / 0.06);
}
/* === Code Blocks: Borderless, VS Code Style, Line Numbers === */
[data-rehype-pretty-code-figure] {
@apply relative overflow-hidden rounded-[var(--radius-code)];
background-color: var(--color-code-block);
border: none;
box-shadow: 0 0 0 1px var(--color-border),
0 2px 8px oklch(0 0 0 / 0.06);
}
.dark [data-rehype-pretty-code-figure] {
box-shadow: 0 0 0 1px var(--color-border),
0 2px 8px oklch(1 0 0 / 0.04);
}
[data-rehype-pretty-code-title] {
@apply relative flex items-center gap-2.5 px-4 py-2 text-xs;
background-color: var(--color-code-title-bg);
border-bottom: 1px solid var(--color-border);
border-radius: var(--radius-code) var(--radius-code) 0 0;
}
.dark [data-rehype-pretty-code-title] {
background-color: var(--color-code-title-bg);
}
[data-rehype-pretty-code-title] + pre {
@apply m-0 rounded-b-[var(--radius-code)] rounded-t-none;
}
[data-rehype-pretty-code-title] .vscode-dots {
@apply inline-flex gap-[6px] mr-2;
}
[data-rehype-pretty-code-title] .vscode-dots span {
@apply block h-2.5 w-2.5 rounded-full;
}
[data-rehype-pretty-code-title] .dot-red {
background-color: var(--color-code-dot-red);
box-shadow: inset 0 0 0 0.5px oklch(0 0 0 / 0.15);
}
[data-rehype-pretty-code-title] .dot-yellow {
background-color: var(--color-code-dot-yellow);
box-shadow: inset 0 0 0 0.5px oklch(0 0 0 / 0.15);
}
[data-rehype-pretty-code-title] .dot-green {
background-color: var(--color-code-dot-green);
box-shadow: inset 0 0 0 0.5px oklch(0 0 0 / 0.15);
}
[data-rehype-pretty-code-figure] pre {
@apply relative overflow-auto p-4;
}
[data-rehype-pretty-code-figure] pre code {
@apply !bg-transparent font-mono text-[13px] leading-[1.6];
display: grid;
}
[data-rehype-pretty-code-figure] code[data-line-numbers] {
counter-reset: line;
}
[data-rehype-pretty-code-figure] code[data-line-numbers] > [data-line]::before {
counter-increment: line;
content: counter(line);
@apply mr-5 inline-block w-4 text-right select-none;
color: var(--color-code-gutter);
@apply text-[11px] font-mono;
}
.dark [data-rehype-pretty-code-figure] code[data-line-numbers] > [data-line]::before {
color: var(--color-code-gutter);
}
[data-rehype-pretty-code-figure] [data-line] {
@apply relative px-2;
border-left: 2px solid transparent;
}
[data-rehype-pretty-code-figure] [data-highlighted-line] {
@apply rounded-r-sm;
background-color: var(--color-code-line-highlight);
border-left-color: var(--color-code-line-highlight-border);
}
[data-rehype-pretty-code-figure] [data-highlighted-chars] {
@apply rounded py-0.5 px-1;
background-color: var(--color-code-mark-bg);
}
[data-rehype-pretty-code-figure] .rehype-pretty-copy {
@apply absolute right-3 top-3 z-10 flex items-center gap-1 rounded-md border px-2 py-1 text-xs font-medium;
background-color: oklch(0.97 0 0 / 0.85);
color: var(--color-code-copy);
opacity: 0;
transition: opacity 0.15s ease;
}
.dark [data-rehype-pretty-code-figure] .rehype-pretty-copy {
background-color: oklch(0.10 0 0 / 0.85);
color: var(--color-code-copy);
}
[data-rehype-pretty-code-figure]:hover .rehype-pretty-copy {
opacity: 1;
}
[data-rehype-pretty-code-figure] .rehype-pretty-copy:hover {
@apply border-current;
background-color: oklch(0.95 0 0 / 0.95);
color: var(--color-code-copy-hover);
}
.dark [data-rehype-pretty-code-figure] .rehype-pretty-copy:hover {
background-color: oklch(0.15 0 0 / 0.95);
}
[data-rehype-pretty-code-figure] .rehype-pretty-copy.rehype-pretty-copied {
@apply border-green-500/50;
color: oklch(0.55 0.18 140);
}
.dark [data-rehype-pretty-code-figure] .rehype-pretty-copy.rehype-pretty-copied {
color: oklch(0.70 0.15 140);
}
/* Shiki dual theme token color switching */
code[data-theme*=" "],
code[data-theme*=" "] span {
color: var(--shiki-light);
}
html.dark code[data-theme*=" "],
html.dark code[data-theme*=" "] span {
color: var(--shiki-dark);
}
/* === Blog typography === */
@plugin "@tailwindcss/typography";