Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a08fff1d77 | ||
| 6feb1a4f71 | |||
| 500d9e2ea0 | |||
| 70a94990e2 | |||
| d0f10986cd | |||
| 629403fdde | |||
|
|
cd1d8b439d | ||
| fb2e87749c | |||
| 43f0f7b324 | |||
| eab6e0c31d | |||
| 805cb28185 | |||
| 54c82a7f79 | |||
| 9a62f867f1 | |||
|
|
f525567877 | ||
| 7c5356088c | |||
| 0bef13c414 | |||
|
|
eed90ee41d | ||
| 488822bb61 | |||
| 0dfcc25984 | |||
| 4c8665ebe2 | |||
| d083660f1c | |||
| e9a8b6de97 |
@@ -8,44 +8,7 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
semantic-release:
|
||||
runs-on: ubuntu-js
|
||||
outputs:
|
||||
new-release-published: ${{ steps.semantic.outputs.new-release-published }}
|
||||
new-release-version: ${{ steps.semantic.outputs.new-release-version }}
|
||||
new-release-git-tag: ${{ steps.semantic.outputs.new-release-git-tag }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24.14.0
|
||||
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.3.10
|
||||
|
||||
- name: Install Dependencies
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Run Semantic Release
|
||||
id: semantic
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
NODE_PATH: ${{ github.workspace }}/node_modules
|
||||
run: |
|
||||
bun run semantic-release
|
||||
|
||||
build:
|
||||
needs: semantic-release
|
||||
if: ${{ needs.semantic-release.outputs.new-release-published == 'true' }}
|
||||
runs-on: ubuntu-js
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -98,8 +61,6 @@ jobs:
|
||||
image: true
|
||||
|
||||
guarddog:
|
||||
needs: semantic-release
|
||||
if: ${{ needs.semantic-release.outputs.new-release-published == 'true' }}
|
||||
runs-on: ubuntu-js
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -136,9 +97,45 @@ jobs:
|
||||
actions: '[{"action": "view", "label": "Open Gitea", "url": "https://gitea.alexlebens.dev/alexlebens/site-profile/actions?workflow=release-image.yaml", "clear": true}]'
|
||||
image: true
|
||||
|
||||
semantic-release:
|
||||
needs: [ build, guarddog ]
|
||||
runs-on: ubuntu-js
|
||||
outputs:
|
||||
new-release-published: ${{ steps.semantic.outputs.new-release-published }}
|
||||
new-release-version: ${{ steps.semantic.outputs.new-release-version }}
|
||||
new-release-git-tag: ${{ steps.semantic.outputs.new-release-git-tag }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24.14.0
|
||||
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.3.10
|
||||
|
||||
- name: Install Dependencies
|
||||
run: bun install --frozen-lockfile
|
||||
|
||||
- name: Run Semantic Release
|
||||
id: semantic
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||
NODE_PATH: ${{ github.workspace }}/node_modules
|
||||
run: |
|
||||
bun run semantic-release
|
||||
|
||||
release-harbor:
|
||||
runs-on: ubuntu-js
|
||||
needs: [semantic-release, build, guarddog, ]
|
||||
needs: semantic-release
|
||||
if: ${{ needs.semantic-release.outputs.new-release-published == 'true' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -240,13 +237,10 @@ jobs:
|
||||
|
||||
release-gitea:
|
||||
runs-on: ubuntu-js
|
||||
needs: [ semantic-release, build, guarddog, release-harbor ]
|
||||
needs: [ semantic-release, release-harbor ]
|
||||
if: |
|
||||
always() &&
|
||||
needs.semantic-release.result == 'success' &&
|
||||
needs.semantic-release.outputs.new-release-published == 'true' &&
|
||||
needs.build.result == 'success' &&
|
||||
needs.guarddog.result == 'success'
|
||||
needs.semantic-release.outputs.new-release-published == 'true'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
39
CHANGELOG.md
39
CHANGELOG.md
@@ -1,3 +1,42 @@
|
||||
# [3.11.0](https://gitea.alexlebens.dev/alexlebens/site-profile/compare/3.10.0...3.11.0) (2026-03-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* adjustment to spacing ([629403f](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/629403fddea28e86a7e3fc7f9a7cec5bc43ef027))
|
||||
* improve category cards spacing, overflow, and add fade effect to edges ([d0f1098](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/d0f10986cddafffa7893a8751bd1a893dd672983))
|
||||
* move script handling to use swup instead of astro transitions, move animations to baselayout ([500d9e2](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/500d9e2ea03c07bc819132b91c99e12cd8d5fc56))
|
||||
* remove astro features that are replaced by swup ([70a9499](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/70a94990e2067891d68cbfb3831b07e3df346c4e))
|
||||
|
||||
# [3.10.0](https://gitea.alexlebens.dev/alexlebens/site-profile/compare/3.9.0...3.10.0) (2026-03-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* function needing paranthensis ([54c82a7](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/54c82a7f79a335f8dfbe41cbaed7e784a0d80aa7))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add scripts to clear and run from scratch ([805cb28](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/805cb281853edff06adaf4c62b7ae256a00bea3f))
|
||||
* disable prerender pending resoltuion of server island fix ([eab6e0c](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/eab6e0c31dbd24470fa55409326d830a374f86cf))
|
||||
* test placing weather section below posts ([43f0f7b](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/43f0f7b3248cead38e8f9a6ff0d9e411483e440c))
|
||||
|
||||
# [3.9.0](https://gitea.alexlebens.dev/alexlebens/site-profile/compare/3.8.0...3.9.0) (2026-03-13)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* copy package.json ([0bef13c](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/0bef13c414a00f5f7750d1db1db28d29b791394f))
|
||||
|
||||
# [3.8.0](https://gitea.alexlebens.dev/alexlebens/site-profile/compare/3.7.0...3.8.0) (2026-03-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* disable security feature ([0dfcc25](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/0dfcc2598401765a1899d407a8bc34e8c105adcf))
|
||||
* use alpine-dev for bun builder ([4c8665e](https://gitea.alexlebens.dev/alexlebens/site-profile/commit/4c8665ebe2527ff605f82451b2173dd0473aa840))
|
||||
|
||||
# [3.7.0](https://gitea.alexlebens.dev/alexlebens/site-profile/compare/3.6.0...3.7.0) (2026-03-12)
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
FROM dhi.io/bun:1.3.10-debian13-dev AS builder
|
||||
ARG REGISTRY=dhi.io
|
||||
FROM ${REGISTRY}/bun:1.3.10-alpine3.22-dev AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json bun.lock ./
|
||||
@@ -15,14 +17,14 @@ FROM build-deps AS build
|
||||
COPY . .
|
||||
RUN bun run build
|
||||
|
||||
FROM dhi.io/bun:1.3.10-alpine3.22 AS runtime
|
||||
FROM ${REGISTRY}/bun:1.3.10-alpine3.22 AS runtime
|
||||
WORKDIR /app
|
||||
COPY --from=prod-deps /app/node_modules /app/node_modules
|
||||
COPY --from=build /app/dist /app/dist
|
||||
|
||||
ARG APP_VERSION=latest
|
||||
ARG APP_VERSION
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV HOST=0.0.0.0
|
||||
ENV PORT=4321
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@ import { getSiteURL } from './src/support/url';
|
||||
export default defineConfig({
|
||||
site: getSiteURL(),
|
||||
|
||||
security: { csp: true },
|
||||
|
||||
image: {
|
||||
remotePatterns: [
|
||||
{ protocol: 'https', hostname: '*.alexlebens.net' },
|
||||
@@ -26,8 +24,6 @@ export default defineConfig({
|
||||
}
|
||||
},
|
||||
|
||||
prefetch: true,
|
||||
|
||||
integrations: [
|
||||
react(),
|
||||
sitemap(),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "site-profile",
|
||||
"type": "module",
|
||||
"version": "3.7.0",
|
||||
"version": "3.11.0",
|
||||
"homepage": "https://www.alexlebens.dev",
|
||||
"bugs": {
|
||||
"url": "https://gitea.alexlebens.dev/alexlebens/site-profile/issues",
|
||||
@@ -19,8 +19,10 @@
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"full-dev": "rm -rf dist node_modules .astro && bun install && astro build && astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"full-preview": "rm -rf dist node_modules .astro && bun install && astro build && astro preview",
|
||||
"astro": "astro",
|
||||
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,md,mdx,astro}\"",
|
||||
"lint": "eslint \"src/**/*.{js,ts,jsx,tsx,astro}\"",
|
||||
|
||||
@@ -95,5 +95,3 @@ const currentPath = pathname.slice(1);
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<script is:inline src="/vendor/preline/collapse2.1.0.min.js"></script>
|
||||
|
||||
@@ -49,100 +49,88 @@
|
||||
(!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||
document.documentElement.classList.toggle('dark', isDark);
|
||||
};
|
||||
|
||||
applyTheme();
|
||||
|
||||
document.addEventListener('astro:after-swap', applyTheme);
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function setupThemeToggle() {
|
||||
const themeToggles = document.querySelectorAll('[data-theme-toggle]');
|
||||
|
||||
// Create theme switch overlay element
|
||||
if (!document.querySelector('.theme-switch-overlay')) {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'theme-switch-overlay fixed inset-0 pointer-events-none z-50';
|
||||
overlay.style.opacity = '0';
|
||||
overlay.style.transition = 'opacity 0.15s ease-out';
|
||||
document.body.appendChild(overlay);
|
||||
}
|
||||
|
||||
themeToggles.forEach((toggle) => {
|
||||
['click', 'touchend'].forEach((eventType) => {
|
||||
toggle.addEventListener(
|
||||
eventType,
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
// Get click/touch position for radial animation
|
||||
let x, y;
|
||||
if (e.type === 'touchend' && e.changedTouches && e.changedTouches[0]) {
|
||||
const rect = toggle.getBoundingClientRect();
|
||||
x = e.changedTouches[0].clientX - rect.left;
|
||||
y = e.changedTouches[0].clientY - rect.top;
|
||||
} else {
|
||||
const rect = toggle.getBoundingClientRect();
|
||||
x = e.clientX - rect.left;
|
||||
y = e.clientY - rect.top;
|
||||
}
|
||||
|
||||
document.documentElement.style.setProperty('--x', `${x}px`);
|
||||
document.documentElement.style.setProperty('--y', `${y}px`);
|
||||
|
||||
const overlay = document.querySelector('.theme-switch-overlay');
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
const newTheme = isDark ? 'light' : 'dark';
|
||||
|
||||
// Show overlay during transition
|
||||
if (overlay) {
|
||||
overlay.style.backgroundColor =
|
||||
newTheme === 'dark' ? 'rgba(24, 24, 27, 0.3)' : 'rgba(255, 255, 255, 0.3)';
|
||||
overlay.style.opacity = '1';
|
||||
}
|
||||
|
||||
document.documentElement.classList.add('theme-switching');
|
||||
|
||||
// Force a reflow to ensure all elements update
|
||||
document.body.offsetHeight;
|
||||
|
||||
// Toggle dark mode with a slight delay to allow overlay to appear
|
||||
setTimeout(() => {
|
||||
if (isDark) {
|
||||
document.documentElement.classList.remove('dark');
|
||||
} else {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
|
||||
localStorage.setItem('theme', newTheme);
|
||||
document.dispatchEvent(
|
||||
new CustomEvent('themeChanged', {
|
||||
detail: { isDark: newTheme === 'dark' },
|
||||
})
|
||||
);
|
||||
|
||||
// Force another reflow to ensure all elements update
|
||||
document.body.offsetHeight;
|
||||
|
||||
setTimeout(() => {
|
||||
if (overlay) {
|
||||
overlay.style.opacity = '0';
|
||||
}
|
||||
document.documentElement.classList.remove('theme-switching');
|
||||
}, 150);
|
||||
}, 50);
|
||||
},
|
||||
{ passive: false }
|
||||
);
|
||||
});
|
||||
});
|
||||
if (!document.querySelector('.theme-switch-overlay')) {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'theme-switch-overlay fixed inset-0 pointer-events-none z-50';
|
||||
overlay.style.opacity = '0';
|
||||
overlay.style.transition = 'opacity 0.15s ease-out';
|
||||
document.body.appendChild(overlay);
|
||||
}
|
||||
['click', 'touchend'].forEach((eventType) => {
|
||||
document.addEventListener(
|
||||
eventType,
|
||||
(e) => {
|
||||
const target = e.target as HTMLElement;
|
||||
const toggle = target.closest('[data-theme-toggle]');
|
||||
|
||||
// Run setup on load
|
||||
document.addEventListener('astro:page-load', setupThemeToggle);
|
||||
if (!toggle) return;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
let x, y;
|
||||
const rect = toggle.getBoundingClientRect();
|
||||
|
||||
if (eventType === 'touchend') {
|
||||
const touchEvent = e as TouchEvent;
|
||||
if (touchEvent.changedTouches && touchEvent.changedTouches[0]) {
|
||||
x = touchEvent.changedTouches[0].clientX - rect.left;
|
||||
y = touchEvent.changedTouches[0].clientY - rect.top;
|
||||
}
|
||||
} else {
|
||||
const mouseEvent = e as MouseEvent;
|
||||
x = mouseEvent.clientX - rect.left;
|
||||
y = mouseEvent.clientY - rect.top;
|
||||
}
|
||||
|
||||
document.documentElement.style.setProperty('--x', `${x}px`);
|
||||
document.documentElement.style.setProperty('--y', `${y}px`);
|
||||
|
||||
const overlay = document.querySelector('.theme-switch-overlay') as HTMLElement;
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
const newTheme = isDark ? 'light' : 'dark';
|
||||
|
||||
if (overlay) {
|
||||
overlay.style.backgroundColor =
|
||||
newTheme === 'dark' ? 'rgba(24, 24, 27, 0.3)' : 'rgba(255, 255, 255, 0.3)';
|
||||
overlay.style.opacity = '1';
|
||||
}
|
||||
|
||||
document.documentElement.classList.add('theme-switching');
|
||||
|
||||
document.body.offsetHeight;
|
||||
|
||||
setTimeout(() => {
|
||||
if (isDark) {
|
||||
document.documentElement.classList.remove('dark');
|
||||
} else {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
|
||||
localStorage.setItem('theme', newTheme);
|
||||
document.dispatchEvent(
|
||||
new CustomEvent('themeChanged', {
|
||||
detail: { isDark: newTheme === 'dark' },
|
||||
})
|
||||
);
|
||||
|
||||
document.body.offsetHeight;
|
||||
|
||||
setTimeout(() => {
|
||||
if (overlay) {
|
||||
overlay.style.opacity = '0';
|
||||
}
|
||||
document.documentElement.classList.remove('theme-switching');
|
||||
}, 150);
|
||||
}, 50);
|
||||
},
|
||||
{ passive: false }
|
||||
);
|
||||
});
|
||||
|
||||
// Also run on page visibility change to ensure theme is consistent
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
const currentTheme = localStorage.getItem('theme');
|
||||
@@ -154,7 +142,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for system preference changes
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', ({ matches }) => {
|
||||
if (!localStorage.getItem('theme')) {
|
||||
if (matches) {
|
||||
|
||||
@@ -22,8 +22,8 @@ const { slug, title, description, logoLight, logoDark, count, publishDate } = As
|
||||
data-astro-prefetch
|
||||
>
|
||||
<div class="relative grow overflow-hidden">
|
||||
<div class="absolute inset-1 flex flex-col p-3 md:p-4 lg:p-5">
|
||||
<div class="flex flex-row items-center mb-4">
|
||||
<div class="mask-fade-edges absolute inset-1 flex flex-col p-3 md:p-4 lg:p-5">
|
||||
<div class="flex flex-row items-center mb-4 shrink-0">
|
||||
<div class="card-hover-icon-scale shrink-0 mr-3">
|
||||
<Logo
|
||||
srcLight={getDirectusImageURL(logoLight)}
|
||||
@@ -35,12 +35,12 @@ const { slug, title, description, logoLight, logoDark, count, publishDate } = As
|
||||
{title}
|
||||
</h3>
|
||||
</div>
|
||||
<div>
|
||||
<p class="card-text-description mb-4">
|
||||
<div class="overflow-hidden">
|
||||
<p class="card-text-description line-clamp-3">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-text-description flex items-center justify-between text-xs mt-auto pt-1 md:pt-2">
|
||||
<div class="card-text-description flex shrink-0 items-center justify-between text-xs mt-auto pt-1 md:pt-2">
|
||||
<span class="inline-flex items-center">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -18,7 +18,7 @@ const global = await directus.request(readSingleton('site_global'));
|
||||
const { posts, title, subTitle } = Astro.props;
|
||||
---
|
||||
|
||||
<section class="max-w-340 2xl:max-w-full px-4 sm:px-6 lg:px-8 py-10 lg:py-14 mx-auto mb-2 md:mb-8">
|
||||
<section class="max-w-340 2xl:max-w-full px-4 sm:px-6 lg:px-8 py-10 lg:py-14 mx-auto mb-2 md:mb-4">
|
||||
<div class="text-center max-w-2xl mx-auto mb-10 lg:mb-14">
|
||||
<h1 class="smooth-reveal card-text-header block">
|
||||
{title}
|
||||
|
||||
@@ -11,7 +11,7 @@ interface Props {
|
||||
const { posts } = Astro.props;
|
||||
---
|
||||
|
||||
<section class="smooth-reveal flex flex-col gap-4 md:mb-20">
|
||||
<section class="smooth-reveal-cards flex flex-col gap-4 md:mb-20">
|
||||
{posts.map((post, index) => index % 2 === 0 ? (
|
||||
<LargeBlogLeftCard post={post}/>
|
||||
) : (
|
||||
|
||||
@@ -20,7 +20,7 @@ const { forecastDays, error } = await getFiveDayForecast(latitude, longitude, ti
|
||||
</div>
|
||||
{error ? (
|
||||
<div class="card-base p-10 text-accent text-center">
|
||||
Sorry, {error.toLowerCase}
|
||||
Sorry, {error.toLowerCase()}
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex flex-wrap justify-center gap-4 lg:gap-6">
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
---
|
||||
import { ClientRouter } from 'astro:transitions';
|
||||
import { readSingleton } from '@directus/sdk';
|
||||
|
||||
import BaseHead from '@components/BaseHead.astro';
|
||||
@@ -39,8 +38,7 @@ const normalizeTitle = !title ? global.name : `${title} | ${global.name}`;
|
||||
structuredData={structuredData}
|
||||
/>
|
||||
|
||||
<ClientRouter fallback="swap" />
|
||||
|
||||
<!-- Set Theme -->
|
||||
<script is:inline>
|
||||
const theme = (() => {
|
||||
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
|
||||
@@ -60,6 +58,12 @@ const normalizeTitle = !title ? global.name : `${title} | ${global.name}`;
|
||||
window.localStorage.setItem('theme', theme);
|
||||
</script>
|
||||
|
||||
<!-- Preline -->
|
||||
<script
|
||||
src="/vendor/preline/collapse2.1.0.min.js"
|
||||
is:inline
|
||||
/>
|
||||
|
||||
<!-- Rybbit Tracking Snippet -->
|
||||
<script
|
||||
src="https://rybbit.alexlebens.dev/api/script.js"
|
||||
@@ -104,7 +108,52 @@ const normalizeTitle = !title ? global.name : `${title} | ${global.name}`;
|
||||
}
|
||||
};
|
||||
resetScroll();
|
||||
document.addEventListener('astro:after-swap', resetScroll);
|
||||
|
||||
document.addEventListener('swup:page:view', () => {
|
||||
resetScroll();
|
||||
if (typeof (window as any).HSStaticMethods !== 'undefined') {
|
||||
(window as any).HSStaticMethods.autoInit();
|
||||
}
|
||||
if (typeof (window as any).rybbit === 'function') {
|
||||
(window as any).rybbit('trackPageview');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
const animateContent = () => {
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(() => {
|
||||
el.classList.add('animate-reveal');
|
||||
}, 50 + index * 100);
|
||||
});
|
||||
|
||||
const smoothReveal2 = document.querySelectorAll('.smooth-reveal-2');
|
||||
smoothReveal2.forEach((el, index) => {
|
||||
setTimeout(() => {
|
||||
el.classList.add('animate-reveal');
|
||||
}, 200 + index * 250);
|
||||
});
|
||||
|
||||
const smoothRevealCards = document.querySelectorAll('.smooth-reveal-cards');
|
||||
smoothRevealCards.forEach((el, index) => {
|
||||
setTimeout(() => {
|
||||
el.classList.add('animate-reveal');
|
||||
}, 400 + index * 250);
|
||||
});
|
||||
|
||||
const smoothRevealFade = document.querySelectorAll('.smooth-reveal-fade');
|
||||
smoothRevealFade.forEach((el, index) => {
|
||||
setTimeout(() => {
|
||||
el.classList.add('animate-reveal-fade');
|
||||
}, 100 + index * 250);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
|
||||
document.addEventListener('swup:page:view', animateContent);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -86,24 +86,6 @@ const global = await directus.request(readSingleton('site_global'));
|
||||
const randomFact = funFacts[Math.floor(Math.random() * funFacts.length)];
|
||||
funFactElement.textContent = randomFact;
|
||||
}
|
||||
|
||||
// Add smooth reveal animations for content after loading
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const animateContent = () => {
|
||||
// Animate group 1
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
100 + index * 150
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -47,33 +47,3 @@ const global = await directus.request(readSingleton('site_global'));
|
||||
</section>
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
<script>
|
||||
// Add smooth reveal animations for content after loading
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const animateContent = () => {
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
50 + index * 100
|
||||
);
|
||||
});
|
||||
|
||||
// Animate with just fade in with staggered delay
|
||||
const smoothRevealFade = document.querySelectorAll('.smooth-reveal-fade');
|
||||
smoothRevealFade.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal-fade');
|
||||
},
|
||||
100 + index * 250
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -52,56 +52,3 @@ const posts = await directus.request(
|
||||
</section>
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
<script>
|
||||
// Add smooth reveal animations for content after loading
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const animateContent = () => {
|
||||
// Animate group 1
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
50 + index * 100
|
||||
);
|
||||
});
|
||||
|
||||
// Animate group 2
|
||||
const smoothReveal2 = document.querySelectorAll('.smooth-reveal-2');
|
||||
smoothReveal2.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
200 + index * 150
|
||||
);
|
||||
});
|
||||
|
||||
// Animate topic cards with staggered delay
|
||||
const smoothRevealCards = document.querySelectorAll('.smooth-reveal-cards');
|
||||
smoothRevealCards.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
500 + index * 100
|
||||
);
|
||||
});
|
||||
|
||||
// Animate with just fade in with staggered delay
|
||||
const smoothRevealFade = document.querySelectorAll('.smooth-reveal-fade');
|
||||
smoothRevealFade.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal-fade');
|
||||
},
|
||||
100 + index * 250
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -37,23 +37,3 @@ const global = await directus.request(readSingleton('site_global'));
|
||||
<ApplicationSection className="smooth-reveal-2" />
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
<script>
|
||||
// Add smooth reveal animations for content after loading
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const animateContent = () => {
|
||||
// Animate group 1
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
50 + index * 100
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -174,21 +174,4 @@ const content = marked.parse(post.content || '');
|
||||
|
||||
lightbox.init();
|
||||
}
|
||||
|
||||
// Add smooth reveal animations for content after loading
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const animateContent = () => {
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
100 + index * 100
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -57,56 +57,3 @@ const recentPosts: Post[] = posts.filter(
|
||||
/>
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
<script>
|
||||
// Add smooth reveal animations for content after loading
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const animateContent = () => {
|
||||
// Animate group 1
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
200 + index * 300
|
||||
);
|
||||
});
|
||||
|
||||
// Animate group 2
|
||||
const smoothReveal2 = document.querySelectorAll('.smooth-reveal-2');
|
||||
smoothReveal2.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
500 + index * 100
|
||||
);
|
||||
});
|
||||
|
||||
// Animate topic cards with staggered delay
|
||||
const smoothRevealCards = document.querySelectorAll('.smooth-reveal-cards');
|
||||
smoothRevealCards.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
1000 + index * 250
|
||||
);
|
||||
});
|
||||
|
||||
// Animate with just fade in with staggered delay
|
||||
const smoothRevealFade = document.querySelectorAll('.smooth-reveal-fade');
|
||||
smoothRevealFade.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal-fade');
|
||||
},
|
||||
100 + index * 250
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -75,56 +75,3 @@ const categoriesPosts = posts
|
||||
</section>
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
<script>
|
||||
// Add smooth reveal animations for content after loading
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const animateContent = () => {
|
||||
// Animate group 1
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
50 + index * 100
|
||||
);
|
||||
});
|
||||
|
||||
// Animate group 2
|
||||
const smoothReveal2 = document.querySelectorAll('.smooth-reveal-2');
|
||||
smoothReveal2.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
200 + index * 150
|
||||
);
|
||||
});
|
||||
|
||||
// Animate topic cards with staggered delay
|
||||
const smoothRevealCards = document.querySelectorAll('.smooth-reveal-cards');
|
||||
smoothRevealCards.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
500 + index * 100
|
||||
);
|
||||
});
|
||||
|
||||
// Animate with just fade in with staggered delay
|
||||
const smoothRevealFade = document.querySelectorAll('.smooth-reveal-fade');
|
||||
smoothRevealFade.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal-fade');
|
||||
},
|
||||
100 + index * 250
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -37,56 +37,3 @@ const global = await directus.request(readSingleton('site_global'));
|
||||
<CategorySection />
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
<script>
|
||||
// Add smooth reveal animations for content after loading
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const animateContent = () => {
|
||||
// Animate group 1
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
50 + index * 100
|
||||
);
|
||||
});
|
||||
|
||||
// Animate group 2
|
||||
const smoothReveal2 = document.querySelectorAll('.smooth-reveal-2');
|
||||
smoothReveal2.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
200 + index * 150
|
||||
);
|
||||
});
|
||||
|
||||
// Animate topic cards with staggered delay
|
||||
const smoothRevealCards = document.querySelectorAll('.smooth-reveal-cards');
|
||||
smoothRevealCards.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
500 + index * 100
|
||||
);
|
||||
});
|
||||
|
||||
// Animate with just fade in with staggered delay
|
||||
const smoothRevealFade = document.querySelectorAll('.smooth-reveal-fade');
|
||||
smoothRevealFade.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal-fade');
|
||||
},
|
||||
100 + index * 250
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -11,6 +11,10 @@ import GiteaSection from '@components/sections/GiteaSection.astro';
|
||||
import BaseLayout from '@layouts/BaseLayout.astro';
|
||||
import directus from '@lib/directus';
|
||||
|
||||
// Weather section server island does not seem to load under Astro 6, setting the whole page for server
|
||||
// side rendering for now.
|
||||
export const prerender = false
|
||||
|
||||
const global = await directus.request(readSingleton('site_global'));
|
||||
const weather = await directus.request(readSingleton('site_weather'));
|
||||
const posts = await directus.request(
|
||||
@@ -55,6 +59,12 @@ const recentPosts = posts
|
||||
|
||||
<FeatureSection />
|
||||
|
||||
<RecentPostsSection
|
||||
posts={recentPosts}
|
||||
title="Latest Posts"
|
||||
subTitle="Checkout my most recent thoughts here"
|
||||
/>
|
||||
|
||||
<WeatherSection
|
||||
server:defer
|
||||
latitude={weather.latitude}
|
||||
@@ -63,12 +73,6 @@ const recentPosts = posts
|
||||
timezone={weather.timezone}
|
||||
/>
|
||||
|
||||
<RecentPostsSection
|
||||
posts={recentPosts}
|
||||
title="Latest Posts"
|
||||
subTitle="Checkout my most recent thoughts here"
|
||||
/>
|
||||
|
||||
<GiteaSection
|
||||
title="Follow me on Gitea"
|
||||
subTitle="I love open source and have my code availabile on my Gitea server."
|
||||
@@ -76,62 +80,3 @@ const recentPosts = posts
|
||||
/>
|
||||
|
||||
</BaseLayout>
|
||||
|
||||
<script>
|
||||
// Add smooth reveal animations for content after loading
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const animateContent = () => {
|
||||
// Animate group 1
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
50 + index * 100
|
||||
);
|
||||
});
|
||||
|
||||
// Animate group 2
|
||||
const smoothReveal2 = document.querySelectorAll('.smooth-reveal-2');
|
||||
smoothReveal2.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
200 + index * 250
|
||||
);
|
||||
});
|
||||
|
||||
// Animate topic cards with staggered delay
|
||||
const smoothRevealCards = document.querySelectorAll('.smooth-reveal-cards');
|
||||
smoothRevealCards.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
400 + index * 250
|
||||
);
|
||||
});
|
||||
|
||||
// Animate with just fade in with staggered delay
|
||||
const smoothRevealFade = document.querySelectorAll('.smooth-reveal-fade');
|
||||
smoothRevealFade.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal-fade');
|
||||
},
|
||||
100 + index * 250
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
animateContent();
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -138,3 +138,15 @@
|
||||
bg-neutral-100 dark:bg-neutral-800
|
||||
shadow-xs dark:shadow-md
|
||||
}
|
||||
|
||||
@utility mask-fade-edges {
|
||||
-webkit-mask-image:
|
||||
linear-gradient(to right, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent),
|
||||
linear-gradient(to bottom, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent);
|
||||
mask-image:
|
||||
linear-gradient(to right, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent),
|
||||
linear-gradient(to bottom, transparent, black var(--fade-dist, 1rem), black calc(100% - var(--fade-dist, 1rem)), transparent);
|
||||
|
||||
-webkit-mask-composite: source-in;
|
||||
mask-composite: intersect;
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
// Add smooth reveal animations for content after loading
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const animateContent = () => {
|
||||
// Animate group 1
|
||||
const smoothReveal = document.querySelectorAll('.smooth-reveal');
|
||||
smoothReveal.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
50 + index * 100
|
||||
);
|
||||
});
|
||||
|
||||
// Animate group 2
|
||||
const smoothReveal2 = document.querySelectorAll('.smooth-reveal-2');
|
||||
smoothReveal2.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
200 + index * 250
|
||||
);
|
||||
});
|
||||
|
||||
// Animate topic cards with staggered delay
|
||||
const smoothRevealCards = document.querySelectorAll('.smooth-reveal-cards');
|
||||
smoothRevealCards.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal');
|
||||
},
|
||||
400 + index * 250
|
||||
);
|
||||
});
|
||||
|
||||
// Animate with just fade in with staggered delay
|
||||
const smoothRevealFade = document.querySelectorAll('.smooth-reveal-fade');
|
||||
smoothRevealFade.forEach((el, index) => {
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add('animate-reveal-fade');
|
||||
},
|
||||
100 + index * 250
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
animateContent();
|
||||
});
|
||||
Reference in New Issue
Block a user