feat: implement blog template

This commit is contained in:
Alejandro Laguna
2025-09-06 20:38:36 +02:00
parent af2a6d33e3
commit 4f0b05c8ef
12 changed files with 1415 additions and 42 deletions

View File

@@ -2,13 +2,25 @@
import { defineConfig } from 'astro/config';
import tailwindcss from "@tailwindcss/vite";
import astroIcon from "astro-icon"
import mdx from '@astrojs/mdx';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
// https://astro.build/config
export default defineConfig({
vite: { plugins: [tailwindcss()], },
integrations: [astroIcon()],
integrations: [
astroIcon(),
],
site: 'https://alejandrolaguna.dev',
base: "/",
markdown: {
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeKatex],
shikiConfig: {
theme: "vesper",
}
},
output: "static",
server: {
host: '0.0.0.0',

914
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,11 +14,15 @@
},
"dependencies": {
"@astrojs/cloudflare": "^12.6.5",
"@astrojs/mdx": "^4.3.4",
"@tailwindcss/vite": "^4.1.11",
"astro": "^5.12.8",
"astro-icon": "^1.1.5",
"katex": "^0.16.22",
"lucide-astro": "^0.536.0",
"lucide-react": "^0.536.0",
"rehype-katex": "^7.0.1",
"remark-math": "^6.0.0",
"serve": "^14.2.4",
"tailwindcss": "^4.1.11"
}

View File

@@ -10,6 +10,7 @@ const workshop = defineCollection({
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
heroImage: image().optional(),
tags: z.array(z.string()).optional()
}),
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,8 @@
---
title: 'My tech'
description: 'My tech'
pubDate: '2025-08-03'
tags: []
---
Yinyoo KZ ZSN Pro (Blue with mic)

View File

@@ -1,16 +0,0 @@
---
title: 'First post'
description: 'Lorem ipsum dolor sit amet'
pubDate: '2025-08-03'
tags: []
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra massa massa ultricies mi.
Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id cursus metus aliquam eleifend mi.
Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.

View File

@@ -0,0 +1,147 @@
---
title: 'Writing an HTTP server in C'
description: 'Lorem ipsum dolor sit amet really long descriptionbla bla bka la bla'
pubDate: '2025-08-03'
tags: ['c', 'programming', 'socket']
heroImage: "../images/OIP.sWCvltMZF_s3mjA5sL-RdgHaE8.jpg"
---
# Lorem Ipsum: A Comprehensive Guide
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. **Ut enim ad minim veniam**, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
## The Origins of Lorem Ipsum
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
### Historical Context
*Sed ut perspiciatis unde omnis* iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
> "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentibus voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident."
>
> — Marcus Tullius Cicero
#### Key Features
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt:
- **Primary advantage**: Lorem ipsum has been the industry's standard dummy text
- **Secondary benefit**: It uses a Latin-like language which is more natural
- **Tertiary aspect**: The distribution of letters approximates English
- **Additional feature**: Available in multiple variations and lengths
##### Numbered List Example
Here's how you might implement lorem ipsum in your workflow:
1. Choose your desired length (short, medium, or long)
2. Select the starting phrase (**Lorem ipsum dolor sit amet**)
3. Generate additional paragraphs as needed
4. Apply formatting using standard markdown syntax
5. Review and adjust for your specific use case
###### Technical Specifications
The standard Lorem Ipsum passage includes these characteristics:
- Contains approximately 500 words
- Uses pseudo-Latin derived from Cicero's work
- Maintains readable character distribution
- Includes both common and uncommon letter combinations
## Code Examples
Here's a simple function to generate lorem ipsum text:
```javascript
function generateLoremIpsum(wordCount = 50) {
const words = [
'lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur',
'adipiscing', 'elit', 'sed', 'do', 'eiusmod', 'tempor'
];
let result = '';
for (let i = 0; i < wordCount; i++) {
result += words[Math.floor(Math.random() * words.length)];
if (i < wordCount - 1) result += ' ';
}
return result.charAt(0).toUpperCase() + result.slice(1) + '.';
}
```
You can also use inline code like `generateLoremIpsum(25)` within your paragraphs.
## Data Tables
Here's a comparison of different lorem ipsum generators:
| Generator | Word Count | Languages | Custom Options |
|-----------|------------|-----------|----------------|
| Lorem Ipsum Generator | 50-500 | Latin | ✅ |
| Hipster Ipsum | 25-200 | English | ✅ |
| Bacon Ipsum | 100-300 | English | ❌ |
| Cat Ipsum | 75-250 | Mixed | ✅ |
## Advanced Formatting
### Text Styling Examples
This text contains **bold formatting** and *italic emphasis*. You can also combine them for ***bold and italic*** text. For technical documentation, you might need to show ~~deleted text~~ or <u>underlined content</u>.
Sometimes you need to highlight important information with ==marked text== or show keyboard shortcuts like <kbd>Ctrl</kbd> + <kbd>C</kbd>.
### Definition Lists
Lorem Ipsum
: Placeholder text commonly used in the printing and typesetting industry
Dolor Sit Amet
: The second phrase in the standard Lorem Ipsum passage
Consectetur Adipiscing
: Latin words meaning "to pursue" and "to obtain"
### Details and Summary
<details>
<summary>Click to expand: More about Lorem Ipsum</summary>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
This hidden content demonstrates how collapsible sections work within the styling system.
</details>
## Mathematical and Scientific Notation
The quadratic formula is expressed as $$ax² + bx + c = 0$$, where the solutions are found using $$x = (-b ± √(b²-4ac))/2a$$.
Chemical formulas like H₂O and CO₂ use subscript notation, while mathematical expressions might use superscript like $$E = mc²$$.
## Links and References
For more information about lorem ipsum, you can visit [Lorem Ipsum Generator](https://www.lipsum.com/) or check out the [Wikipedia article on Lorem Ipsum](https://en.wikipedia.org/wiki/Lorem_ipsum).
You might also find these internal links helpful:
- [Section on Origins](#the-origins-of-lorem-ipsum)
- [Code Examples](#code-examples)
- [Data Tables](#data-tables)
---
## Conclusion
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium. The versatility of Lorem Ipsum makes it an invaluable tool for designers, developers, and content creators worldwide.
<small>*This document was created as a comprehensive test of markdown styling capabilities. All Lorem Ipsum text is used for demonstration purposes only.*</small>
### Footnotes and Citations
According to recent studies¹, Lorem Ipsum remains the most widely used placeholder text in the design industry. Various alternatives² have emerged, but none have achieved the same level of adoption.
---
*¹ Design Industry Survey 2023*
*² Alternative includes Hipster Ipsum, Bacon Ipsum, and Cat Ipsum*

View File

@@ -10,10 +10,11 @@ import { House, Sun, Moon } from "lucide-astro";
<title>Alejandro Laguna</title>
<meta name="description" content="A computer science student's digital lab notebook documenting knowledge, building software, and understanding the world." />
<meta name="generator" content={Astro.generator} />
<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css" integrity="sha384-5TcZemv2l/9On385z///+d7MSYlvIEw9FuZTIdZ14vJLqWphw7e7ZPuOiCHJcFCP" crossorigin="anonymous">
</head>
<body class="bg-neutral-50 text-neutral-900 dark:bg-neutral-900 dark:text-neutral-100 min-h-screen antialiased transition-colors duration-200">
<div class="fixed inset-0 bg-[linear-gradient(rgba(0,0,0,0.03)_1px,transparent_1px),linear-gradient(90deg,rgba(0,0,0,0.03)_1px,transparent_1px)] dark:bg-[linear-gradient(rgba(255,255,255,0.03)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.03)_1px,transparent_1px)] bg-[size:32px_32px] pointer-events-none" aria-hidden="true"></div>

View File

@@ -11,8 +11,7 @@ const {title, description, pubDate} = Astro.props;
---
<Layout>
<h1 class="text-4xl sm:text-5xl font-bold mb-6 text-neutral-900">{title}</h1>
<main class="text-lg text-neutral-600 leading-relaxed text-justify">
<main class="post text-lg text-neutral-600 dark:text-neutral-300 leading-relaxed text-justify">
<slot />
</main>
</Layout>

View File

@@ -1,7 +1,8 @@
<!-- ---
---
import "../../styles/global.css"
import Layout from "../../layouts/Layout.astro"
import { getCollection } from 'astro:content';
import { Image } from 'astro:assets';
const posts = (await getCollection('workshop')).sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
@@ -9,31 +10,88 @@ const posts = (await getCollection('workshop')).sort(
---
<Layout>
<section class="max-w-3xl mb-10 sm:mb-14">
<section class="max-w-7xl mb-10 sm:mb-14">
<h1 class="text-4xl sm:text-5xl font-bold mb-6 text-neutral-900 dark:text-neutral-100">Workshop</h1>
<p class="text-lg text-neutral-600 dark:text-neutral-400 leading-relaxed text-justify">
I'm a second year computer science student at the European Institute of Technology, still trying to figure out my place but enjoying the journey through systems programming, webdev and other fields. Outside of code, my favorite writer is Isaac Asimov, my favorite piece of music is Spiegel im Spiegel, and my favorite book is The Witches by Roald Dahl. My favorite star is Vega because it was once our north star and will be again in about 12,000 years - something poetic about that cycle. And that's pretty much everything you need to know about me, except maybe my tea preferences, but we'll save that for another time... </p>
<p class="text-lg text-neutral-600 dark:text-neutral-400 leading-relaxed text-justify max-w-3xl">
I'm a second year computer science student at the European Institute of Technology, still trying to figure out my place but enjoying the journey through systems programming, webdev and other fields. Outside of code, my favorite writer is Isaac Asimov, my favorite piece of music is Spiegel im Spiegel, and my favorite book is The Witches by Roald Dahl. My favorite star is Vega because it was once our north star and will be again in about 12,000 years - something poetic about that cycle. And that's pretty much everything you need to know about me, except maybe my tea preferences, but we'll save that for another time...
</p>
</section>
<ul class="space-y-4">
{/* Grid layout for posts */}
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6">
{posts.map((post) => (
<li class="p-4 rounded-xl border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-800 hover:shadow-md transition-shadow">
<a href={`/workshop/${post.id}/`} class="block">
<h4 class="text-xl font-semibold text-neutral-900 dark:text-neutral-100 hover:text-neutral-700 dark:hover:text-neutral-300 transition-colors">
{post.data.title}
</h4>
{post.data.pubDate && (
<p class="text-sm text-neutral-500 dark:text-neutral-400 mt-1">
{new Date(post.data.pubDate).toLocaleDateString()}
</p>
<article class="group rounded-xl border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-800 hover:shadow-lg transition-all duration-300 overflow-hidden flex flex-col">
<a href={`/workshop/${post.id}/`} class="block flex flex-col h-full">
{/* Hero Image */}
{post.data.heroImage && (
<div class="aspect-video overflow-hidden">
<Image
src={post.data.heroImage}
alt={post.data.title}
width={800}
height={450}
class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
loading="lazy"
/>
</div>
)}
</a>
</li>
))}
</ul>
</Layout> -->
---
import WorkInProgress from "../../components/WorkInProgress.astro"
---
<WorkInProgress />
<div class="p-4 sm:p-6 flex flex-col flex-grow">
{/* Title */}
<h2 class="text-lg sm:text-xl font-semibold text-neutral-900 dark:text-neutral-100 group-hover:text-neutral-700 dark:group-hover:text-neutral-300 transition-colors mb-2 line-clamp-2">
{post.data.title}
</h2>
{/* Subtitle/Description */}
{post.data.description && (
<p class="text-sm sm:text-base text-neutral-600 dark:text-neutral-400 mb-4 line-clamp-3 leading-relaxed flex-grow">
{post.data.description}
</p>
)}
{/* Tags */}
{post.data.tags && post.data.tags.length > 0 && (
<div class="flex flex-wrap gap-1.5 mb-4">
{post.data.tags.slice(0, 3).map((tag) => (
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-neutral-100 dark:bg-neutral-700 text-neutral-700 dark:text-neutral-300 hover:bg-neutral-200 dark:hover:bg-neutral-600 transition-colors">
#{tag}
</span>
))}
{post.data.tags.length > 3 && (
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-neutral-100 dark:bg-neutral-700 text-neutral-500 dark:text-neutral-400">
+{post.data.tags.length - 3}
</span>
)}
</div>
)}
{/* Publication Date */}
{post.data.pubDate && (
<div class="flex items-center text-xs sm:text-sm text-neutral-500 dark:text-neutral-400 mt-auto">
<svg class="w-3 h-3 sm:w-4 sm:h-4 mr-1.5 sm:mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
<time datetime={post.data.pubDate.toISOString()}>
{new Date(post.data.pubDate).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})}
</time>
{post.data.updatedDate && (
<span class="ml-1 sm:ml-2 text-xs hidden sm:inline">
(Updated {new Date(post.data.updatedDate).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
})})
</span>
)}
</div>
)}
</div>
</a>
</article>
))}
</div>
</Layout>

View File

@@ -31,3 +31,248 @@ h1, h2, h3 {
.nav-card:focus {
transform: translateY(-1px);
}
/* Headings */
.post h1 {
@apply text-3xl sm:text-4xl font-bold mb-6 mt-8 text-neutral-900 dark:text-neutral-100 border-b border-neutral-200 dark:border-neutral-700 pb-2;
}
.post h2 {
@apply text-2xl sm:text-3xl font-bold mb-5 mt-8 text-neutral-900 dark:text-neutral-100 border-b border-neutral-200 dark:border-neutral-700 pb-2;
}
.post h3 {
@apply text-xl sm:text-2xl font-serif font-semibold mb-4 mt-6 text-neutral-800 dark:text-neutral-200;
}
.post h4 {
@apply text-lg sm:text-xl font-serif font-semibold mb-3 mt-5 text-neutral-800 dark:text-neutral-200;
}
.post h5 {
@apply text-base sm:text-lg font-medium mb-3 mt-4 text-neutral-700 dark:text-neutral-300;
}
.post h6 {
@apply text-sm sm:text-base font-serif font-medium mb-2 mt-4 text-neutral-700 dark:text-neutral-300 uppercase tracking-wide;
}
/* Paragraphs and Text */
.post p {
@apply text-lg text-neutral-600 dark:text-neutral-300 leading-relaxed mb-4 text-justify;
}
.post strong, .prose b {
@apply font-semibold text-neutral-800 dark:text-neutral-200;
}
.post em, .prose i {
@apply italic text-neutral-700 dark:text-neutral-300;
}
.post small {
@apply text-sm text-neutral-500 dark:text-neutral-400;
}
.post mark {
@apply bg-yellow-200 dark:bg-yellow-800 text-neutral-900 dark:text-neutral-100 px-1 rounded;
}
.post del, .prose s {
@apply line-through text-neutral-500 dark:text-neutral-400;
}
.post ins, .prose u {
@apply underline text-neutral-700 dark:text-neutral-300;
}
/* Links */
.post a {
@apply text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 underline underline-offset-2 transition-colors duration-200;
}
.post a:visited {
@apply text-purple-600 dark:text-purple-400;
}
/* Lists */
.post ul {
@apply list-disc list-inside mb-4 text-lg text-neutral-600 dark:text-neutral-300 leading-relaxed space-y-2;
}
.post ol {
@apply list-decimal list-inside mb-4 text-lg text-neutral-600 dark:text-neutral-300 leading-relaxed space-y-2;
}
.post li {
@apply mb-1;
}
.post li::marker {
@apply text-neutral-500 dark:text-neutral-400;
}
.post ul ul, .prose ol ol, .prose ul ol, .prose ol ul {
@apply mt-2 mb-2 ml-6;
}
/* Blockquotes */
.post blockquote {
@apply border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 py-2 mb-4 italic text-neutral-700 dark:text-neutral-300 bg-neutral-50 dark:bg-neutral-800 rounded-r-md px-3;
}
.post blockquote p {
@apply mb-2 last:mb-0;
}
.post blockquote cite {
@apply text-sm text-neutral-500 dark:text-neutral-400 not-italic block mt-2;
}
/* Code */
.post code {
@apply bg-neutral-100 dark:bg-neutral-800 text-neutral-800 dark:text-neutral-200 px-2 py-1 rounded text-sm font-mono border border-neutral-200 dark:border-neutral-700;
}
.post pre {
@apply bg-neutral-900 dark:bg-neutral-950 text-neutral-100 dark:text-neutral-200 p-4 rounded-lg overflow-x-auto mb-4 border border-neutral-200 dark:border-neutral-700;
}
.post pre code {
@apply bg-transparent border-none p-0 text-inherit;
}
/* Tables */
.post table {
@apply w-full border-collapse mb-4 text-sm sm:text-base;
}
.post thead {
@apply bg-neutral-100 dark:bg-neutral-800;
}
.post th {
@apply border border-neutral-300 dark:border-neutral-600 px-4 py-2 text-left font-semibold text-neutral-900 dark:text-neutral-100;
}
.post td {
@apply border border-neutral-300 dark:border-neutral-600 px-4 py-2 text-neutral-700 dark:text-neutral-300;
}
.post tbody tr:nth-child(even) {
@apply bg-neutral-50 dark:bg-neutral-800/50;
}
.post tbody tr:hover {
@apply bg-neutral-100 dark:bg-neutral-700/50 transition-colors duration-150;
}
/* Horizontal Rule */
.post hr {
@apply border-0 h-px bg-neutral-300 dark:bg-neutral-600 my-8;
}
/* Images */
.post img {
@apply max-w-full h-auto rounded-lg shadow-md mb-4 border border-neutral-200 dark:border-neutral-700;
}
.post figure {
@apply mb-4;
}
.post figcaption {
@apply text-sm text-neutral-500 dark:text-neutral-400 text-center mt-2 italic;
}
/* Keyboard Keys */
.post kbd {
@apply bg-neutral-200 dark:bg-neutral-700 text-neutral-800 dark:text-neutral-200 px-2 py-1 rounded text-sm font-mono border border-neutral-300 dark:border-neutral-600 shadow-sm;
}
/* Abbreviations */
.post abbr {
@apply underline decoration-dotted cursor-help;
}
/* Definition Lists */
.post dl {
@apply mb-4;
}
.post dt {
@apply font-semibold text-neutral-800 dark:text-neutral-200 mb-1;
}
.post dd {
@apply text-neutral-600 dark:text-neutral-300 ml-4 mb-2;
}
/* Details and Summary */
.post details {
@apply border border-neutral-200 dark:border-neutral-700 rounded-lg p-4 mb-4 bg-neutral-50 dark:bg-neutral-800;
}
.post summary {
@apply font-semibold text-neutral-800 dark:text-neutral-200 cursor-pointer hover:text-neutral-600 dark:hover:text-neutral-400 transition-colors duration-200;
}
.post details[open] summary {
@apply mb-3 pb-2 border-b border-neutral-200 dark:border-neutral-700;
}
/* Address */
.post address {
@apply not-italic text-neutral-600 dark:text-neutral-300 mb-4;
}
/* Subscript and Superscript */
.post sub, .prose sup {
@apply text-xs;
}
/* Selection */
.post ::selection {
@apply bg-blue-200 dark:bg-blue-800 text-neutral-900 dark:text-neutral-100;
}
/* Focus styles for accessibility */
.post a:focus,
.post button:focus,
.post summary:focus {
@apply outline-2 outline-blue-500 dark:outline-blue-400 outline-offset-2;
}
/* Responsive adjustments */
@media (max-width: 640px) {
.post {
@apply text-base;
}
.post p {
@apply text-base;
}
.post ul, .prose ol {
@apply text-base;
}
}
/* Print styles */
@media print {
.post {
@apply text-black;
}
.post h1, .prose h2, .prose h3, .prose h4, .prose h5, .prose h6 {
@apply text-black border-black;
}
.post a {
@apply text-black underline;
}
.post code, .prose pre {
@apply bg-gray-100 text-black border-gray-300;
}
}