feat: dedicated typography file, remove tailwind-typography
This commit is contained in:
parent
8cf00868c4
commit
bbdb1ef828
18 changed files with 160 additions and 87 deletions
31
README.md
31
README.md
|
@ -124,20 +124,23 @@ Colors are defined in `src/styles/global.css` in [<abbr title="Hue, Saturation,
|
||||||
|
|
||||||
```css
|
```css
|
||||||
:root {
|
:root {
|
||||||
--background: hsl(0 0% 100%);
|
--background: oklch(1 0 0);
|
||||||
--foreground: hsl(0 0% 3.9%);
|
--foreground: oklch(0.145 0 0);
|
||||||
--primary: hsl(0 0% 9%);
|
--card: oklch(1 0 0);
|
||||||
--primary-foreground: hsl(0 0% 98%);
|
--card-foreground: oklch(0.145 0 0);
|
||||||
--secondary: hsl(0 0% 80.1%);
|
--popover: oklch(1 0 0);
|
||||||
--secondary-foreground: hsl(0 0% 9%);
|
--popover-foreground: oklch(0.145 0 0);
|
||||||
--muted: hsl(0 0% 80.1%);
|
--primary: oklch(0.205 0 0);
|
||||||
--muted-foreground: hsl(0 0% 45.1%);
|
--primary-foreground: oklch(0.985 0 0);
|
||||||
--accent: hsl(0 0% 80.1%);
|
--secondary: oklch(0.97 0 0);
|
||||||
--accent-foreground: hsl(0 0% 9%);
|
--secondary-foreground: oklch(0.205 0 0);
|
||||||
--destructive: hsl(0 84.2% 60.2%);
|
--muted: oklch(0.97 0 0);
|
||||||
--destructive-foreground: hsl(0 0% 98%);
|
--muted-foreground: oklch(0.556 0 0);
|
||||||
--border: hsl(0 0% 89.8%);
|
--accent: oklch(0.97 0 0);
|
||||||
--ring: hsl(0 0% 3.9%);
|
--accent-foreground: oklch(0.205 0 0);
|
||||||
|
--destructive: oklch(0.577 0.245 27.325);
|
||||||
|
--border: oklch(0.922 0 0);
|
||||||
|
--ring: oklch(0.708 0 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import expressiveCode from 'astro-expressive-code'
|
||||||
import { rehypeHeadingIds } from '@astrojs/markdown-remark'
|
import { rehypeHeadingIds } from '@astrojs/markdown-remark'
|
||||||
import rehypeExternalLinks from 'rehype-external-links'
|
import rehypeExternalLinks from 'rehype-external-links'
|
||||||
import rehypeKatex from 'rehype-katex'
|
import rehypeKatex from 'rehype-katex'
|
||||||
import sectionize from '@hbsnow/rehype-sectionize'
|
// import sectionize from '@hbsnow/rehype-sectionize'
|
||||||
import remarkEmoji from 'remark-emoji'
|
import remarkEmoji from 'remark-emoji'
|
||||||
import remarkMath from 'remark-math'
|
import remarkMath from 'remark-math'
|
||||||
import remarkToc from 'remark-toc'
|
import remarkToc from 'remark-toc'
|
||||||
|
@ -89,7 +89,7 @@ export default defineConfig({
|
||||||
],
|
],
|
||||||
rehypeHeadingIds,
|
rehypeHeadingIds,
|
||||||
rehypeKatex,
|
rehypeKatex,
|
||||||
sectionize,
|
// sectionize,
|
||||||
],
|
],
|
||||||
remarkPlugins: [remarkToc, remarkMath, remarkEmoji],
|
remarkPlugins: [remarkToc, remarkMath, remarkEmoji],
|
||||||
},
|
},
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.7.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/typography": "^0.5.16",
|
|
||||||
"prettier": "^3.5.1",
|
"prettier": "^3.5.1",
|
||||||
"prettier-plugin-astro": "^0.14.1",
|
"prettier-plugin-astro": "^0.14.1",
|
||||||
"prettier-plugin-astro-organize-imports": "^0.4.11",
|
"prettier-plugin-astro-organize-imports": "^0.4.11",
|
||||||
|
|
|
@ -23,7 +23,7 @@ const authors = await parseAuthors(entry.data.authors ?? [])
|
||||||
---
|
---
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="not-prose hover:bg-secondary/50 rounded-xl border p-4 transition-colors duration-300 ease-in-out"
|
class="hover:bg-secondary/50 rounded-xl border p-4 transition-colors duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
href={`/${entry.collection}/${entry.id}`}
|
href={`/${entry.collection}/${entry.id}`}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
import '../styles/global.css'
|
import '../styles/global.css'
|
||||||
import '../styles/katex.css'
|
import '../styles/typography.css'
|
||||||
|
|
||||||
import { SITE } from '@/consts'
|
import { SITE } from '@/consts'
|
||||||
import { ClientRouter } from 'astro:transitions'
|
import { ClientRouter } from 'astro:transitions'
|
||||||
|
|
|
@ -12,7 +12,7 @@ const { project } = Astro.props
|
||||||
---
|
---
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="not-prose hover:bg-secondary/50 rounded-xl border p-4 transition-colors duration-300 ease-in-out"
|
class="hover:bg-secondary/50 rounded-xl border p-4 transition-colors duration-300 ease-in-out"
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
href={project.data.link}
|
href={project.data.link}
|
||||||
|
|
|
@ -29,7 +29,7 @@ const getSocialLink = ({ href, label }: SocialLink) => ({
|
||||||
})
|
})
|
||||||
---
|
---
|
||||||
|
|
||||||
<ul class={cn('not-prose flex flex-wrap gap-2', className)} role="list">
|
<ul class={cn('flex flex-wrap gap-2', className)} role="list">
|
||||||
{
|
{
|
||||||
links.map((link) => {
|
links.map((link) => {
|
||||||
const { href, ariaLabel, iconName } = getSocialLink(link)
|
const { href, ariaLabel, iconName } = getSocialLink(link)
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { cn } from '@/lib/utils'
|
||||||
>
|
>
|
||||||
<div class="max-w-md">
|
<div class="max-w-md">
|
||||||
<h1 class="mb-4 text-3xl font-medium">404: Page not found</h1>
|
<h1 class="mb-4 text-3xl font-medium">404: Page not found</h1>
|
||||||
<p class="prose prose-neutral dark:prose-invert">
|
<p class="prose">
|
||||||
Oops! The page you're looking for doesn't exist.
|
Oops! The page you're looking for doesn't exist.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,7 +16,7 @@ const projects = await getCollection('projects')
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="min-w-full">
|
<div class="min-w-full">
|
||||||
<div class="prose prose-neutral dark:prose-invert mb-8">
|
<div class="prose mb-8">
|
||||||
<p class="mb-4">
|
<p class="mb-4">
|
||||||
astro-erudite is an opinionated, no-frills static blogging template
|
astro-erudite is an opinionated, no-frills static blogging template
|
||||||
that prioritizes simplicity and performance, built with <Link
|
that prioritizes simplicity and performance, built with <Link
|
||||||
|
|
|
@ -47,7 +47,7 @@ const authorPosts = allPosts
|
||||||
<h2 class="text-2xl font-medium">Posts by {author.data.name}</h2>
|
<h2 class="text-2xl font-medium">Posts by {author.data.name}</h2>
|
||||||
{
|
{
|
||||||
authorPosts.length > 0 ? (
|
authorPosts.length > 0 ? (
|
||||||
<ul class="not-prose flex flex-col gap-4">
|
<ul class="flex flex-col gap-4">
|
||||||
{authorPosts.map((post) => (
|
{authorPosts.map((post) => (
|
||||||
<li>
|
<li>
|
||||||
<BlogCard entry={post} />
|
<BlogCard entry={post} />
|
||||||
|
|
|
@ -13,7 +13,7 @@ const authors = await getCollection('authors')
|
||||||
<Breadcrumbs items={[{ label: 'Authors', icon: 'lucide:users' }]} />
|
<Breadcrumbs items={[{ label: 'Authors', icon: 'lucide:users' }]} />
|
||||||
{
|
{
|
||||||
authors.length > 0 ? (
|
authors.length > 0 ? (
|
||||||
<ul class="not-prose flex flex-col gap-4">
|
<ul class="flex flex-col gap-4">
|
||||||
{authors.map((author) => (
|
{authors.map((author) => (
|
||||||
<li>
|
<li>
|
||||||
<AuthorCard author={author} />
|
<AuthorCard author={author} />
|
||||||
|
|
|
@ -153,7 +153,7 @@ const authors = await parseAuthors(post.data.authors ?? [])
|
||||||
{headings.length > 0 && <TableOfContents headings={headings} />}
|
{headings.length > 0 && <TableOfContents headings={headings} />}
|
||||||
|
|
||||||
<article
|
<article
|
||||||
class="prose prose-neutral dark:prose-invert col-start-2 max-w-none"
|
class="prose col-start-2 max-w-none"
|
||||||
>
|
>
|
||||||
<Content />
|
<Content />
|
||||||
</article>
|
</article>
|
||||||
|
|
|
@ -48,7 +48,7 @@ const years = Object.keys(postsByYear).sort((a, b) => parseInt(b) - parseInt(a))
|
||||||
years.map((year) => (
|
years.map((year) => (
|
||||||
<section class="flex flex-col gap-y-4">
|
<section class="flex flex-col gap-y-4">
|
||||||
<div class="font-medium">{year}</div>
|
<div class="font-medium">{year}</div>
|
||||||
<ul class="not-prose flex flex-col gap-4">
|
<ul class="flex flex-col gap-4">
|
||||||
{postsByYear[year].map((post) => (
|
{postsByYear[year].map((post) => (
|
||||||
<li>
|
<li>
|
||||||
<BlogCard entry={post} />
|
<BlogCard entry={post} />
|
||||||
|
|
|
@ -3,13 +3,6 @@ import BlogCard from '@/components/BlogCard.astro'
|
||||||
import Container from '@/components/Container.astro'
|
import Container from '@/components/Container.astro'
|
||||||
import Link from '@/components/Link.astro'
|
import Link from '@/components/Link.astro'
|
||||||
import { buttonVariants } from '@/components/ui/button'
|
import { buttonVariants } from '@/components/ui/button'
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardDescription,
|
|
||||||
CardHeader,
|
|
||||||
CardTitle,
|
|
||||||
} from '@/components/ui/card'
|
|
||||||
import { SITE } from '@/consts'
|
import { SITE } from '@/consts'
|
||||||
import Layout from '@/layouts/Layout.astro'
|
import Layout from '@/layouts/Layout.astro'
|
||||||
import { getCollection } from 'astro:content'
|
import { getCollection } from 'astro:content'
|
||||||
|
@ -23,15 +16,12 @@ const blog = (await getCollection('blog'))
|
||||||
<Layout title="Home" description={SITE.DESCRIPTION}>
|
<Layout title="Home" description={SITE.DESCRIPTION}>
|
||||||
<Container class="flex flex-col gap-y-6">
|
<Container class="flex flex-col gap-y-6">
|
||||||
<section>
|
<section>
|
||||||
<Card>
|
<div class="rounded-lg border">
|
||||||
<CardHeader>
|
<div class="flex flex-col space-y-1.5 p-6">
|
||||||
<CardTitle className="text-3xl">er·u·dite</CardTitle>
|
<h3 class="text-3xl font-medium leading-none">er·u·dite</h3>
|
||||||
<CardDescription
|
<p class="text-sm text-muted-foreground">/ˈer(y)əˌdīt/ • <span class="font-medium">adjective</span></p>
|
||||||
>/ˈer(y)əˌdīt/ • <span class="font-medium">adjective</span
|
</div>
|
||||||
></CardDescription
|
<div class="p-6 pt-0">
|
||||||
>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<p class="text-muted-foreground mb-2 text-sm">
|
<p class="text-muted-foreground mb-2 text-sm">
|
||||||
astro-erudite is an opinionated, no-frills static blogging template
|
astro-erudite is an opinionated, no-frills static blogging template
|
||||||
built with <Link
|
built with <Link
|
||||||
|
@ -69,12 +59,12 @@ const blog = (await getCollection('blog'))
|
||||||
underline>The State of Static Blogs in 2024</Link
|
underline>The State of Static Blogs in 2024</Link
|
||||||
>.
|
>.
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</div>
|
||||||
</Card>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="flex flex-col gap-y-4">
|
<section class="flex flex-col gap-y-4">
|
||||||
<h2 class="text-2xl font-medium">Latest posts</h2>
|
<h2 class="text-2xl font-medium">Latest posts</h2>
|
||||||
<ul class="not-prose flex flex-col gap-y-4">
|
<ul class="flex flex-col gap-y-4">
|
||||||
{
|
{
|
||||||
blog.map((post) => (
|
blog.map((post) => (
|
||||||
<li>
|
<li>
|
||||||
|
|
|
@ -56,7 +56,7 @@ export async function getStaticPaths() {
|
||||||
posts.map((post) => (
|
posts.map((post) => (
|
||||||
<section class="flex flex-col gap-y-4">
|
<section class="flex flex-col gap-y-4">
|
||||||
<div>
|
<div>
|
||||||
<ul class="not-prose flex flex-col gap-4">
|
<ul class="flex flex-col gap-4">
|
||||||
<li>
|
<li>
|
||||||
<BlogCard entry={post} />
|
<BlogCard entry={post} />
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
@import 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css';
|
||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
@plugin '@tailwindcss/typography';
|
|
||||||
|
|
||||||
@custom-variant dark (&:is(.dark *));
|
@custom-variant dark (&:is(.dark *));
|
||||||
|
|
||||||
|
@ -53,13 +53,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--radius: 0.625rem;
|
|
||||||
--background: oklch(1 0 0);
|
--background: oklch(1 0 0);
|
||||||
--foreground: oklch(0.145 0 0);
|
--foreground: oklch(0.145 0 0);
|
||||||
--card: oklch(1 0 0);
|
|
||||||
--card-foreground: oklch(0.145 0 0);
|
|
||||||
--popover: oklch(1 0 0);
|
|
||||||
--popover-foreground: oklch(0.145 0 0);
|
|
||||||
--primary: oklch(0.205 0 0);
|
--primary: oklch(0.205 0 0);
|
||||||
--primary-foreground: oklch(0.985 0 0);
|
--primary-foreground: oklch(0.985 0 0);
|
||||||
--secondary: oklch(0.97 0 0);
|
--secondary: oklch(0.97 0 0);
|
||||||
|
@ -76,10 +71,6 @@
|
||||||
.dark {
|
.dark {
|
||||||
--background: oklch(0.145 0 0);
|
--background: oklch(0.145 0 0);
|
||||||
--foreground: oklch(0.985 0 0);
|
--foreground: oklch(0.985 0 0);
|
||||||
--card: oklch(0.205 0 0);
|
|
||||||
--card-foreground: oklch(0.985 0 0);
|
|
||||||
--popover: oklch(0.205 0 0);
|
|
||||||
--popover-foreground: oklch(0.985 0 0);
|
|
||||||
--primary: oklch(0.922 0 0);
|
--primary: oklch(0.922 0 0);
|
||||||
--primary-foreground: oklch(0.205 0 0);
|
--primary-foreground: oklch(0.205 0 0);
|
||||||
--secondary: oklch(0.269 0 0);
|
--secondary: oklch(0.269 0 0);
|
||||||
|
@ -120,32 +111,3 @@
|
||||||
@apply transition-none!;
|
@apply transition-none!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer components {
|
|
||||||
article {
|
|
||||||
@apply prose-headings:scroll-mt-20 prose-headings:break-words [&>section]:first:prose-headings:mt-0!;
|
|
||||||
@apply prose-headings:font-medium! prose-code:font-medium!;
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Removes background from <mark> elements */
|
|
||||||
mark {
|
|
||||||
@apply bg-transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adjacent expressive-code blocks */
|
|
||||||
div.expressive-code:has(+ div.expressive-code) {
|
|
||||||
@apply mb-4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inline code */
|
|
||||||
:not(pre) > code {
|
|
||||||
@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!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
@import 'https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css';
|
|
120
src/styles/typography.css
Normal file
120
src/styles/typography.css
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
@reference './global.css';
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
.prose {
|
||||||
|
@apply text-foreground text-base leading-8 [&>*]:first:mt-0 [&>*]:last:mb-0;
|
||||||
|
|
||||||
|
p {
|
||||||
|
@apply text-foreground/80 my-5 leading-7 [&:not(:first-child)]:mt-5;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
@apply text-foreground mt-0 mb-6 scroll-m-20 text-4xl leading-tight font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
@apply text-foreground mt-8 mb-4 scroll-m-20 text-2xl leading-tight font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
@apply text-foreground mt-6 mb-4 scroll-m-20 text-xl leading-snug font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
@apply text-foreground mt-6 mb-3 scroll-m-20 text-lg leading-normal font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
@apply text-foreground mt-5 mb-3 scroll-m-20 leading-normal font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
@apply text-foreground mt-5 mb-3 scroll-m-20 leading-normal font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply text-foreground decoration-muted-foreground hover:decoration-foreground font-medium break-words underline underline-offset-[3px] transition-colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
@apply text-foreground font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
@apply marker:text-foreground/30 my-5 ml-6 list-disc [&>li]:mt-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
@apply marker:text-foreground/30 my-5 ml-6 list-decimal [&>li]:mt-4;
|
||||||
|
@apply [&[type='A']]:list-[upper-alpha] [&[type='I']]:list-[upper-roman] [&[type='a']]:list-[lower-alpha] [&[type='i']]:list-[lower-roman];
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
@apply text-foreground/80 pl-2 leading-7 [&>p]:my-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul ul,
|
||||||
|
ol ol,
|
||||||
|
ul ol,
|
||||||
|
ol ul {
|
||||||
|
@apply marker:text-foreground/30 my-2 ml-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
@apply bg-muted/50 text-foreground relative rounded-sm px-[0.3rem] py-[0.2rem] text-sm font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expressive-code {
|
||||||
|
@apply my-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
@apply my-6 border-l-2 pl-6 text-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
@apply border-border my-8 border-t;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
@apply my-8 w-full text-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead {
|
||||||
|
@apply border-muted-foreground/30 border-b;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
@apply border px-4 py-2 text-left font-medium [&[align=center]]:text-center [&[align=right]]:text-right;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr {
|
||||||
|
@apply border-muted-foreground/20 even:bg-muted/50 border-b;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
@apply border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right;
|
||||||
|
}
|
||||||
|
|
||||||
|
img,
|
||||||
|
video {
|
||||||
|
@apply my-8;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
@apply my-8;
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
@apply text-muted-foreground mt-3 text-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
@apply text-foreground bg-muted border-border rounded-md border px-2 py-1 text-xs font-medium shadow-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.katex-display {
|
||||||
|
@apply my-6 overflow-x-auto overflow-y-hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue