From a024cc536974b9d16033cacda41d49bba2836fdd Mon Sep 17 00:00:00 2001 From: Krishna Ayyalasomayajula Date: Mon, 1 Jun 2026 22:40:39 -0500 Subject: [PATCH] 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 --- app/globals.css | 125 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/app/globals.css b/app/globals.css index cd4d06a..06fa895 100644 --- a/app/globals.css +++ b/app/globals.css @@ -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";