Compare commits
77 Commits
70b0b86944
...
0.8.13
Author | SHA1 | Date | |
---|---|---|---|
54759056b3 | |||
3cc9762e0d | |||
ef757c4a14
|
|||
176f92bf67 | |||
09d411dd68 | |||
54acfcb24d
|
|||
6f3b631862
|
|||
18cd240a9b | |||
bb4fe8ef37
|
|||
e0e3c1f61a
|
|||
0b5c6ae999 | |||
a20ba4ab43 | |||
550e7dfe52 | |||
03174cfb9d
|
|||
da50c1928c
|
|||
f1d1fe979e | |||
4d6019d0b0 | |||
7dd302b3d4
|
|||
8a8f2a6216
|
|||
97775f1ceb | |||
0a437a26f1 | |||
ba67b4d0e4 | |||
0bcfa9bed4
|
|||
ada95481f7
|
|||
7c9f4acc00
|
|||
0b7b87580a
|
|||
08f076e566
|
|||
26c27b9353 | |||
ce8b3a2e19 | |||
6d34c0d407 | |||
63607bbca3 | |||
745d2553a0
|
|||
8a19559cc7 | |||
42854db0fb
|
|||
7b72e3849b | |||
6a8dbb0c7c | |||
91fdf5a83f
|
|||
073f3a7916
|
|||
38202841ca | |||
0492922cce
|
|||
a17500835b | |||
2f8b97208c | |||
d6c30d5e5b
|
|||
a7ea9db3aa
|
|||
9134e78e8a | |||
2ca7d6705d | |||
5722e8c7a1 | |||
e39fd2acb8 | |||
0313fd54bc | |||
dbb0f6d7ff | |||
20669d9766 | |||
6b2e6353d1 | |||
6d112b52df | |||
ff17af604f | |||
32ea0989d7 | |||
e4ab7d134c | |||
5fad13655c | |||
8614d40a64 | |||
8c417b93b3 | |||
1d9519831b | |||
fa57f2e93f | |||
9e01002d4e | |||
cb52c169a3 | |||
3017668cd2 | |||
1972b3bc19 | |||
af77f90a49 | |||
bdda29f369 | |||
644c5fcd6a | |||
bafd8158d3 | |||
4d9c1a3e8c | |||
4a4233ac62 | |||
c71957348d | |||
400bf16dd9 | |||
85535614a0 | |||
38fcbb635b | |||
b1e57c3f17 | |||
e22a1985be |
35
.gitea/workflows/process-issues.yaml
Normal file
35
.gitea/workflows/process-issues.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
name: process-issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '@daily'
|
||||
|
||||
jobs:
|
||||
process-issues:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Python Script
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: alexlebens/workflow-scripts
|
||||
ref: main
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
path: scripts
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.13'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install requests
|
||||
|
||||
- name: Run Script
|
||||
env:
|
||||
INSTANCE_URL: ${{ vars.INSTANCE_URL }}
|
||||
REPOSITORY: ${{ gitea.repository }}
|
||||
TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
STALE_DAYS: 3
|
||||
STALE_TAG: 'stale'
|
||||
EXCLUDE_TAG: 'renovate'
|
||||
run: python ./scripts/scripts/process-issues.py
|
35
.gitea/workflows/process-pull-requests.yaml
Normal file
35
.gitea/workflows/process-pull-requests.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
name: process-pull-requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '@daily'
|
||||
|
||||
jobs:
|
||||
process-pull-requests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Python Script
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: alexlebens/workflow-scripts
|
||||
ref: main
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
path: scripts
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.13'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install requests
|
||||
|
||||
- name: Run Script
|
||||
env:
|
||||
INSTANCE_URL: ${{ vars.INSTANCE_URL }}
|
||||
REPOSITORY: ${{ gitea.repository }}
|
||||
TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
STALE_DAYS: 3
|
||||
STALE_TAG: 'stale'
|
||||
REQUIRED_TAG: 'automerge'
|
||||
run: python ./scripts/scripts/process-pull-requests.py
|
@@ -13,7 +13,7 @@ on:
|
||||
jobs:
|
||||
renovate:
|
||||
runs-on: ubuntu-latest
|
||||
container: ghcr.io/renovatebot/renovate:40
|
||||
container: ghcr.io/renovatebot/renovate:41
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
@@ -1,75 +0,0 @@
|
||||
name: tag-old-issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '@daily'
|
||||
|
||||
jobs:
|
||||
tag-old-issues:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Tag Old Issues
|
||||
env:
|
||||
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
INSTANCE_URL: ${{ vars.INSTANCE_URL }}
|
||||
REPO_OWNER: ${{ github.repository_owner }}
|
||||
REPO_NAME: ${{ github.repository_name }}
|
||||
TAG_NAME: 'stale'
|
||||
DAYS_OLD: 3
|
||||
EXCLUDE_TAG_NAME: ''
|
||||
REQUIRED_TAG: 'automerge'
|
||||
run: |
|
||||
# Install necessary tools
|
||||
apt-get update && apt-get install -y jq curl
|
||||
|
||||
# --- Conditionally build the API URL ---
|
||||
API_URL="${GITEA_INSTANCE_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/issues?state=open"
|
||||
if [[ -n "${REQUIRED_TAG}" ]]; then
|
||||
echo "Filtering for issues with the required tag: ${REQUIRED_TAG}"
|
||||
# URL-encode the tag to handle special characters
|
||||
ENCODED_TAG=$(jq -s -R -r @uri <<< "${REQUIRED_TAG}")
|
||||
API_URL="${API_URL}&labels=${ENCODED_TAG}"
|
||||
else
|
||||
echo "No required tag specified. Checking all open issues."
|
||||
fi
|
||||
|
||||
# Fetch issues using the constructed URL
|
||||
ISSUES=$(curl -s -X GET \
|
||||
-H "Authorization: token ${BOT_TOKEN}" \
|
||||
-H "Accept: application/json" \
|
||||
"${API_URL}")
|
||||
|
||||
# Calculate the date ${DAYS_OLD} days ago in ISO 8601 format
|
||||
OLDER_THAN_DATE=$(date -d "-${DAYS_OLD} days" -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||
|
||||
# Filter issues older than the specified date and without the exclusion tag
|
||||
echo "$ISSUES" | jq -c '.[] | select(.created_at < "'"$OLDER_THAN_DATE"'")' | while read -r issue; do
|
||||
ISSUE_NUMBER=$(echo "$issue" | jq -r '.number')
|
||||
LABELS=$(echo "$issue" | jq -r '.labels[].name')
|
||||
|
||||
# Check if the issue has the exclusion tag
|
||||
if ! echo "$LABELS" | grep -q -w "${EXCLUDE_TAG_NAME}"; then
|
||||
echo "Tagging issue #${ISSUE_NUMBER} as ${TAG_NAME}"
|
||||
|
||||
# Get existing labels for the issue
|
||||
EXISTING_LABELS=$(curl -s -X GET \
|
||||
-H "Authorization: token ${BOT_TOKEN}" \
|
||||
-H "Accept: application/json" \
|
||||
"${INSTANCE_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/issues/${ISSUE_NUMBER}/labels" | jq -r '.[].name')
|
||||
|
||||
# Add the new tag to the list of existing labels
|
||||
NEW_LABELS=$(echo -e "${EXISTING_LABELS}\n${TAG_NAME}" | sort -u | jq -R -s -c 'split("\n") | map(select(length > 0))')
|
||||
|
||||
# Update the issue with the new set of labels
|
||||
curl -s -X PUT \
|
||||
-H "Authorization: token ${BOT_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"labels\": $(echo "$NEW_LABELS" | jq -r 'map(select(. != ""))')}" \
|
||||
"${INSTANCE_URL}/api/v1/repos/${REPO_OWNER}/${REPO_NAME}/issues/${ISSUE_NUMBER}/labels"
|
||||
else
|
||||
echo "Skipping issue #${ISSUE_NUMBER} because it has the '${EXCLUDE_TAG_NAME}' tag."
|
||||
fi
|
||||
done
|
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.16.x
|
||||
node-version: 22.17.x
|
||||
cache: pnpm
|
||||
|
||||
- name: Install Dependencies
|
||||
|
@@ -1,7 +1,7 @@
|
||||
ARG REGISTRY=docker.io
|
||||
FROM ${REGISTRY}/node:22.16.0-alpine3.22 AS base
|
||||
FROM ${REGISTRY}/node:22.17.0-alpine3.22 AS base
|
||||
|
||||
LABEL version="0.8.10"
|
||||
LABEL version="0.8.13"
|
||||
LABEL description="Astro based personal website"
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
|
15
package.json
15
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "site-profile",
|
||||
"type": "module",
|
||||
"version": "0.8.10",
|
||||
"version": "0.8.13",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
@@ -17,14 +17,11 @@
|
||||
"@astrojs/node": "^9.2.2",
|
||||
"@astrojs/react": "^4.3.0",
|
||||
"@astrojs/rss": "^4.0.12",
|
||||
"@astrojs/sitemap": "^3.4.1",
|
||||
"@directus/sdk": "^19.1.0",
|
||||
"@directus/sdk": "^20.0.0",
|
||||
"@tailwindcss/postcss": "^4.1.8",
|
||||
"@tailwindcss/vite": "^4.1.8",
|
||||
"astro": "^5.9.2",
|
||||
"form-data": "4.0.3",
|
||||
"astro": "^5.10.1",
|
||||
"framer-motion": "^12.16.0",
|
||||
"postcss-preset-env": "^10.2.1",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-hotkeys-hook": "^5.1.0",
|
||||
@@ -34,13 +31,13 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@typescript-eslint/parser": "8.34.0",
|
||||
"eslint": "9.28.0",
|
||||
"@typescript-eslint/parser": "8.36.0",
|
||||
"eslint": "9.30.1",
|
||||
"eslint-config-prettier": "10.1.5",
|
||||
"eslint-plugin-astro": "1.3.1",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-astro": "^0.14.1",
|
||||
"prettier-plugin-tailwindcss": "^0.6.12",
|
||||
"typescript-eslint": "8.34.0"
|
||||
"typescript-eslint": "8.36.0"
|
||||
}
|
||||
}
|
||||
|
2097
pnpm-lock.yaml
generated
2097
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -2,12 +2,6 @@
|
||||
const config = {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {},
|
||||
autoprefixer: {},
|
||||
'postcss-preset-env': {
|
||||
features: {
|
||||
'nesting-rules': false,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
BIN
public/i.jpg
Normal file
BIN
public/i.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 381 KiB |
@@ -1,10 +1,40 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["config:recommended", "mergeConfidence:all-badges", ":rebaseStalePrs"],
|
||||
"extends": [
|
||||
"config:recommended",
|
||||
"mergeConfidence:all-badges",
|
||||
":rebaseStalePrs"
|
||||
],
|
||||
"timezone": "US/Central",
|
||||
"schedule": ["* */1 * * *"],
|
||||
"labels": [],
|
||||
"prHourlyLimit": 0,
|
||||
"prConcurrentLimit": 0,
|
||||
"packageRules": []
|
||||
"packageRules": [
|
||||
{
|
||||
"description": "Label dependency",
|
||||
"matchDatasources": [
|
||||
"npm"
|
||||
],
|
||||
"addLabels": [
|
||||
"dependency"
|
||||
],
|
||||
"automerge": false,
|
||||
"minimumReleaseAge": "1 days"
|
||||
},
|
||||
{
|
||||
"description": "Automerge dependency patch",
|
||||
"matchDatasources": [
|
||||
"npm"
|
||||
],
|
||||
"matchUpdateTypes": [
|
||||
"patch"
|
||||
],
|
||||
"addLabels": [
|
||||
"dependency",
|
||||
"automerge"
|
||||
],
|
||||
"automerge": true,
|
||||
"minimumReleaseAge": "1 days"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -135,6 +135,7 @@ const socialLinks = [
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bottom section -->
|
||||
<div class="theme-transition-all mt-12 border-t border-zinc-200 pt-8 dark:border-zinc-800">
|
||||
@@ -181,9 +182,9 @@ const socialLinks = [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
<style>
|
||||
.theme-transition-all {
|
||||
transition-property: background-color, border-color, color, fill, stroke;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
@@ -245,5 +246,4 @@ const socialLinks = [
|
||||
.animation-delay-2000 {
|
||||
animation-delay: 2s;
|
||||
}
|
||||
</style>
|
||||
</footer>
|
||||
</style>
|
||||
|
@@ -72,7 +72,7 @@ const currentPath = pathname.slice(1);
|
||||
class="pointer-events-none fixed inset-0 z-50 flex flex-col bg-white opacity-0 transition-all duration-300 ease-in-out dark:bg-zinc-900"
|
||||
>
|
||||
<div class="flex items-center justify-between border-b border-zinc-100 p-4 dark:border-zinc-800">
|
||||
<a href="/" class="text-xl font-bold text-zinc-900 dark:text-white">JD</a>
|
||||
<a href="/" class="text-xl font-bold text-zinc-900 dark:text-white">{global.initals}</a>
|
||||
<button
|
||||
id="close-menu-button"
|
||||
class="rounded-md p-2 text-zinc-900 transition-colors hover:bg-zinc-100 dark:text-white dark:hover:bg-zinc-800"
|
||||
@@ -200,9 +200,9 @@ const currentPath = pathname.slice(1);
|
||||
|
||||
// Add shadow on scroll
|
||||
if (currentScrollY > 10) {
|
||||
header.classList.add('shadow-sm');
|
||||
header.classList.add('shadow-xs');
|
||||
} else {
|
||||
header.classList.remove('shadow-sm');
|
||||
header.classList.remove('shadow-xs');
|
||||
}
|
||||
|
||||
// Update last scroll position
|
||||
@@ -240,6 +240,6 @@ const currentPath = pathname.slice(1);
|
||||
/* Mobile menu transition */
|
||||
#mobile-menu {
|
||||
transition: opacity 0.3s ease;
|
||||
backdrop-filter: blur(4px);
|
||||
backdrop-filter: blur-sm(4px);
|
||||
}
|
||||
</style>
|
||||
|
@@ -94,7 +94,7 @@ const encodedUrl = encodeURIComponent(url);
|
||||
>
|
||||
<span
|
||||
id="copy-tooltip"
|
||||
class="absolute -top-8 left-1/2 -translate-x-1/2 transform rounded bg-zinc-800 px-2 py-1 text-xs whitespace-nowrap text-white opacity-0 transition-opacity duration-300 dark:bg-zinc-700"
|
||||
class="absolute -top-8 left-1/2 -translate-x-1/2 transform rounded-sm bg-zinc-800 px-2 py-1 text-xs whitespace-nowrap text-white opacity-0 transition-opacity duration-300 dark:bg-zinc-700"
|
||||
>
|
||||
Copied!
|
||||
</span>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<button
|
||||
id="theme-toggle"
|
||||
data-theme-toggle
|
||||
class="group relative touch-manipulation overflow-hidden rounded-full p-1.5 transition-all duration-300 hover:bg-zinc-100 focus:ring-2 focus:ring-zinc-300 focus:outline-none sm:p-2 dark:hover:bg-zinc-800 dark:focus:ring-zinc-700"
|
||||
class="group relative touch-manipulation overflow-hidden rounded-full p-1.5 transition-all duration-300 hover:bg-zinc-100 focus:ring-2 focus:ring-zinc-300 focus:outline-hidden sm:p-2 dark:hover:bg-zinc-800 dark:focus:ring-zinc-700"
|
||||
aria-label="Toggle dark mode"
|
||||
>
|
||||
<div class="relative z-10 flex h-5 w-5 items-center justify-center">
|
||||
@@ -274,12 +274,12 @@
|
||||
}
|
||||
|
||||
#theme-toggle:hover .icon-light:not(.dark .icon-light) {
|
||||
filter: drop-shadow(0 0 2px rgba(251, 191, 36, 0.6));
|
||||
filter: drop-shadow-sm(0 0 2px rgba(251, 191, 36, 0.6));
|
||||
transform: scale(1.1) rotate(15deg);
|
||||
}
|
||||
|
||||
#theme-toggle:hover .icon-dark:not(:not(.dark) .icon-dark) {
|
||||
filter: drop-shadow(0 0 2px rgba(129, 140, 248, 0.6));
|
||||
filter: drop-shadow-sm(0 0 2px rgba(129, 140, 248, 0.6));
|
||||
transform: scale(1.1) rotate(-15deg);
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,6 @@ export interface Props {
|
||||
}
|
||||
---
|
||||
|
||||
<Layout title={global.title} description={global.description}>
|
||||
<Layout title={global.title} description={global.title}>
|
||||
<slot />
|
||||
</Layout>
|
||||
|
@@ -12,7 +12,7 @@ export interface Props {
|
||||
}
|
||||
---
|
||||
|
||||
<Layout title={global.title} description={global.description}>
|
||||
<Layout title={global.title} description={global.title}>
|
||||
<slot />
|
||||
</Layout>
|
||||
|
||||
|
@@ -17,7 +17,7 @@ const { title, description } = Astro.props;
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.png" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<meta name="description" content={description} />
|
||||
<title>{title}</title>
|
||||
@@ -42,7 +42,7 @@ const { title, description } = Astro.props;
|
||||
<!-- Background component with dot pattern and ambient glow -->
|
||||
<Background />
|
||||
|
||||
<div class="mx-auto w-full max-w-3xl flex-grow px-4 sm:px-6">
|
||||
<div class="mx-auto w-full max-w-3xl grow px-4 sm:px-6">
|
||||
<Navigation />
|
||||
<main class="py-12">
|
||||
<slot />
|
||||
@@ -281,7 +281,7 @@ const { title, description } = Astro.props;
|
||||
/* Page transition effects */
|
||||
#page-transition {
|
||||
transition: opacity 0.3s ease;
|
||||
backdrop-filter: blur(4px);
|
||||
backdrop-filter: blur-sm(4px);
|
||||
}
|
||||
|
||||
/* Transition spinner animation */
|
||||
|
@@ -1,12 +1,12 @@
|
||||
---
|
||||
import { ViewTransitions } from 'astro:transitions';
|
||||
import { ClientRouter } from 'astro:transitions';
|
||||
import BaseLayout from './BaseLayout.astro';
|
||||
|
||||
const { title, description } = Astro.props;
|
||||
---
|
||||
|
||||
<BaseLayout title={title} description={description}>
|
||||
<ViewTransitions fallback="swap" />
|
||||
<ClientRouter fallback="swap" />
|
||||
|
||||
<div transition:animate="slide">
|
||||
<slot />
|
||||
|
@@ -68,7 +68,7 @@ import Layout from '../layouts/Layout.astro';
|
||||
|
||||
<button
|
||||
id="back-button"
|
||||
class="group inline-flex items-center gap-2 rounded-lg border border-zinc-300 px-6 py-3 text-zinc-700 shadow-sm transition-all duration-300 hover:bg-zinc-100 hover:shadow-md dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
class="group inline-flex items-center gap-2 rounded-lg border border-zinc-300 px-6 py-3 text-zinc-700 shadow-xs transition-all duration-300 hover:bg-zinc-100 hover:shadow-md dark:border-zinc-700 dark:text-zinc-300 dark:hover:bg-zinc-800"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -89,7 +89,7 @@ import Layout from '../layouts/Layout.astro';
|
||||
|
||||
<!-- Random fun fact -->
|
||||
<div
|
||||
class="mx-auto mt-16 max-w-md rounded-xl border border-zinc-100 bg-zinc-50 p-6 shadow-sm backdrop-blur-sm dark:border-zinc-700/50 dark:bg-zinc-800/50"
|
||||
class="mx-auto mt-16 max-w-md rounded-xl border border-zinc-100 bg-zinc-50 p-6 shadow-xs backdrop-blur-xs dark:border-zinc-700/50 dark:bg-zinc-800/50"
|
||||
>
|
||||
<h3 class="text-sm font-medium tracking-wider text-zinc-500 uppercase dark:text-zinc-400">
|
||||
Did you know?
|
||||
|
@@ -120,18 +120,12 @@ const skills = await directus.request(
|
||||
<div class="slider-track animate-slide flex">
|
||||
{
|
||||
skills.map((skill, index) => (
|
||||
<div
|
||||
key={`${skill.title}-${index}`}
|
||||
class="skill-card theme-transition-element mx-2 min-w-[220px] transform rounded-xl border border-zinc-200 bg-white transition-all duration-300 hover:-translate-y-2 hover:scale-105 hover:border-zinc-300 hover:shadow-xl sm:mx-4 sm:min-w-[280px] dark:border-zinc-700 dark:bg-zinc-800/50 dark:hover:border-zinc-600"
|
||||
>
|
||||
<div class="skill-card theme-transition-element mx-2 min-w-[220px] transform rounded-xl border border-zinc-200 bg-white transition-all duration-300 hover:-translate-y-2 hover:scale-105 hover:border-zinc-300 hover:shadow-xl sm:mx-4 sm:min-w-[280px] dark:border-zinc-700 dark:bg-zinc-800/50 dark:hover:border-zinc-600">
|
||||
<div class="p-4 sm:p-6">
|
||||
<div class="mb-4 flex items-center justify-between sm:mb-6">
|
||||
<div class="flex items-center gap-2 sm:gap-4">
|
||||
<div class="theme-transition-bg theme-transition-color flex h-8 w-8 transform items-center justify-center rounded-lg bg-zinc-100 text-zinc-800 transition-transform group-hover:rotate-12 sm:h-12 sm:w-12 dark:bg-zinc-800 dark:text-zinc-200">
|
||||
<skill.icon
|
||||
size={20}
|
||||
className="sm:text-2xl transform transition-all hover:scale-125"
|
||||
/>
|
||||
<skill.icon />
|
||||
</div>
|
||||
<h3 class="theme-transition-color text-base font-semibold text-zinc-900 sm:text-xl dark:text-zinc-100">
|
||||
{skill.title}
|
||||
|
@@ -309,7 +309,7 @@ const { post, nextPost, prevPost } = Astro.props;
|
||||
}
|
||||
|
||||
.prose code {
|
||||
@reference rounded bg-zinc-100 px-1.5 py-0.5 text-sm font-medium text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200;
|
||||
@reference rounded-sm bg-zinc-100 px-1.5 py-0.5 text-sm font-medium text-zinc-800 dark:bg-zinc-800 dark:text-zinc-200;
|
||||
}
|
||||
|
||||
.prose pre {
|
||||
|
@@ -202,7 +202,7 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
||||
</a>
|
||||
</h3>
|
||||
|
||||
<p class="mb-4 line-clamp-2 flex-grow text-center text-sm text-zinc-600 md:text-left dark:text-zinc-400">
|
||||
<p class="mb-4 line-clamp-2 grow text-center text-sm text-zinc-600 md:text-left dark:text-zinc-400">
|
||||
{post.description}
|
||||
</p>
|
||||
|
||||
|
@@ -236,7 +236,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
||||
<span class="theme-transition-color mr-2 text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||
#{tag}
|
||||
</span>
|
||||
<span class="theme-transition-all flex-shrink-0 rounded-full bg-zinc-100 px-2 py-0.5 text-xs text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
|
||||
<span class="theme-transition-all shrink-0 rounded-full bg-zinc-100 px-2 py-0.5 text-xs text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
|
||||
{tagCount} {tagCount === 1 ? 'post' : 'posts'}
|
||||
</span>
|
||||
</div>
|
||||
|
@@ -88,7 +88,7 @@ const relatedTags = [
|
||||
class="mb-2 flex flex-col justify-center gap-4 sm:flex-row sm:items-center sm:justify-start"
|
||||
>
|
||||
<div
|
||||
class="tag-icon mx-auto flex h-12 w-12 items-center justify-center rounded-xl bg-zinc-100 shadow-sm sm:mx-0 dark:bg-zinc-800"
|
||||
class="tag-icon mx-auto flex h-12 w-12 items-center justify-center rounded-xl bg-zinc-100 shadow-xs sm:mx-0 dark:bg-zinc-800"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -144,7 +144,7 @@ const relatedTags = [
|
||||
{relatedTags.map((relatedTag) => (
|
||||
<a
|
||||
href={`/topics/${relatedTag}`}
|
||||
class="inline-flex flex-shrink-0 items-center rounded-full bg-zinc-100 px-3 py-1.5 text-sm font-medium text-zinc-900 transition-colors hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-100 dark:hover:bg-zinc-700"
|
||||
class="inline-flex shrink-0 items-center rounded-full bg-zinc-100 px-3 py-1.5 text-sm font-medium text-zinc-900 transition-colors hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-100 dark:hover:bg-zinc-700"
|
||||
>
|
||||
#{relatedTag}
|
||||
</a>
|
||||
@@ -167,7 +167,7 @@ const relatedTags = [
|
||||
|
||||
<div class="flex flex-col gap-5 sm:flex-row sm:gap-6">
|
||||
{post.image && (
|
||||
<div class="mx-auto h-40 w-full flex-shrink-0 overflow-hidden rounded-xl shadow-sm transition-all duration-300 group-hover:shadow-md sm:mx-0 sm:w-56">
|
||||
<div class="mx-auto h-40 w-full shrink-0 overflow-hidden rounded-xl shadow-xs transition-all duration-300 group-hover:shadow-md sm:mx-0 sm:w-56">
|
||||
<img
|
||||
src={`${process.env.DIRECTUS_URL ?? 'https://directus.alexlebens.dev'}/assets/${post.image}?width=500`}
|
||||
alt={post.image_alt}
|
||||
|
@@ -52,7 +52,7 @@ const sortedTags = [...tagObjects].sort((a, b) => b.count - a.count);
|
||||
<span class="relative inline-block">
|
||||
<span class="relative inline-block">
|
||||
<span
|
||||
class="theme-transition-bg absolute -inset-1 rounded-lg bg-gradient-to-r from-zinc-200/50 to-zinc-300/50 blur-sm dark:from-zinc-800/50 dark:to-zinc-700/50"
|
||||
class="theme-transition-bg absolute -inset-1 rounded-lg bg-gradient-to-r from-zinc-200/50 to-zinc-300/50 blur-xs dark:from-zinc-800/50 dark:to-zinc-700/50"
|
||||
></span>
|
||||
<span class="relative">Explore</span>
|
||||
</span>
|
||||
@@ -101,7 +101,7 @@ const sortedTags = [...tagObjects].sort((a, b) => b.count - a.count);
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex w-full justify-center">
|
||||
<div class="tag-cloud hover-3d glass theme-transition-all relative w-full rounded-lg border border-zinc-100 bg-white/50 p-3 backdrop-blur-sm sm:rounded-xl sm:p-4 md:rounded-2xl md:p-6 lg:rounded-3xl lg:p-8 dark:border-zinc-800 dark:bg-zinc-900/50">
|
||||
<div class="tag-cloud hover-3d glass theme-transition-all relative w-full rounded-lg border border-zinc-100 bg-white/50 p-3 backdrop-blur-xs sm:rounded-xl sm:p-4 md:rounded-2xl md:p-6 lg:rounded-3xl lg:p-8 dark:border-zinc-800 dark:bg-zinc-900/50">
|
||||
<div class="bg-grid-pattern theme-transition-bg absolute inset-0 opacity-5 dark:opacity-10" />
|
||||
<div class="theme-transition-bg absolute -top-8 -right-8 h-20 w-20 rounded-full bg-gradient-to-br from-zinc-200/30 to-zinc-300/20 blur-xl sm:h-24 sm:w-24 md:h-32 md:w-32 lg:h-40 lg:w-40 dark:from-zinc-700/20 dark:to-zinc-800/10" />
|
||||
<div class="theme-transition-bg absolute -bottom-8 -left-8 h-20 w-20 rounded-full bg-gradient-to-tl from-zinc-200/30 to-zinc-300/20 blur-xl sm:h-24 sm:w-24 md:h-32 md:w-32 lg:h-40 lg:w-40 dark:from-zinc-700/20 dark:to-zinc-800/10" />
|
||||
@@ -114,13 +114,13 @@ const sortedTags = [...tagObjects].sort((a, b) => b.count - a.count);
|
||||
{sortedTags.map((tag) => (
|
||||
<a
|
||||
href={`/topics/${tag.name}`}
|
||||
class="theme-transition-element theme-ripple group relative min-w-0 flex-grow overflow-hidden rounded-md border border-zinc-200 transition-all duration-300 hover:scale-[1.03] hover:border-zinc-300 hover:shadow-md active:scale-95 sm:rounded-lg sm:hover:shadow-lg md:rounded-xl dark:border-zinc-800 dark:hover:border-zinc-700"
|
||||
class="theme-transition-element theme-ripple group relative min-w-0 grow overflow-hidden rounded-md border border-zinc-200 transition-all duration-300 hover:scale-[1.03] hover:border-zinc-300 hover:shadow-md active:scale-95 sm:rounded-lg sm:hover:shadow-lg md:rounded-xl dark:border-zinc-800 dark:hover:border-zinc-700"
|
||||
style={`--tag-hue: ${tag.hue};`}
|
||||
>
|
||||
<div class="theme-transition-bg absolute inset-0 bg-gradient-to-br from-zinc-50/90 to-zinc-100/90 opacity-100 transition-opacity group-hover:opacity-95 dark:from-zinc-800/90 dark:to-zinc-900/90" />
|
||||
|
||||
<div class="xxxs:px-2 xxs:px-2 xs:px-2 xxxs:py-2 xxs:py-2 xs:py-2 xxs:gap-2 relative flex w-full items-center gap-1.5 px-1.5 py-1.5 sm:px-3 sm:py-3 md:px-4 md:py-4">
|
||||
<div class="xxxs:w-6 xxxs:h-6 xxs:w-6 xxs:h-6 xs:w-7 xs:h-7 group-hover:bg-accent/20 dark:group-hover:bg-accent/20 group-hover:text-accent-dark dark:group-hover:text-accent-light theme-transition-all flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-zinc-100 text-zinc-700 shadow-sm transition-all duration-300 sm:h-8 sm:w-8 md:h-10 md:w-10 dark:bg-zinc-800 dark:text-zinc-300">
|
||||
<div class="xxxs:w-6 xxxs:h-6 xxs:w-6 xxs:h-6 xs:w-7 xs:h-7 group-hover:bg-accent/20 dark:group-hover:bg-accent/20 group-hover:text-accent-dark dark:group-hover:text-accent-light theme-transition-all flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-zinc-100 text-zinc-700 shadow-xs transition-all duration-300 sm:h-8 sm:w-8 md:h-10 md:w-10 dark:bg-zinc-800 dark:text-zinc-300">
|
||||
<span class="xxxs:text-xs xxs:text-xs xs:text-sm text-xs font-semibold sm:text-base md:text-lg">
|
||||
#
|
||||
</span>
|
||||
@@ -554,8 +554,8 @@ const sortedTags = [...tagObjects].sort((a, b) => b.count - a.count);
|
||||
}
|
||||
|
||||
/* Prevent layout shifts */
|
||||
.flex-grow {
|
||||
flex-grow: 1;
|
||||
.grow {
|
||||
grow: 1;
|
||||
}
|
||||
|
||||
.min-w-0 {
|
||||
|
@@ -15,7 +15,7 @@
|
||||
}
|
||||
|
||||
body {
|
||||
@reference min-h-screen bg-white text-zinc-900 dark:bg-zinc-900 dark:text-zinc-100;
|
||||
@apply min-h-screen bg-white text-zinc-900 dark:bg-zinc-900 dark:text-zinc-100;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
@@ -41,7 +41,7 @@
|
||||
/* Better touch targets on mobile */
|
||||
button,
|
||||
a {
|
||||
@reference min-h-[44px];
|
||||
@apply min-h-[44px];
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user