From dfeb181a1d781d5bcdcf7240a67e594f3a170e50 Mon Sep 17 00:00:00 2001 From: Alex Lebens Date: Sun, 15 Mar 2026 22:38:23 -0500 Subject: [PATCH] feat: consolidate css into tailwind --- src/styles/global.css | 120 ++++++++++++++---------- src/styles/utilities-buttons.css | 51 +++++++++++ src/styles/utilities-cards.css | 79 ++++++++++++++++ src/styles/utilities-misc.css | 44 +++++++++ src/styles/utilities.css | 152 ------------------------------- tailwind.config.js | 62 +------------ 6 files changed, 250 insertions(+), 258 deletions(-) create mode 100644 src/styles/utilities-buttons.css create mode 100644 src/styles/utilities-cards.css create mode 100644 src/styles/utilities-misc.css delete mode 100644 src/styles/utilities.css diff --git a/src/styles/global.css b/src/styles/global.css index f57b4f7..dee3ca7 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -1,5 +1,7 @@ @import 'tailwindcss'; -@import './utilities.css'; +@import './utilities-buttons.css'; +@import './utilities-cards.css'; +@import './utilities-misc.css'; @plugin '@tailwindcss/typography'; @plugin '@tailwindcss/forms'; @@ -43,6 +45,33 @@ --color-background-card: light-dark(color-mix(in srgb, var(--color-neutral-100) 80%, transparent), color-mix(in srgb, var(--color-neutral-800) 60%, transparent)); --color-divider: light-dark(color-mix(in srgb, var(--color-slate-400) 40%, transparent), color-mix(in srgb, var(--color-neutral-500) 50%, transparent)); + + /* Typography */ + --color-prose-blog-body: var(--color-neutral-700); + --color-prose-blog-headings: var(--color-neutral-900); + --color-prose-blog-links: var(--color-orange-300); + + --color-prose-blog-invert-body: var(--color-neutral-400); + --color-prose-blog-invert-headings: var(--color-neutral-200); + + --radius-markdown-img: 0.5rem; + + /* Shiki */ + --color-shiki-bg: light-dark(var(--color-neutral-200), var(--color-neutral-800)); + --color-shiki-text: light-dark(var(--shiki-light), var(--shiki-dark)); + + /* Reveal Animations */ + --animate-reveal: reveal 0.8s ease forwards; + --animate-reveal-fade: reveal-fade 1.8s ease forwards; + + @keyframes reveal { + from { opacity: 0; transform: translateY(20px); } + to { opacity: 1; transform: translateY(0); } + } + @keyframes reveal-fade { + from { opacity: 0; } + to { opacity: 1; } + } } @layer base { @@ -51,7 +80,6 @@ -moz-osx-font-smoothing: grayscale; --theme-transition: 0.3s ease; - --scroll-offset: 0px; } :root:where(.dark, .dark *) { @@ -90,56 +118,56 @@ border-color var(--theme-transition); } - /* Shiki syntax highlighting */ - :root { - --shiki-fg: var(--shiki-light); - --shiki-bg: var(--color-neutral-200); + /* Typography */ + .prose blockquote { + font-style: normal; + quotes: none; } - .dark { - --shiki-fg: var(--shiki-dark); - --shiki-bg: var(--color-neutral-800); + .prose img { + @apply rounded-lg; } + .prose-blog { + --tw-prose-body: var(--color-neutral-700); + --tw-prose-headings: var(--color-neutral-900); + --tw-prose-lead: var(--color-neutral-700); + --tw-prose-links: var(--color-orange-300); + --tw-prose-bold: var(--color-neutral-900); + --tw-prose-counters: var(--color-neutral-600); + --tw-prose-bullets: var(--color-neutral-400); + --tw-prose-hr: var(--color-neutral-300); + --tw-prose-quotes: var(--color-neutral-500); + --tw-prose-quote-borders: var(--color-neutral-300); + --tw-prose-captions: var(--color-neutral-700); + --tw-prose-code: var(--color-neutral-700); + --tw-prose-pre-code: var(--color-neutral-900); + --tw-prose-pre-bg: var(--color-white); + --tw-prose-th-borders: var(--color-neutral-300); + --tw-prose-td-borders: var(--color-neutral-200); + + &:where(.dark, .dark *) { + --tw-prose-body: var(--color-neutral-400); + --tw-prose-headings: var(--color-neutral-200); + --tw-prose-lead: var(--color-neutral-300); + --tw-prose-links: var(--color-orange-300); + --tw-prose-bold: var(--color-neutral-300); + --tw-prose-counters: var(--color-neutral-400); + --tw-prose-bullets: var(--color-neutral-600); + --tw-prose-hr: var(--color-neutral-700); + --tw-prose-quotes: var(--color-neutral-500); + --tw-prose-quote-borders: var(--color-neutral-500); + --tw-prose-captions: var(--color-neutral-400); + --tw-prose-code: var(--color-neutral-350); + --tw-prose-pre-code: var(--color-neutral-300); + --tw-prose-th-borders: var(--color-neutral-600); + --tw-prose-td-borders: var(--color-neutral-700); + } + } + + /* Shiki */ pre.shiki { background-color: var(--shiki-bg) !important; color: var(--shiki-fg) !important; } - - pre.shiki span { - color: var(--shiki-light); - } - - .dark pre.shiki span { - color: var(--shiki-dark) !important; - } -} - -/* Content reveal animations */ -.smooth-reveal, -.smooth-reveal-2, -.smooth-reveal-cards { - opacity: 0; - transform: translateY(20px); - transition: - opacity 0.8s ease, - transform 0.8s ease; -} - -.animate-reveal { - opacity: 1 !important; - transform: translateY(0) !important; -} - -.smooth-reveal-fade { - opacity: 0; - transform: translateY(0px); - transition: - opacity 1.8s ease, - transform 0.8s ease; -} - -.animate-reveal-fade { - opacity: 1 !important; - transform: translateY(0) !important; } diff --git a/src/styles/utilities-buttons.css b/src/styles/utilities-buttons.css new file mode 100644 index 0000000..85df765 --- /dev/null +++ b/src/styles/utilities-buttons.css @@ -0,0 +1,51 @@ +@utility button-base { + @apply transition-all duration-300 + border border-transparent + shadow-sm hover:shadow-md dark:shadow-md dark:hover:shadow-lg + px-4 py-3 +} + +@utility button-base-hidden { + @apply transition-all duration-300 + border border-transparent + hover:bg-neutral-200 dark:hover:bg-neutral-700 + p-2 +} + +@utility button-hover-arrow { + @apply translate-y-px transition duration-300 + group-hover:translate-x-1 + h-3 w-3 md:h-5 md:w-5 +} + +@utility button-text-title { + @apply text-neutral-200 2xl:text-base + text-sm font-bold +} + +@utility button-text-title-hidden { + @apply transition-all duration-300 + text-neutral-600 group-hover:text-neutral-700 dark:text-neutral-400 dark:group-hover:text-neutral-300 2xl:text-base + text-sm font-medium +} + +@utility button-bg-blue { + @apply transition-all duration-300 + bg-cobalt hover:bg-steel dark:bg-steel dark:hover:bg-cobalt +} + +@utility button-bg-teal { + @apply transition-all duration-300 + bg-bermuda hover:bg-turquoise group-hover:bg-turquoise dark:bg-turquoise dark:hover:bg-bermuda dark:group-hover:bg-bermuda +} + +@utility button-bg-neutral { + @apply transition-all duration-300 + border border-neutral-100 dark:border-stone-500/20 + bg-background-card hover:bg-neutral-100 dark:hover:bg-neutral-800/90 +} + +@utility button-bg-gitea { + @apply transition-all duration-300 + bg-gitea-primary hover:bg-gitea-secondary dark:bg-gitea-secondary dark:hover:bg-gitea-primary +} diff --git a/src/styles/utilities-cards.css b/src/styles/utilities-cards.css new file mode 100644 index 0000000..74da20f --- /dev/null +++ b/src/styles/utilities-cards.css @@ -0,0 +1,79 @@ +@utility card-base { + @apply transition-all duration-300 + rounded-xl + border border-neutral-100 dark:border-stone-500/20 + bg-background-card hover:bg-neutral-100 dark:hover:bg-neutral-800/90 + shadow-xs hover:shadow-md dark:shadow-md dark:hover:shadow-lg +} + +@utility card-base-hidden { + @apply transition-all duration-300 + rounded-2xl + border border-transparent + hover:bg-neutral-400/20 dark:hover:bg-neutral-800/40 +} + +@utility card-hover-icon-color { + @apply transition-all duration-300 + text-primary + group-hover:text-main +} + +@utility card-hover-icon-scale { + @apply transition-transform duration-300 will-change-transform + drop-shadow-md dark:drop-shadow-xl dark:drop-shadow-neutral-500/60 + group-hover:scale-3d group-hover:scale-105 +} + +@utility card-text-header { + @apply text-header + text-4xl md:text-5xl + font-bold leading-tight tracking-tight text-balance +} + +@utility card-text-header-minor { + @apply text-header + text-2xl md:text-3xl + font-semibold leading-tight tracking-tight text-balance +} + +@utility card-text-header-description { + @apply text-primary + text-lg + text-pretty leading-relaxed +} + +@utility card-text-title { + @apply text-primary + font-bold +} + +@utility card-text-title-major { + @apply text-header + text-4xl md:text-3xl + font-bold leading-tight tracking-tight text-balance +} + +@utility card-hover-text-title { + @apply transition-all duration-300 + group-hover:text-main +} + +@utility card-hover-text-neutral { + @apply transition-all duration-300 + group-hover:text-primary-hover +} + +@utility card-hover-text-gitea { + @apply transition-all duration-300 + group-hover:text-gitea-primary +} + +@utility card-text-description { + @apply text-secondary +} + +@utility card-hover-text-description { + @apply transition-all duration-300 + text-secondary-hover +} diff --git a/src/styles/utilities-misc.css b/src/styles/utilities-misc.css new file mode 100644 index 0000000..387214f --- /dev/null +++ b/src/styles/utilities-misc.css @@ -0,0 +1,44 @@ +/* Nav */ +@utility nav-base { + @apply border border-neutral-100 dark:border-stone-500/20 + bg-neutral-100 dark:bg-neutral-800 + shadow-xs dark:shadow-md +} + +/* Fade edges of a div */ +@utility mask-fade-edges { + -webkit-mask-image: + linear-gradient(to right, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent), + linear-gradient(to bottom, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent); + mask-image: + linear-gradient(to right, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent), + linear-gradient(to bottom, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent); + + -webkit-mask-composite: source-in; + mask-composite: intersect; +} + +/* Animations */ +@utility smooth-reveal { + opacity: 0; + transform: translateY(20px); + transition: opacity 0.8s ease, transform 0.8s ease; +} + +@utility smooth-reveal-2 { + opacity: 0; + transform: translateY(20px); + transition: opacity 0.8s ease, transform 0.8s ease; +} + +@utility smooth-reveal-cards { + opacity: 0; + transform: translateY(20px); + transition: opacity 0.8s ease, transform 0.8s ease; +} + +@utility smooth-reveal-fade { + opacity: 0; + transform: translateY(0px); + transition: opacity 1.8s ease, transform 0.8s ease; +} diff --git a/src/styles/utilities.css b/src/styles/utilities.css deleted file mode 100644 index 10c792c..0000000 --- a/src/styles/utilities.css +++ /dev/null @@ -1,152 +0,0 @@ -/* Button classes */ -@utility button-base { - @apply transition-all duration-300 - border border-transparent - shadow-sm hover:shadow-md dark:shadow-md dark:hover:shadow-lg - px-4 py-3 -} - -@utility button-base-hidden { - @apply transition-all duration-300 - border border-transparent - hover:bg-neutral-200 dark:hover:bg-neutral-700 - p-2 -} - -@utility button-hover-arrow { - @apply translate-y-px transition duration-300 - group-hover:translate-x-1 - h-3 w-3 md:h-5 md:w-5 -} - -@utility button-text-title { - @apply text-neutral-200 2xl:text-base - text-sm font-bold -} - -@utility button-text-title-hidden { - @apply transition-all duration-300 - text-neutral-600 group-hover:text-neutral-700 dark:text-neutral-400 dark:group-hover:text-neutral-300 2xl:text-base - text-sm font-medium -} - -@utility button-bg-blue { - @apply transition-all duration-300 - bg-cobalt hover:bg-steel dark:bg-steel dark:hover:bg-cobalt -} - -@utility button-bg-teal { - @apply transition-all duration-300 - bg-bermuda hover:bg-turquoise group-hover:bg-turquoise dark:bg-turquoise dark:hover:bg-bermuda dark:group-hover:bg-bermuda -} - -@utility button-bg-neutral { - @apply transition-all duration-300 - border border-neutral-100 dark:border-stone-500/20 - bg-background-card hover:bg-neutral-100 dark:hover:bg-neutral-800/90 -} - -@utility button-bg-gitea { - @apply transition-all duration-300 - bg-gitea-primary hover:bg-gitea-secondary dark:bg-gitea-secondary dark:hover:bg-gitea-primary -} - -/* Card classes */ -@utility card-base { - @apply transition-all duration-300 - rounded-xl - border border-neutral-100 dark:border-stone-500/20 - bg-background-card hover:bg-neutral-100 dark:hover:bg-neutral-800/90 - shadow-xs hover:shadow-md dark:shadow-md dark:hover:shadow-lg -} - -@utility card-base-hidden { - @apply transition-all duration-300 - rounded-2xl - border border-transparent - hover:bg-neutral-400/20 dark:hover:bg-neutral-800/40 -} - -@utility card-hover-icon-color { - @apply transition-all duration-300 - text-primary - group-hover:text-main -} - -@utility card-hover-icon-scale { - @apply transition-transform duration-300 will-change-transform - drop-shadow-md dark:drop-shadow-xl dark:drop-shadow-neutral-500/60 - group-hover:scale-3d group-hover:scale-105 -} - -@utility card-text-header { - @apply text-header - text-4xl md:text-5xl - font-bold leading-tight tracking-tight text-balance -} - -@utility card-text-header-minor { - @apply text-header - text-2xl md:text-3xl - font-semibold leading-tight tracking-tight text-balance -} - -@utility card-text-header-description { - @apply text-primary - text-lg - text-pretty leading-relaxed -} - -@utility card-text-title { - @apply text-primary - font-bold -} - -@utility card-text-title-major { - @apply text-header - text-4xl md:text-3xl - font-bold leading-tight tracking-tight text-balance -} - -@utility card-hover-text-title { - @apply transition-all duration-300 - group-hover:text-main -} - -@utility card-hover-text-neutral { - @apply transition-all duration-300 - group-hover:text-primary-hover -} - -@utility card-hover-text-gitea { - @apply transition-all duration-300 - group-hover:text-gitea-primary -} - -@utility card-text-description { - @apply text-secondary -} - -@utility card-hover-text-description { - @apply transition-all duration-300 - text-secondary-hover -} - -/* Misc */ -@utility nav-base { - @apply border border-neutral-100 dark:border-stone-500/20 - bg-neutral-100 dark:bg-neutral-800 - shadow-xs dark:shadow-md -} - -@utility mask-fade-edges { - -webkit-mask-image: - linear-gradient(to right, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent), - linear-gradient(to bottom, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent); - mask-image: - linear-gradient(to right, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent), - linear-gradient(to bottom, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent); - - -webkit-mask-composite: source-in; - mask-composite: intersect; -} diff --git a/tailwind.config.js b/tailwind.config.js index 4d835d1..d51e2e9 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,64 +1,6 @@ /** @type {import('tailwindcss').Config} */ export default { - content: [ - './src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}', - './node_modules/preline/preline.js', - ], - darkMode: 'class', - theme: { - extend: { - typography: ({ theme }) => ({ - blog: { - css: { - '--tw-prose-body': theme('colors.neutral[700]'), - '--tw-prose-headings': theme('colors.neutral[900]'), - '--tw-prose-lead': theme('colors.neutral[700]'), - '--tw-prose-links': theme('colors.orange[300]'), - '--tw-prose-bold': theme('colors.neutral[900]'), - '--tw-prose-counters': theme('colors.neutral[600]'), - '--tw-prose-bullets': theme('colors.neutral[400]'), - '--tw-prose-hr': theme('colors.neutral[300]'), - '--tw-prose-quotes': theme('colors.neutral[500]'), - '--tw-prose-quote-borders': theme('colors.neutral[300]'), - '--tw-prose-captions': theme('colors.neutral[700]'), - '--tw-prose-code': theme('colors.neutral[700]'), - '--tw-prose-pre-code': theme('colors.neutral[900]'), - '--tw-prose-pre-bg': theme('colors.white'), - '--tw-prose-th-borders': theme('colors.neutral[300]'), - '--tw-prose-td-borders': theme('colors.neutral[200]'), - - '--tw-prose-invert-body': theme('colors.neutral[400]'), - '--tw-prose-invert-headings': theme('colors.neutral[200]'), - '--tw-prose-invert-lead': theme('colors.neutral[300]'), - '--tw-prose-invert-links': theme('colors.orange[300]'), - '--tw-prose-invert-bold': theme('colors.neutral[300]'), - '--tw-prose-invert-counters': theme('colors.neutral[400]'), - '--tw-prose-invert-bullets': theme('colors.neutral[600]'), - '--tw-prose-invert-hr': theme('colors.neutral[700]'), - '--tw-prose-invert-quotes': theme('colors.neutral[500]'), - '--tw-prose-invert-quote-borders': theme('colors.neutral[500]'), - '--tw-prose-invert-captions': theme('colors.neutral[400]'), - '--tw-prose-invert-code': theme('colors.neutral[350]'), - '--tw-prose-invert-pre-code': theme('colors.neutral[300]'), - '--tw-prose-invert-th-borders': theme('colors.neutral[600]'), - '--tw-prose-invert-td-borders': theme('colors.neutral[700]'), - }, - }, - DEFAULT: { - css: { - blockquote: { - fontStyle: 'normal', - quotes: 'none', - }, - }, - }, - }), - }, - }, - plugins: [ - require('tailwindcss/nesting'), - require('preline/plugin'), - require('@tailwindcss/typography'), - ], + content: ['./node_modules/preline/preline.js'], + plugins: [require('preline/plugin')], };