mirror of
https://github.com/thiloho/thiloho.github.io.git
synced 2025-12-23 14:33:36 +01:00
Add cyan accent color to enhance website aesthetics
This update introduces a vibrant cyan accent color alongside the existing blue, creating a more visually engaging design while maintaining the clean, minimalist aesthetic. Changes: - Define custom cyan and blue accent colors in global.css using @theme - Add gradient effect (blue to cyan) on h1 and h2 headings - Add cyan accent border on code blocks for visual distinction - Update Button component with cyan border on hover/active states - Add gradient indicator for active navigation items - Add colorful hover states to theme toggle icons - Include smooth color transitions for improved UX Both light and dark modes are fully supported with appropriate color variants.
This commit is contained in:
37
CLAUDE.md
37
CLAUDE.md
@@ -71,11 +71,13 @@ thiloho.github.io/
|
|||||||
## Tech Stack Details
|
## Tech Stack Details
|
||||||
|
|
||||||
### Core Framework
|
### Core Framework
|
||||||
|
|
||||||
- **Astro 5.14.6**: Static site generator with component islands architecture
|
- **Astro 5.14.6**: Static site generator with component islands architecture
|
||||||
- **TypeScript**: Strict mode enabled (`extends: "astro/tsconfigs/strict"`)
|
- **TypeScript**: Strict mode enabled (`extends: "astro/tsconfigs/strict"`)
|
||||||
- **Node.js**: ES Modules (`"type": "module"`)
|
- **Node.js**: ES Modules (`"type": "module"`)
|
||||||
|
|
||||||
### Styling
|
### Styling
|
||||||
|
|
||||||
- **Tailwind CSS 4.1.14**: Utility-first CSS framework
|
- **Tailwind CSS 4.1.14**: Utility-first CSS framework
|
||||||
- **@tailwindcss/typography**: Typography plugin for prose content
|
- **@tailwindcss/typography**: Typography plugin for prose content
|
||||||
- **Custom Fonts**:
|
- **Custom Fonts**:
|
||||||
@@ -86,6 +88,7 @@ thiloho.github.io/
|
|||||||
- **Tiempos Headline**: Serif variant for headlines (weights: 300-900)
|
- **Tiempos Headline**: Serif variant for headlines (weights: 300-900)
|
||||||
|
|
||||||
### Markdown Processing
|
### Markdown Processing
|
||||||
|
|
||||||
- **markdown-it**: Markdown parser
|
- **markdown-it**: Markdown parser
|
||||||
- **rehype-slug**: Automatically add IDs to headings
|
- **rehype-slug**: Automatically add IDs to headings
|
||||||
- **rehype-autolink-headings**: Make headings linkable (wrap behavior)
|
- **rehype-autolink-headings**: Make headings linkable (wrap behavior)
|
||||||
@@ -93,16 +96,19 @@ thiloho.github.io/
|
|||||||
- **Syntax highlighting**: GitHub Dark theme via Shiki
|
- **Syntax highlighting**: GitHub Dark theme via Shiki
|
||||||
|
|
||||||
### Content Management
|
### Content Management
|
||||||
|
|
||||||
- **Content Collections**: Defined in `src/content.config.ts`
|
- **Content Collections**: Defined in `src/content.config.ts`
|
||||||
- **blog**: Markdown files with frontmatter (title, description, pubDate, modDate)
|
- **blog**: Markdown files with frontmatter (title, description, pubDate, modDate)
|
||||||
- **tracks**: JSON file with music track data (id, title, youtubeLink, artist, album)
|
- **tracks**: JSON file with music track data (id, title, youtubeLink, artist, album)
|
||||||
|
|
||||||
### Integrations
|
### Integrations
|
||||||
|
|
||||||
- **@astrojs/sitemap**: Automatic sitemap generation
|
- **@astrojs/sitemap**: Automatic sitemap generation
|
||||||
- **@astrojs/rss**: RSS feed support
|
- **@astrojs/rss**: RSS feed support
|
||||||
- **sanitize-html**: HTML sanitization
|
- **sanitize-html**: HTML sanitization
|
||||||
|
|
||||||
### Development Tools
|
### Development Tools
|
||||||
|
|
||||||
- **Prettier**: Code formatting with plugins for Astro and Tailwind
|
- **Prettier**: Code formatting with plugins for Astro and Tailwind
|
||||||
- **Nix**: Development environment and server deployment
|
- **Nix**: Development environment and server deployment
|
||||||
|
|
||||||
@@ -124,11 +130,13 @@ nix run .#deploy-server # Deploy to remote NixOS server
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Starting Development
|
### Starting Development
|
||||||
|
|
||||||
1. Install dependencies: `npm install`
|
1. Install dependencies: `npm install`
|
||||||
2. Start dev server: `npm run dev`
|
2. Start dev server: `npm run dev`
|
||||||
3. Open browser to `http://localhost:4321`
|
3. Open browser to `http://localhost:4321`
|
||||||
|
|
||||||
### Building for Production
|
### Building for Production
|
||||||
|
|
||||||
1. Run build: `npm run build`
|
1. Run build: `npm run build`
|
||||||
2. Output is in `dist/` directory
|
2. Output is in `dist/` directory
|
||||||
3. Preview with: `npm run preview`
|
3. Preview with: `npm run preview`
|
||||||
@@ -140,6 +148,7 @@ nix run .#deploy-server # Deploy to remote NixOS server
|
|||||||
Blog posts are stored in `src/content/blog/` with each post in its own directory containing a `index.md` file.
|
Blog posts are stored in `src/content/blog/` with each post in its own directory containing a `index.md` file.
|
||||||
|
|
||||||
**Required frontmatter structure**:
|
**Required frontmatter structure**:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
---
|
---
|
||||||
title: "Your Post Title"
|
title: "Your Post Title"
|
||||||
@@ -154,6 +163,7 @@ Write your blog post content using Markdown...
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Blog post conventions**:
|
**Blog post conventions**:
|
||||||
|
|
||||||
- Each post lives in its own directory: `src/content/blog/post-slug/index.md`
|
- Each post lives in its own directory: `src/content/blog/post-slug/index.md`
|
||||||
- Use kebab-case for directory names (e.g., `nixos-with-ext4-and-luks`)
|
- Use kebab-case for directory names (e.g., `nixos-with-ext4-and-luks`)
|
||||||
- Include high-quality images in the same directory as the post
|
- Include high-quality images in the same directory as the post
|
||||||
@@ -163,6 +173,7 @@ Write your blog post content using Markdown...
|
|||||||
### Adding Music Tracks
|
### Adding Music Tracks
|
||||||
|
|
||||||
Edit `src/content/tracks.json` following this schema:
|
Edit `src/content/tracks.json` following this schema:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": 1,
|
"id": 1,
|
||||||
@@ -176,23 +187,27 @@ Edit `src/content/tracks.json` following this schema:
|
|||||||
## Code Conventions
|
## Code Conventions
|
||||||
|
|
||||||
### TypeScript
|
### TypeScript
|
||||||
|
|
||||||
- Use strict TypeScript configuration
|
- Use strict TypeScript configuration
|
||||||
- Define types explicitly where needed
|
- Define types explicitly where needed
|
||||||
- Leverage Astro's built-in type system
|
- Leverage Astro's built-in type system
|
||||||
|
|
||||||
### Astro Components
|
### Astro Components
|
||||||
|
|
||||||
- Use `.astro` file extension
|
- Use `.astro` file extension
|
||||||
- Component names should be PascalCase (e.g., `TableOfContents.astro`)
|
- Component names should be PascalCase (e.g., `TableOfContents.astro`)
|
||||||
- Place reusable components in `src/components/`
|
- Place reusable components in `src/components/`
|
||||||
- Use layouts for page templates (`src/layouts/`)
|
- Use layouts for page templates (`src/layouts/`)
|
||||||
|
|
||||||
### Styling
|
### Styling
|
||||||
|
|
||||||
- Use Tailwind utility classes for styling
|
- Use Tailwind utility classes for styling
|
||||||
- Custom styles go in `src/styles/global.css`
|
- Custom styles go in `src/styles/global.css`
|
||||||
- Follow the custom variant pattern: `@custom-variant dark (&:where(.dark, .dark *))`
|
- Follow the custom variant pattern: `@custom-variant dark (&:where(.dark, .dark *))`
|
||||||
- Apply responsive design with Tailwind's breakpoint prefixes
|
- Apply responsive design with Tailwind's breakpoint prefixes
|
||||||
|
|
||||||
### Formatting
|
### Formatting
|
||||||
|
|
||||||
- Always run `npm run format` before committing
|
- Always run `npm run format` before committing
|
||||||
- Prettier automatically formats:
|
- Prettier automatically formats:
|
||||||
- Astro files (via `prettier-plugin-astro`)
|
- Astro files (via `prettier-plugin-astro`)
|
||||||
@@ -200,6 +215,7 @@ Edit `src/content/tracks.json` following this schema:
|
|||||||
- Configuration is in `.prettierrc`
|
- Configuration is in `.prettierrc`
|
||||||
|
|
||||||
### File Naming
|
### File Naming
|
||||||
|
|
||||||
- Components: PascalCase (e.g., `Header.astro`)
|
- Components: PascalCase (e.g., `Header.astro`)
|
||||||
- Pages: kebab-case or descriptive names (e.g., `index.astro`, `legal-disclosure.astro`)
|
- Pages: kebab-case or descriptive names (e.g., `index.astro`, `legal-disclosure.astro`)
|
||||||
- Content directories: kebab-case (e.g., `nixos-with-ext4-and-luks`)
|
- Content directories: kebab-case (e.g., `nixos-with-ext4-and-luks`)
|
||||||
@@ -208,12 +224,14 @@ Edit `src/content/tracks.json` following this schema:
|
|||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
### GitHub Pages
|
### GitHub Pages
|
||||||
|
|
||||||
- **Automatic deployment** on push to `main` branch
|
- **Automatic deployment** on push to `main` branch
|
||||||
- Workflow file: `.github/workflows/deploy.yml`
|
- Workflow file: `.github/workflows/deploy.yml`
|
||||||
- Uses official Astro GitHub Action (`withastro/action@v3`)
|
- Uses official Astro GitHub Action (`withastro/action@v3`)
|
||||||
- Custom domain: thilohohlt.com (configured via `public/CNAME`)
|
- Custom domain: thilohohlt.com (configured via `public/CNAME`)
|
||||||
|
|
||||||
### Deployment Process
|
### Deployment Process
|
||||||
|
|
||||||
1. Push to `main` branch
|
1. Push to `main` branch
|
||||||
2. GitHub Actions builds the site
|
2. GitHub Actions builds the site
|
||||||
3. Astro generates static files
|
3. Astro generates static files
|
||||||
@@ -221,6 +239,7 @@ Edit `src/content/tracks.json` following this schema:
|
|||||||
5. Site available at https://thilohohlt.com
|
5. Site available at https://thilohohlt.com
|
||||||
|
|
||||||
### Build Configuration
|
### Build Configuration
|
||||||
|
|
||||||
- Site URL: `https://thilohohlt.com` (defined in `astro.config.ts`)
|
- Site URL: `https://thilohohlt.com` (defined in `astro.config.ts`)
|
||||||
- Prefetch: All links are prefetched (`prefetchAll: true`)
|
- Prefetch: All links are prefetched (`prefetchAll: true`)
|
||||||
- Output: Static HTML/CSS/JS in `dist/`
|
- Output: Static HTML/CSS/JS in `dist/`
|
||||||
@@ -230,12 +249,14 @@ Edit `src/content/tracks.json` following this schema:
|
|||||||
This repository includes Nix configuration for self-hosted services listed at https://thilohohlt.com/services.
|
This repository includes Nix configuration for self-hosted services listed at https://thilohohlt.com/services.
|
||||||
|
|
||||||
### Nix Files
|
### Nix Files
|
||||||
|
|
||||||
- `flake.nix`: Main Nix flake configuration
|
- `flake.nix`: Main Nix flake configuration
|
||||||
- `flake.lock`: Dependency lock file
|
- `flake.lock`: Dependency lock file
|
||||||
- `server/default.nix`: NixOS system configuration
|
- `server/default.nix`: NixOS system configuration
|
||||||
- `server/hardware-configuration.nix`: Hardware-specific settings
|
- `server/hardware-configuration.nix`: Hardware-specific settings
|
||||||
|
|
||||||
### Nix Workflows
|
### Nix Workflows
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Enter development shell (provides nixd, nixfmt)
|
# Enter development shell (provides nixd, nixfmt)
|
||||||
nix develop
|
nix develop
|
||||||
@@ -252,7 +273,9 @@ nix run .#deploy-server
|
|||||||
```
|
```
|
||||||
|
|
||||||
### IDE Support for Nix
|
### IDE Support for Nix
|
||||||
|
|
||||||
For NixOS option completions, use the `jnoortheen.nix-ide` VSCode extension with these settings:
|
For NixOS option completions, use the `jnoortheen.nix-ide` VSCode extension with these settings:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"nix.enableLanguageServer": true,
|
"nix.enableLanguageServer": true,
|
||||||
@@ -270,21 +293,25 @@ For NixOS option completions, use the `jnoortheen.nix-ide` VSCode extension with
|
|||||||
## Key Features to Preserve
|
## Key Features to Preserve
|
||||||
|
|
||||||
### Custom Rehype Plugins
|
### Custom Rehype Plugins
|
||||||
|
|
||||||
The `rehypeWrapTables` plugin wraps tables in scrollable divs for responsive design:
|
The `rehypeWrapTables` plugin wraps tables in scrollable divs for responsive design:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
const rehypeWrapTables = () => {
|
const rehypeWrapTables = () => {
|
||||||
// Wraps tables in div.overflow-x-auto.max-w-full
|
// Wraps tables in div.overflow-x-auto.max-w-full
|
||||||
// Ensures tables are scrollable on mobile
|
// Ensures tables are scrollable on mobile
|
||||||
}
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### Markdown Configuration
|
### Markdown Configuration
|
||||||
|
|
||||||
- Syntax highlighting: GitHub Dark theme
|
- Syntax highlighting: GitHub Dark theme
|
||||||
- Auto-generated heading IDs (via rehype-slug)
|
- Auto-generated heading IDs (via rehype-slug)
|
||||||
- Clickable headings that wrap content (via rehype-autolink-headings)
|
- Clickable headings that wrap content (via rehype-autolink-headings)
|
||||||
- Tables wrapped for horizontal scrolling
|
- Tables wrapped for horizontal scrolling
|
||||||
|
|
||||||
### Font Loading
|
### Font Loading
|
||||||
|
|
||||||
- All fonts use `font-display: swap` for performance
|
- All fonts use `font-display: swap` for performance
|
||||||
- Fonts are self-hosted in `/public/fonts/`
|
- Fonts are self-hosted in `/public/fonts/`
|
||||||
- Font families defined in `src/styles/global.css`
|
- Font families defined in `src/styles/global.css`
|
||||||
@@ -303,12 +330,14 @@ const rehypeWrapTables = () => {
|
|||||||
### Common Tasks
|
### Common Tasks
|
||||||
|
|
||||||
**Adding a new blog post**:
|
**Adding a new blog post**:
|
||||||
|
|
||||||
1. Create directory in `src/content/blog/` with kebab-case name
|
1. Create directory in `src/content/blog/` with kebab-case name
|
||||||
2. Add `index.md` with proper frontmatter
|
2. Add `index.md` with proper frontmatter
|
||||||
3. Write content using Markdown
|
3. Write content using Markdown
|
||||||
4. Test with `npm run dev`
|
4. Test with `npm run dev`
|
||||||
|
|
||||||
**Modifying a component**:
|
**Modifying a component**:
|
||||||
|
|
||||||
1. Read the component file first
|
1. Read the component file first
|
||||||
2. Understand its usage across the site
|
2. Understand its usage across the site
|
||||||
3. Make targeted changes
|
3. Make targeted changes
|
||||||
@@ -316,12 +345,14 @@ const rehypeWrapTables = () => {
|
|||||||
5. Format with Prettier
|
5. Format with Prettier
|
||||||
|
|
||||||
**Updating styles**:
|
**Updating styles**:
|
||||||
|
|
||||||
1. Check `src/styles/global.css` for existing patterns
|
1. Check `src/styles/global.css` for existing patterns
|
||||||
2. Use Tailwind utilities when possible
|
2. Use Tailwind utilities when possible
|
||||||
3. Add custom CSS only when necessary
|
3. Add custom CSS only when necessary
|
||||||
4. Maintain dark mode support via custom variant
|
4. Maintain dark mode support via custom variant
|
||||||
|
|
||||||
**Working with NixOS configuration**:
|
**Working with NixOS configuration**:
|
||||||
|
|
||||||
1. Changes to server config go in `server/` directory
|
1. Changes to server config go in `server/` directory
|
||||||
2. Always validate with `nix run .#eval-server` before deploying
|
2. Always validate with `nix run .#eval-server` before deploying
|
||||||
3. Be cautious with production server changes
|
3. Be cautious with production server changes
|
||||||
@@ -340,22 +371,26 @@ const rehypeWrapTables = () => {
|
|||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Build Fails
|
### Build Fails
|
||||||
|
|
||||||
- Check `astro.config.ts` for syntax errors
|
- Check `astro.config.ts` for syntax errors
|
||||||
- Verify all blog posts have required frontmatter
|
- Verify all blog posts have required frontmatter
|
||||||
- Ensure TypeScript types are correct
|
- Ensure TypeScript types are correct
|
||||||
- Run `npm install` to update dependencies
|
- Run `npm install` to update dependencies
|
||||||
|
|
||||||
### Dev Server Issues
|
### Dev Server Issues
|
||||||
|
|
||||||
- Port 4321 might be in use (kill the process or use `--port` flag)
|
- Port 4321 might be in use (kill the process or use `--port` flag)
|
||||||
- Clear `.astro/` directory and rebuild: `rm -rf .astro && npm run dev`
|
- Clear `.astro/` directory and rebuild: `rm -rf .astro && npm run dev`
|
||||||
- Check for TypeScript errors in components
|
- Check for TypeScript errors in components
|
||||||
|
|
||||||
### Styling Problems
|
### Styling Problems
|
||||||
|
|
||||||
- Run `npm run format` to fix Tailwind class ordering
|
- Run `npm run format` to fix Tailwind class ordering
|
||||||
- Check global.css for font loading issues
|
- Check global.css for font loading issues
|
||||||
- Verify Tailwind plugin is loaded in Vite config
|
- Verify Tailwind plugin is loaded in Vite config
|
||||||
|
|
||||||
### Content Not Appearing
|
### Content Not Appearing
|
||||||
|
|
||||||
- Verify content collection schema in `src/content.config.ts`
|
- Verify content collection schema in `src/content.config.ts`
|
||||||
- Check frontmatter matches schema requirements
|
- Check frontmatter matches schema requirements
|
||||||
- Ensure file paths are correct
|
- Ensure file paths are correct
|
||||||
|
|||||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -4582,7 +4582,6 @@
|
|||||||
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"prettier": "bin/prettier.cjs"
|
"prettier": "bin/prettier.cjs"
|
||||||
},
|
},
|
||||||
@@ -4599,7 +4598,6 @@
|
|||||||
"integrity": "sha512-RiBETaaP9veVstE4vUwSIcdATj6dKmXljouXc/DDNwBSPTp8FRkLGDSGFClKsAFeeg+13SB0Z1JZvbD76bigJw==",
|
"integrity": "sha512-RiBETaaP9veVstE4vUwSIcdATj6dKmXljouXc/DDNwBSPTp8FRkLGDSGFClKsAFeeg+13SB0Z1JZvbD76bigJw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/compiler": "^2.9.1",
|
"@astrojs/compiler": "^2.9.1",
|
||||||
"prettier": "^3.0.0",
|
"prettier": "^3.0.0",
|
||||||
@@ -5030,7 +5028,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz",
|
||||||
"integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==",
|
"integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "1.0.7"
|
"@types/estree": "1.0.7"
|
||||||
},
|
},
|
||||||
@@ -5325,8 +5322,7 @@
|
|||||||
"version": "4.1.14",
|
"version": "4.1.14",
|
||||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz",
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz",
|
||||||
"integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==",
|
"integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==",
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/tapable": {
|
"node_modules/tapable": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
@@ -5810,7 +5806,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
|
||||||
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
|
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"fdir": "^6.4.4",
|
"fdir": "^6.4.4",
|
||||||
@@ -6018,7 +6013,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ interface Props {
|
|||||||
const { href, variant = "text", title, id } = Astro.props;
|
const { href, variant = "text", title, id } = Astro.props;
|
||||||
|
|
||||||
const baseClasses =
|
const baseClasses =
|
||||||
"border-transparent border-b-2 p-2 cursor-pointer hover:border-neutral-300 hover:bg-neutral-200 hover:dark:border-neutral-600 hover:dark:bg-neutral-700 active:bg-neutral-200 active:dark:bg-neutral-700 active:border-neutral-300 active:dark:border-neutral-600";
|
"border-transparent border-b-2 p-2 cursor-pointer hover:border-[var(--color-accent-cyan)] hover:bg-neutral-200 hover:dark:border-[var(--color-accent-cyan-light)] hover:dark:bg-neutral-700 active:bg-neutral-200 active:dark:bg-neutral-700 active:border-[var(--color-accent-cyan)] active:dark:border-[var(--color-accent-cyan-light)] transition-colors duration-200";
|
||||||
const classes = `${baseClasses} ${variant === "icon" && href ? "inline-grid place-content-center" : "inline-block"}`;
|
const classes = `${baseClasses} ${variant === "icon" && href ? "inline-grid place-content-center" : "inline-block"}`;
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Icon from "./Icon.astro";
|
|||||||
import Button from "./Button.astro";
|
import Button from "./Button.astro";
|
||||||
|
|
||||||
const routes = ["blog", "tracks", "services"];
|
const routes = ["blog", "tracks", "services"];
|
||||||
|
const currentPath = Astro.url.pathname;
|
||||||
---
|
---
|
||||||
|
|
||||||
<nav class="sticky top-0 z-20 max-w-none bg-white dark:bg-neutral-800">
|
<nav class="sticky top-0 z-20 max-w-none bg-white dark:bg-neutral-800">
|
||||||
@@ -15,18 +16,32 @@ const routes = ["blog", "tracks", "services"];
|
|||||||
</a>
|
</a>
|
||||||
<div class="flex overflow-x-auto">
|
<div class="flex overflow-x-auto">
|
||||||
{
|
{
|
||||||
routes.map((route) => (
|
routes.map((route) => {
|
||||||
|
const isActive = currentPath.startsWith(`/${route}`);
|
||||||
|
return (
|
||||||
|
<span class="relative">
|
||||||
<Button href={`/${route}`}>
|
<Button href={`/${route}`}>
|
||||||
{route
|
{route
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||||
.join(" ")}
|
.join(" ")}
|
||||||
</Button>
|
</Button>
|
||||||
))
|
{isActive && (
|
||||||
|
<span class="absolute right-0 bottom-0 left-0 h-0.5 bg-gradient-to-r from-[var(--color-accent-blue)] to-[var(--color-accent-cyan)] dark:from-[var(--color-accent-blue-light)] dark:to-[var(--color-accent-cyan-light)]" />
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
<Button id="theme-toggle" variant="icon" title="Toggle dark mode">
|
<Button id="theme-toggle" variant="icon" title="Toggle dark mode">
|
||||||
<Icon name="moon" class="dark:hidden" />
|
<Icon
|
||||||
<Icon name="sun" class="hidden dark:block" />
|
name="moon"
|
||||||
|
class="transition-colors duration-200 hover:text-[var(--color-accent-cyan)] dark:hidden"
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
name="sun"
|
||||||
|
class="hidden transition-colors duration-200 hover:text-[var(--color-accent-cyan-light)] dark:block"
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="icon" href="/rss.xml" title="RSS feed">
|
<Button variant="icon" href="/rss.xml" title="RSS feed">
|
||||||
<Icon name="rss" />
|
<Icon name="rss" />
|
||||||
|
|||||||
@@ -2,6 +2,13 @@
|
|||||||
@plugin "@tailwindcss/typography";
|
@plugin "@tailwindcss/typography";
|
||||||
@custom-variant dark (&:where(.dark, .dark *));
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--color-accent-cyan: #0891b2;
|
||||||
|
--color-accent-cyan-light: #67e8f9;
|
||||||
|
--color-accent-blue: #1e40af;
|
||||||
|
--color-accent-blue-light: #93c5fd;
|
||||||
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
body {
|
body {
|
||||||
font-family: "Tiempos Text", serif;
|
font-family: "Tiempos Text", serif;
|
||||||
@@ -16,6 +23,32 @@
|
|||||||
font-family: "Styrene A", sans-serif;
|
font-family: "Styrene A", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Gradient effect on h1 and h2 */
|
||||||
|
h1,
|
||||||
|
h2 {
|
||||||
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
var(--color-accent-blue) 0%,
|
||||||
|
var(--color-accent-cyan) 100%
|
||||||
|
);
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark h1,
|
||||||
|
.dark h2 {
|
||||||
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
var(--color-accent-blue-light) 0%,
|
||||||
|
var(--color-accent-cyan-light) 100%
|
||||||
|
);
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
code,
|
code,
|
||||||
kbd,
|
kbd,
|
||||||
samp,
|
samp,
|
||||||
@@ -24,6 +57,15 @@
|
|||||||
font-family: "Styrene B", monospace;
|
font-family: "Styrene B", monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Accent border on code blocks */
|
||||||
|
pre {
|
||||||
|
border-left: 4px solid var(--color-accent-cyan);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark pre {
|
||||||
|
border-left-color: var(--color-accent-cyan-light);
|
||||||
|
}
|
||||||
|
|
||||||
mark {
|
mark {
|
||||||
@apply bg-neutral-200 text-current dark:bg-neutral-600;
|
@apply bg-neutral-200 text-current dark:bg-neutral-600;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user