more updates
parent
b808dc93e7
commit
cf38b8710a
@ -1 +1,242 @@
|
||||
# Poisson Blog Template
|
||||
|
||||
An Astro-based academic blog template designed for the PHC (Dipartimento di Matematica) at University of Pisa. This template provides a clean, mathematical content-friendly platform for sharing academic posts, notes, and research materials.
|
||||
|
||||
## Features
|
||||
|
||||
- ✨ Built with [Astro](https://astro.build/) for fast, static site generation
|
||||
|
||||
- 📝 Support for Markdown and MDX content with mathematical expressions
|
||||
|
||||
- 🎨 Multiple customizable themes
|
||||
|
||||
- 🏷️ Tag-based post organization
|
||||
|
||||
- 📚 Dedicated sections for posts and notes
|
||||
|
||||
- 🔍 SEO-friendly structure
|
||||
|
||||
- 📱 Responsive design
|
||||
|
||||
## Available Themes
|
||||
|
||||
The template includes several pre-built themes located in `src/themes/`:
|
||||
|
||||
- **base.css** - Clean, minimal base theme
|
||||
|
||||
- **colorful.css** - Vibrant, colorful theme
|
||||
|
||||
- **modern.css** - Contemporary design with modern styling
|
||||
|
||||
- **mono.css** - Monochromatic, minimalist theme
|
||||
|
||||
- **sober.css** - Professional, academic-focused theme
|
||||
|
||||
To change themes, modify the CSS import in `src/layouts/Base.astro`.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
/
|
||||
├── public/
|
||||
│ ├── favicon.svg
|
||||
│ └── materiale/ # Static files and documents
|
||||
├── src/
|
||||
│ ├── components/ # Reusable Astro components
|
||||
│ ├── layouts/ # Page layouts
|
||||
│ ├── pages/
|
||||
│ │ ├── index.astro # Homepage
|
||||
│ │ ├── appunti/ # Notes section
|
||||
│ │ └── posts/ # Blog posts
|
||||
│ ├── themes/ # CSS theme files
|
||||
│ └── config.ts # Site configuration
|
||||
├── astro.config.mjs # Astro configuration
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. **Clone or download this template**
|
||||
|
||||
```bash
|
||||
git clone https://git.phc.dm.unipi.it/phc/poisson-template-astro.git
|
||||
cd poisson-template-astro
|
||||
```
|
||||
|
||||
2. **Install dependencies:**
|
||||
|
||||
```bash
|
||||
npm install
|
||||
# or
|
||||
bun install
|
||||
```
|
||||
|
||||
3. **To edit the site locally:**
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
4. **Edit the configuration:**
|
||||
|
||||
- Update `src/config.ts` with your information
|
||||
- Modify the site title and other settings
|
||||
|
||||
5. **Add your content:**
|
||||
|
||||
- Create posts in `src/pages/posts/`
|
||||
- Add notes in `src/pages/appunti/`
|
||||
- Include any static files in `public/materiale/`
|
||||
|
||||
## Content Creation
|
||||
|
||||
### Blog Posts
|
||||
|
||||
Create new markdown posts in `src/pages/posts/` with the following frontmatter:
|
||||
|
||||
```markdown
|
||||
---
|
||||
title: 'Your Post Title'
|
||||
description: 'Brief description of the post'
|
||||
tags: ['tag1', 'tag2']
|
||||
publishDate: '2025-06-08'
|
||||
draft: false
|
||||
---
|
||||
|
||||
Your content goes here...
|
||||
```
|
||||
|
||||
### Mathematical Content
|
||||
|
||||
The template supports mathematical expressions using [KaTeX](https://katex.org/):
|
||||
|
||||
- Inline math: `$E = mc^2$`
|
||||
|
||||
- Display math: `$$\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}$$`
|
||||
|
||||
## Deployment
|
||||
|
||||
### Deploy to Poisson Server
|
||||
|
||||
The template is pre-configured for deployment to the PHC Poisson server:
|
||||
|
||||
1. **Build for Poisson:**
|
||||
|
||||
```bash
|
||||
npm run build:poisson
|
||||
```
|
||||
|
||||
2. **Update the Poisson configuration:**
|
||||
|
||||
- Edit the `build:poisson` script in `package.json`
|
||||
- Replace `ncognome` with your actual username
|
||||
- Update the site URL accordingly
|
||||
|
||||
3. **Upload the built files:**
|
||||
|
||||
- The build creates a `dist/` folder
|
||||
- Upload the contents to your Poisson web directory, for example using `scp`:
|
||||
|
||||
```bash
|
||||
scp -r dist/* ncognome@poisson.phc.dm.unipi.it:/home/ncognome/public_html/
|
||||
```
|
||||
|
||||
or with `rsync`:
|
||||
|
||||
```bash
|
||||
rsync -avz dist/ ncognome@poisson.phc.dm.unipi.it:/home/ncognome/public_html/
|
||||
```
|
||||
|
||||
4. **Access your site:**
|
||||
|
||||
- Visit `https://poisson.phc.dm.unipi.it/~ncognome/` to see your deployed site
|
||||
|
||||
### Deploy to GitHub Pages
|
||||
|
||||
For GitHub Pages deployment, follow these steps:
|
||||
|
||||
1. **Configure Astro for GitHub Pages:**
|
||||
|
||||
Update `astro.config.mjs` to include your GitHub Pages settings:
|
||||
|
||||
```javascript
|
||||
export default defineConfig({
|
||||
site: 'https://yourusername.github.io',
|
||||
base: '/your-repo-name', // Only if not deploying to yourusername.github.io
|
||||
// ... other config
|
||||
})
|
||||
```
|
||||
|
||||
2. **Create GitHub Action workflow:**
|
||||
|
||||
Create `.github/workflows/deploy.yml`:
|
||||
|
||||
```yaml
|
||||
name: Deploy to GitHub Pages
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout your repository using git
|
||||
uses: actions/checkout@v4
|
||||
- name: Install, build, and upload your site
|
||||
uses: withastro/action@v3
|
||||
|
||||
deploy:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
```
|
||||
|
||||
3. **Enable GitHub Pages:**
|
||||
|
||||
- Go to your repository's **Settings** → **Pages**
|
||||
- Select **GitHub Actions** as the source
|
||||
- Commit and push your changes
|
||||
|
||||
4. **Configure for custom domain (optional):**
|
||||
- Add a `CNAME` file in the `public/` directory with your domain
|
||||
- Update the `site` config to use your custom domain
|
||||
- Remove the `base` configuration
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### Site Configuration
|
||||
|
||||
Edit `src/config.ts` to customize:
|
||||
|
||||
- Site title
|
||||
- Post frontmatter types
|
||||
- Other site-wide settings
|
||||
|
||||
### Build Scripts
|
||||
|
||||
- `npm run dev` - Start development server
|
||||
- `npm run build` - Build for production
|
||||
- `npm run build:poisson` - Build for Poisson server deployment
|
||||
- `npm run preview` - Preview the built site
|
||||
|
||||
## Contributing
|
||||
|
||||
This template is designed for academic use at the University of Pisa. Feel free to customize and extend it for your needs.
|
||||
|
||||
## License
|
||||
|
||||
This template is provided as-is for educational and academic purposes.
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
---
|
||||
import Base from '@/layouts/Base.astro'
|
||||
import config from '@/config'
|
||||
---
|
||||
|
||||
<Base>
|
||||
<main>
|
||||
<h2>Appunti</h2>
|
||||
|
||||
<div>
|
||||
<h3>Corso 1</h3>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod beatae, alias vitae assumenda quia
|
||||
corporis quos natus laboriosam illo consectetur. Praesentium explicabo vitae assumenda saepe impedit
|
||||
commodi iusto. Enim harum perspiciatis quae ea nihil iusto saepe cum! Doloribus, ullam dolorum.
|
||||
</p>
|
||||
<p class="text-center">
|
||||
<a href="#">Scarica</a>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Corso 2</h3>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod beatae, alias vitae assumenda quia
|
||||
corporis quos natus laboriosam illo consectetur. Praesentium explicabo vitae assumenda saepe impedit
|
||||
commodi iusto. Enim harum perspiciatis quae ea nihil iusto saepe cum! Doloribus, ullam dolorum.
|
||||
</p>
|
||||
<p class="text-center">
|
||||
<a href="#">Scarica</a>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Corso 3</h3>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod beatae, alias vitae assumenda quia
|
||||
corporis quos natus laboriosam illo consectetur. Praesentium explicabo vitae assumenda saepe impedit
|
||||
commodi iusto. Enim harum perspiciatis quae ea nihil iusto saepe cum! Doloribus, ullam dolorum.
|
||||
</p>
|
||||
<p class="text-center">
|
||||
<a href="#">Scarica</a>
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
</Base>
|
||||
@ -0,0 +1,34 @@
|
||||
---
|
||||
layout: '@/layouts/Post.astro'
|
||||
title: Appunti
|
||||
---
|
||||
|
||||
## Corso 1
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod beatae, alias vitae assumenda quia
|
||||
corporis quos natus laboriosam illo consectetur. Praesentium explicabo vitae assumenda saepe impedit
|
||||
commodi iusto. Enim harum perspiciatis quae ea nihil iusto saepe cum! Doloribus, ullam dolorum.
|
||||
|
||||
<p class="text-center">
|
||||
<a class="button" href="/materiale/dispensa-1.pdf">Scarica</a>
|
||||
</p>
|
||||
|
||||
## Corso 2
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod beatae, alias vitae assumenda quia
|
||||
corporis quos natus laboriosam illo consectetur. Praesentium explicabo vitae assumenda saepe impedit
|
||||
commodi iusto. Enim harum perspiciatis quae ea nihil iusto saepe cum! Doloribus, ullam dolorum.
|
||||
|
||||
<p class="text-center">
|
||||
<a class="button" href="/materiale/dispensa-1.pdf">Scarica</a>
|
||||
</p>
|
||||
|
||||
## Corso 3
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quod beatae, alias vitae assumenda quia
|
||||
corporis quos natus laboriosam illo consectetur. Praesentium explicabo vitae assumenda saepe impedit
|
||||
commodi iusto. Enim harum perspiciatis quae ea nihil iusto saepe cum! Doloribus, ullam dolorum.
|
||||
|
||||
<p class="text-center">
|
||||
<a class="button" href="/materiale/dispensa-1.pdf">Scarica</a>
|
||||
</p>
|
||||
@ -0,0 +1,123 @@
|
||||
---
|
||||
layout: '@/layouts/Post.astro'
|
||||
title: Getting Started with Astro
|
||||
publishDate: 2025-06-07
|
||||
description: |
|
||||
Discover the power of Astro, a modern web framework that delivers
|
||||
lightning-fast websites with zero JavaScript by default.
|
||||
tags: ['astro', 'web-development', 'javascript', 'performance', 'static-site']
|
||||
---
|
||||
|
||||
Astro is revolutionizing the way we build websites by prioritizing performance and developer experience. Unlike traditional frameworks that ship JavaScript by default, Astro follows a **zero-JavaScript** approach, only adding interactivity when you explicitly need it.
|
||||
|
||||
## What Makes Astro Special?
|
||||
|
||||
### 🚀 Lightning Fast Performance
|
||||
|
||||
Astro generates static HTML at build time, resulting in incredibly fast loading times. Your users get the content they need without waiting for JavaScript to load and execute.
|
||||
|
||||
### 🏝️ Islands Architecture
|
||||
|
||||
With Astro's unique **Islands Architecture**, you can use components from different frameworks (React, Vue, Svelte) on the same page, but they remain isolated and only hydrate when needed.
|
||||
|
||||
```astro
|
||||
---
|
||||
// You can mix and match frameworks!
|
||||
import ReactCounter from './ReactCounter.jsx'
|
||||
import VueCalendar from './VueCalendar.vue'
|
||||
import SvelteChart from './SvelteChart.svelte'
|
||||
---
|
||||
|
||||
<main>
|
||||
<h1>My Astro Page</h1>
|
||||
<ReactCounter client:load />
|
||||
<VueCalendar client:visible />
|
||||
<SvelteChart client:idle />
|
||||
</main>
|
||||
```
|
||||
|
||||
### 📝 Content-First Approach
|
||||
|
||||
Astro excels at content-heavy sites like blogs, documentation, and marketing pages. It supports:
|
||||
|
||||
- **Markdown** out of the box
|
||||
- **MDX** for interactive content
|
||||
- **Content Collections** for type-safe content management
|
||||
|
||||
## Key Features
|
||||
|
||||
> Astro combines the best of static site generation with the flexibility of modern component frameworks.
|
||||
|
||||
1. **Zero JavaScript by Default** - Only add JS when you need it
|
||||
2. **Framework Agnostic** - Use React, Vue, Svelte, or plain HTML
|
||||
3. **Built-in Optimizations** - Image optimization, CSS bundling, and more
|
||||
4. **TypeScript Support** - First-class TypeScript support
|
||||
5. **Excellent DX** - Fast dev server, hot reloading, and great tooling
|
||||
|
||||
## Mathematical Expressions
|
||||
|
||||
Astro works great with mathematical content too! Here's the famous Euler's identity:
|
||||
|
||||
$$e^{i\pi} + 1 = 0$$
|
||||
|
||||
This equation beautifully connects five fundamental mathematical constants:
|
||||
|
||||
- $e$ (Euler's number)
|
||||
- $i$ (imaginary unit)
|
||||
- $\pi$ (pi)
|
||||
- $1$ (multiplicative identity)
|
||||
- $0$ (additive identity)
|
||||
|
||||
## Code Example
|
||||
|
||||
Here's how you can create a simple Astro component:
|
||||
|
||||
```astro
|
||||
---
|
||||
// Component Script (runs at build time)
|
||||
const greeting = 'Hello, Astro!'
|
||||
const currentYear = new Date().getFullYear()
|
||||
---
|
||||
|
||||
<!-- Component Template -->
|
||||
<div class="greeting-card">
|
||||
<h2>{greeting}</h2>
|
||||
<p>Welcome to the future of web development!</p>
|
||||
<footer>
|
||||
<small>© {currentYear} - Built with Astro</small>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.greeting-card {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 2rem;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
font-size: 2rem;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
Ready to try Astro? Here's how to create your first project:
|
||||
|
||||
<p class="text-center">
|
||||
<a class="button" href="https://docs.astro.build/en/getting-started/">Start Building</a>
|
||||
</p>
|
||||
|
||||
## Conclusion
|
||||
|
||||
Astro represents a paradigm shift in web development, prioritizing performance without sacrificing developer experience. Whether you're building a blog, documentation site, or marketing page, Astro provides the tools you need to create fast, modern websites.
|
||||
|
||||
The combination of static generation, islands architecture, and framework flexibility makes Astro an excellent choice for your next project. Give it a try and experience the difference!
|
||||
|
||||
---
|
||||
|
||||
_Happy coding! 🚀_
|
||||
@ -0,0 +1,96 @@
|
||||
---
|
||||
import Base from '@/layouts/Base.astro'
|
||||
import PostCard from '@/components/PostCard.astro'
|
||||
import type { MarkdownInstance } from 'astro'
|
||||
import type { PostFrontmatter } from '@/config'
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = import.meta.glob<MarkdownInstance<PostFrontmatter>>('../*.md', { eager: true })
|
||||
const postsArray = Object.values(posts).filter(post => !post.frontmatter.draft)
|
||||
|
||||
// Collect all unique tags
|
||||
const tags = new Set<string>()
|
||||
postsArray.forEach(post => {
|
||||
post.frontmatter.tags?.forEach(tag => tags.add(tag))
|
||||
})
|
||||
|
||||
// Generate paths for each tag with precomputed related tags
|
||||
return Array.from(tags).map(tag => {
|
||||
// Filter posts by the current tag
|
||||
const taggedPosts = postsArray
|
||||
.filter(post => post.frontmatter.tags?.includes(tag))
|
||||
.toSorted((a, b) => {
|
||||
return new Date(b.frontmatter.publishDate).getTime() - new Date(a.frontmatter.publishDate).getTime()
|
||||
})
|
||||
|
||||
// Get all other tags from these posts for related tags
|
||||
const relatedTags = new Set<string>()
|
||||
taggedPosts.forEach(post => {
|
||||
post.frontmatter.tags?.forEach(t => {
|
||||
if (t !== tag) {
|
||||
relatedTags.add(t)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return {
|
||||
params: { tag },
|
||||
props: {
|
||||
tag,
|
||||
relatedTags: Array.from(relatedTags).sort(),
|
||||
taggedPosts,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const { tag, taggedPosts, relatedTags } = Astro.props
|
||||
---
|
||||
|
||||
<Base>
|
||||
<main>
|
||||
<h2>Post con tag <a href={`/posts/tags/${tag}`}>#{tag}</a></h2>
|
||||
<p>
|
||||
{taggedPosts.length} post{taggedPosts.length !== 1 ? 's' : ''} trovato{taggedPosts.length !== 1 ? 'i' : ''}.
|
||||
<a href="/posts/tags" class="back-link">← Torna a tutti i tag</a>
|
||||
</p>
|
||||
{
|
||||
taggedPosts.length > 0 ? (
|
||||
<div class="card-list">
|
||||
{taggedPosts.map(post => (
|
||||
<PostCard
|
||||
post={{
|
||||
...post.frontmatter,
|
||||
url: post.url ?? '#',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<p>Nessun post trovato per questo tag.</p>
|
||||
<p>
|
||||
<a href="/posts" class="button">
|
||||
Esplora tutti i post
|
||||
</a>
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
relatedTags.length > 0 && (
|
||||
<>
|
||||
<h2>Tag correlati</h2>
|
||||
<div class="tags">
|
||||
{relatedTags.map(relatedTag => (
|
||||
<a href={`/posts/tags/${relatedTag}`} class="tag">
|
||||
#{relatedTag}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</main>
|
||||
</Base>
|
||||
@ -0,0 +1,50 @@
|
||||
---
|
||||
import Base from '@/layouts/Base.astro'
|
||||
import type { MarkdownInstance } from 'astro'
|
||||
import type { PostFrontmatter } from '@/config'
|
||||
|
||||
const posts = import.meta.glob<MarkdownInstance<PostFrontmatter>>('../*.md', { eager: true })
|
||||
|
||||
// Collect all tags and count their usage
|
||||
const tagCounts = new Map<string, number>()
|
||||
const tagPosts = new Map<string, Array<MarkdownInstance<PostFrontmatter>>>()
|
||||
|
||||
Object.values(posts)
|
||||
.filter(post => !post.frontmatter.draft)
|
||||
.forEach(post => {
|
||||
post.frontmatter.tags?.forEach(tag => {
|
||||
tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1)
|
||||
if (!tagPosts.has(tag)) {
|
||||
tagPosts.set(tag, [])
|
||||
}
|
||||
tagPosts.get(tag)!.push(post)
|
||||
})
|
||||
})
|
||||
|
||||
// Sort tags by usage count (descending) then alphabetically
|
||||
const sortedTags = Array.from(tagCounts.entries()).sort((a, b) => {
|
||||
if (a[1] !== b[1]) {
|
||||
return b[1] - a[1] // Sort by count descending
|
||||
}
|
||||
return a[0].localeCompare(b[0]) // Then alphabetically
|
||||
})
|
||||
---
|
||||
|
||||
<Base>
|
||||
<main>
|
||||
<h1>Archivio Tag</h1>
|
||||
<p>Esplora i post per argomento. Clicca su un tag per vedere tutti i post correlati.</p>
|
||||
|
||||
<div class="tags">
|
||||
{
|
||||
sortedTags.map(([tag, count]) => (
|
||||
<a href={`/posts/tags/${tag}`} class="tag">
|
||||
#{tag} ({count})
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
{sortedTags.length === 0 && <p class="no-tags">Nessun tag trovato.</p>}
|
||||
</main>
|
||||
</Base>
|
||||
@ -1,5 +0,0 @@
|
||||
@layer base, typography, components, utilities;
|
||||
|
||||
/* @import url(@/themes/base.css); */
|
||||
/* @import url(@/themes/colorful.css); */
|
||||
@import url(@/themes/mono.css);
|
||||
@ -0,0 +1,381 @@
|
||||
:root {
|
||||
--heading-base-size: 18px;
|
||||
--heading-scale-factor: 1.33;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
:root {
|
||||
--heading-base-size: 16px;
|
||||
--heading-scale-factor: 1.25;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
background: var(--bg, #fff);
|
||||
}
|
||||
}
|
||||
|
||||
@layer component {
|
||||
blockquote {
|
||||
padding: 0.5rem 1rem;
|
||||
border-left: var(--blockquote-border, 4px solid #ccc);
|
||||
background: var(--blockquote-bg, #f9f9f9);
|
||||
font-style: italic;
|
||||
border-top-right-radius: 0.5rem;
|
||||
border-bottom-right-radius: 0.5rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--link-color, #007bff);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: 2px solid underline;
|
||||
}
|
||||
}
|
||||
|
||||
pre:not(:has(.math-inline, .math-display, .katex)),
|
||||
code {
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
background: var(--code-bg, #f5f5f5) !important;
|
||||
border-radius: 0.5rem;
|
||||
font-size: 95%;
|
||||
}
|
||||
|
||||
pre:not(:has(.math-inline, .math-display, .katex)) {
|
||||
padding: 0.5rem;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
max-width: 60rem;
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto auto;
|
||||
align-items: center;
|
||||
|
||||
border: var(--header-border, 1px solid #ccc);
|
||||
border-radius: var(--header-border-radius, 1rem);
|
||||
padding: var(--header-padding, 0.5rem);
|
||||
|
||||
> h1 {
|
||||
justify-self: start;
|
||||
|
||||
display: grid;
|
||||
place-content: center;
|
||||
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
|
||||
padding: 0 0.5rem;
|
||||
|
||||
> a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide hamburger menu elements on desktop */
|
||||
.hamburger-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hamburger-icon {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
gap: 0.25rem;
|
||||
|
||||
span {
|
||||
width: 1.5rem;
|
||||
height: 0.125rem;
|
||||
background-color: var(--text-fg, #333);
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 0.125rem;
|
||||
}
|
||||
}
|
||||
|
||||
> nav {
|
||||
justify-self: end;
|
||||
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
gap: 1rem;
|
||||
|
||||
> .nav-item {
|
||||
display: grid;
|
||||
|
||||
> a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
font-weight: 500;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.5rem 1rem;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
/* text-decoration: 2px solid underline; */
|
||||
background-color: var(--nav-hover-bg-color, #f0f0f0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive header styles */
|
||||
@media (max-width: 1024px) and (min-width: 769px) {
|
||||
max-width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: none;
|
||||
max-width: none;
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
border-bottom: var(--header-border, 1px solid #ccc);
|
||||
background-color: var(--background-color, #fff);
|
||||
z-index: 1000;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
padding: 1rem;
|
||||
|
||||
> h1 {
|
||||
font-size: 1.25rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Show hamburger icon on mobile */
|
||||
.hamburger-icon {
|
||||
display: flex;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
/* Animate hamburger icon when menu is open */
|
||||
.hamburger-toggle:checked + .hamburger-icon span:nth-child(1) {
|
||||
transform: rotate(45deg) translate(0.15rem, 0.375rem);
|
||||
}
|
||||
|
||||
.hamburger-toggle:checked + .hamburger-icon span:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.hamburger-toggle:checked + .hamburger-icon span:nth-child(3) {
|
||||
transform: rotate(-45deg) translate(0.15rem, -0.375rem);
|
||||
}
|
||||
|
||||
/* Mobile navigation */
|
||||
> nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: -100%;
|
||||
width: 80%;
|
||||
max-width: 300px;
|
||||
height: 100vh;
|
||||
background-color: var(--background-color, #fff);
|
||||
border-left: var(--header-border, 1px solid #ccc);
|
||||
transition: right 0.3s ease;
|
||||
z-index: 999;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
gap: 0;
|
||||
padding-top: 54px;
|
||||
|
||||
> .nav-item {
|
||||
display: block;
|
||||
border-bottom: var(--header-border, 1px solid #ccc);
|
||||
|
||||
&:first-child {
|
||||
border-top: var(--header-border, 1px solid #ccc);
|
||||
}
|
||||
|
||||
> a {
|
||||
display: block;
|
||||
padding: 1rem 1.5rem;
|
||||
border-radius: 0;
|
||||
font-size: 1.1rem;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--nav-hover-bg-color, #f0f0f0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Show navigation when checkbox is checked */
|
||||
.hamburger-toggle:checked ~ nav {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
/* Overlay when menu is open */
|
||||
.hamburger-toggle:checked::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 998;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
padding: 0.75rem;
|
||||
|
||||
> h1 {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
> nav {
|
||||
width: 90%;
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
gap: 0.5rem;
|
||||
|
||||
padding: 1rem;
|
||||
border: var(--header-border, 1px solid #ccc);
|
||||
border-radius: 0.5rem;
|
||||
background: var(--card-bg, #fff);
|
||||
|
||||
.title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-fg-dimmed, #666);
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1rem;
|
||||
color: var(--text-fg, #333);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--card-hover-bg, #f0f0f0);
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.card-list {
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
gap: 1rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.jumbotron {
|
||||
height: 50vh;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
max-width: 40ch;
|
||||
}
|
||||
|
||||
/* Responsive jumbotron */
|
||||
@media (max-width: 768px) {
|
||||
height: 40vh;
|
||||
padding: 0 1rem;
|
||||
|
||||
h1 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 3));
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
height: 35vh;
|
||||
|
||||
h1 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 1rem;
|
||||
background: var(--link-color, #007bff);
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
text-decoration: none;
|
||||
font-family: inherit;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 64ms ease-out;
|
||||
box-shadow: 0 2px 4px rgba(0, 123, 255, 0.2);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: #0056b3;
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 8px rgba(0, 123, 255, 0.3);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 4px rgba(0, 123, 255, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-block;
|
||||
padding: 0 0.35rem;
|
||||
background: #ddd;
|
||||
color: #333;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: none;
|
||||
background: #bbb;
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,511 @@
|
||||
/* Sober Theme - Clean and polished old-style with left sidebar */
|
||||
|
||||
:root {
|
||||
--heading-base-size: 18px;
|
||||
--heading-scale-factor: 1.33;
|
||||
|
||||
/* Sober color palette - muted, sophisticated tones */
|
||||
--sidebar-bg: #2c2c2c;
|
||||
--sidebar-text: #e8e8e8;
|
||||
--sidebar-accent: #b8860b;
|
||||
--content-bg: #fafafa;
|
||||
--content-text: #333;
|
||||
--border-color: #d0d0d0;
|
||||
--card-bg: #ffffff;
|
||||
--hover-bg: #f5f5f5;
|
||||
--muted-text: #666;
|
||||
--link-color: #8b4513;
|
||||
--code-bg: #f8f8f8;
|
||||
--blockquote-bg: #f9f7f4;
|
||||
--blockquote-border: #d4a574;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
:root {
|
||||
--heading-base-size: 16px;
|
||||
--heading-scale-factor: 1.25;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
background: var(--content-bg);
|
||||
color: var(--content-text);
|
||||
display: grid;
|
||||
grid-template-columns: 250px 1fr;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Responsive grid adjustments */
|
||||
@media (max-width: 1024px) {
|
||||
body {
|
||||
grid-template-columns: 220px 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@layer typography {
|
||||
main,
|
||||
article {
|
||||
grid-column: 2;
|
||||
padding: 2rem 3rem;
|
||||
max-width: 52rem;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
|
||||
> * {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
padding: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@layer component {
|
||||
/* Left Sidebar Header */
|
||||
header {
|
||||
grid-column: 1;
|
||||
background: var(--sidebar-bg);
|
||||
color: var(--sidebar-text);
|
||||
padding: 2rem 1.5rem;
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2rem;
|
||||
|
||||
> .spacer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> h1 {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 2px solid var(--sidebar-accent);
|
||||
text-align: center;
|
||||
letter-spacing: 0.05em;
|
||||
|
||||
> a {
|
||||
color: var(--sidebar-text);
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
color: var(--sidebar-accent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
|
||||
> .nav-item {
|
||||
> a {
|
||||
display: block;
|
||||
color: var(--sidebar-text);
|
||||
text-decoration: none;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid transparent;
|
||||
margin: 0.125rem 0;
|
||||
|
||||
font-weight: 600;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-color: var(--sidebar-accent);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||
color: var(--sidebar-accent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide hamburger elements on desktop */
|
||||
.hamburger-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hamburger-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Mobile responsive sidebar */
|
||||
@media (max-width: 1024px) {
|
||||
padding: 1.5rem 1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
height: 60px;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 0 1rem;
|
||||
gap: 1rem;
|
||||
z-index: 1000;
|
||||
|
||||
> h1 {
|
||||
font-size: 1.25rem;
|
||||
padding: 0;
|
||||
border: none;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Hide hamburger elements on larger screens */
|
||||
.hamburger-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hamburger-icon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
gap: 0.25rem;
|
||||
margin-left: auto;
|
||||
|
||||
span {
|
||||
width: 1.5rem;
|
||||
height: 0.125rem;
|
||||
background-color: var(--sidebar-text);
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 0.125rem;
|
||||
}
|
||||
}
|
||||
|
||||
> nav {
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: -100%;
|
||||
width: 80%;
|
||||
max-width: 300px;
|
||||
height: calc(100vh - 60px);
|
||||
background: var(--sidebar-bg);
|
||||
transition: left 0.3s ease;
|
||||
padding: 1rem;
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Show navigation when checkbox is checked */
|
||||
.hamburger-toggle:checked ~ nav {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
/* Animate hamburger icon */
|
||||
.hamburger-toggle:checked + .hamburger-icon span:nth-child(1) {
|
||||
transform: rotate(45deg) translate(0.15rem, 0.375rem);
|
||||
}
|
||||
|
||||
.hamburger-toggle:checked + .hamburger-icon span:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.hamburger-toggle:checked + .hamburger-icon span:nth-child(3) {
|
||||
transform: rotate(-45deg) translate(0.15rem, -0.375rem);
|
||||
}
|
||||
|
||||
/* Overlay */
|
||||
.hamburger-toggle:checked::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(100vh - 60px);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Typography and Content Styling */
|
||||
blockquote {
|
||||
padding: 1rem 1.5rem;
|
||||
border-left: 4px solid var(--blockquote-border);
|
||||
background: var(--blockquote-bg);
|
||||
font-style: italic;
|
||||
border-radius: 0 0.5rem 0.5rem 0;
|
||||
margin: 1.5rem 0;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '"';
|
||||
font-size: 3rem;
|
||||
color: var(--blockquote-border);
|
||||
position: absolute;
|
||||
top: -0.5rem;
|
||||
left: 0.5rem;
|
||||
font-family: Georgia, serif;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--link-color);
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid transparent;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
border-bottom-color: var(--link-color);
|
||||
color: #654321;
|
||||
}
|
||||
}
|
||||
|
||||
pre:not(:has(.math-inline, .math-display, .katex)),
|
||||
code {
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||
background: var(--code-bg) !important;
|
||||
border-radius: 0.25rem;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
pre:not(:has(.math-inline, .math-display, .katex)) {
|
||||
padding: 1rem;
|
||||
line-height: 1.4;
|
||||
overflow-x: auto;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 0.125rem 0.25rem;
|
||||
}
|
||||
|
||||
/* Card Components */
|
||||
.card {
|
||||
display: grid;
|
||||
grid-auto-flow: row;
|
||||
gap: 1rem;
|
||||
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
.title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: var(--content-text);
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 0.875rem;
|
||||
color: var(--muted-text);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: var(--content-text);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
border-color: var(--sidebar-accent);
|
||||
}
|
||||
}
|
||||
|
||||
.card-list {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
/* Jumbotron */
|
||||
.jumbotron {
|
||||
height: 60vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
background: linear-gradient(150deg, #f8f8f8 0%, #f0f0f0 100%);
|
||||
border-bottom: 4px solid var(--sidebar-accent);
|
||||
margin-bottom: 2rem;
|
||||
border-top-left-radius: 1rem;
|
||||
border-top-right-radius: 1rem;
|
||||
|
||||
h1 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 4));
|
||||
font-weight: 300;
|
||||
color: var(--sidebar-bg);
|
||||
margin-bottom: 1rem;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
p {
|
||||
max-width: 45ch;
|
||||
font-size: 1.125rem;
|
||||
color: var(--muted-text);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
height: 40vh;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 1rem;
|
||||
background: linear-gradient(135deg, var(--card-bg) 0%, #f8f8f8 100%);
|
||||
color: var(--sidebar-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 0.5rem;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
transition: all 64ms ease-in;
|
||||
letter-spacing: 0.025em;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: linear-gradient(135deg, #f0f0f0 0%, #e8e8e8 100%);
|
||||
color: var(--sidebar-bg);
|
||||
border-color: var(--sidebar-accent);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Tags */
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.tag {
|
||||
display: inline-block;
|
||||
padding: 0rem 0.5rem;
|
||||
background: var(--hover-bg);
|
||||
color: var(--content-text);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 2rem;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: var(--sidebar-accent);
|
||||
color: white;
|
||||
border-color: var(--sidebar-accent);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 1.5rem 0;
|
||||
background: var(--card-bg);
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 0.75rem 1rem;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
th {
|
||||
background: var(--hover-bg);
|
||||
font-weight: 600;
|
||||
color: var(--sidebar-bg);
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background: var(--hover-bg);
|
||||
}
|
||||
|
||||
/* Lists */
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
/* Headings */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: var(--sidebar-bg);
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
margin: 2rem 0 1rem 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 4));
|
||||
border-bottom: 2px solid var(--sidebar-accent);
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 3));
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: calc(var(--heading-base-size) * pow(var(--heading-scale-factor), 2));
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: calc(var(--heading-base-size) * var(--heading-scale-factor));
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: var(--heading-base-size);
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: calc(var(--heading-base-size) * 0.9);
|
||||
color: var(--muted-text);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue