mirror of
https://github.com/Arlind-dev/sulej.ch.git
synced 2025-12-05 19:17:20 +01:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd8f94dcd6 | ||
|
|
19cb5f14e3 | ||
|
|
f29ecb118e | ||
|
|
742259c87e | ||
|
|
03d20eca98 | ||
|
|
215e7a759e | ||
|
|
667ea89249 | ||
|
|
4aaf96a643 | ||
|
|
9c742d9a90 | ||
|
|
afb550ac16 | ||
|
|
c38c3089e5 | ||
|
|
7a1a2aac21 | ||
|
|
05851c3e72 | ||
|
|
381f14d406 | ||
|
|
7c6e256b3b | ||
|
|
7d0fd2e5b1 | ||
|
|
c697b86375 | ||
|
|
a30832cd17 | ||
|
|
0a89355ceb | ||
|
|
8ad7a8da2e | ||
|
|
35181d2f6f | ||
|
|
8ce4f5b3c5 | ||
| e49ea7dd60 | |||
| 6bfb56264c | |||
| aae339d760 | |||
| d4fbd26596 | |||
| 982fd5f38e | |||
|
|
55318b13da | ||
|
|
da3fcdd87f | ||
|
|
62a0ecf8f1 | ||
|
|
854fa03ca0 | ||
|
|
9c157101c3 | ||
| 5153aeaa27 | |||
| d8901ec8e0 | |||
|
|
a21fbffc96 | ||
|
|
92a1e33c1e | ||
|
|
d6f5c0e9d3 | ||
| ae19a5ed99 | |||
| 5331d06702 | |||
| 6a71380297 | |||
| 9c3aad5205 | |||
| 5f19f10ad0 | |||
|
|
1601d979df | ||
|
|
656533a9e6 | ||
|
|
a4836e7d0b | ||
|
|
129661b096 | ||
|
|
a94a9ddfad | ||
| 4fdcfba3bf | |||
| ad363a9726 | |||
| b5d5d93d53 | |||
| ca43f3ee5d | |||
| 22459635c1 | |||
| 21f517bdf4 | |||
| 09a1e38086 | |||
| cee85a9a1f | |||
| 5b90f1ec52 |
22
.github/dependabot.yml
vendored
Normal file
22
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# Dependabot configuration file
|
||||
# Docs: https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 10
|
||||
166
.github/workflows/main.yml
vendored
166
.github/workflows/main.yml
vendored
@@ -1,19 +1,25 @@
|
||||
name: Release & Deploy Docker
|
||||
name: Semantic Release, Build & Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
id-token: write
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-24.04
|
||||
if: github.ref == 'refs/heads/main'
|
||||
timeout-minutes: 20
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
outputs:
|
||||
new_release_published: ${{ steps.semantic.outputs.new_release_published }}
|
||||
@@ -21,34 +27,27 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Import GPG key and configure signing
|
||||
env:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
||||
uses: crazy-max/ghaction-import-gpg@v6
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
passphrase: ${{ secrets.GPG_PASSPHRASE }}
|
||||
git_user_signingkey: true
|
||||
git_commit_gpgsign: true
|
||||
git_config_global: true
|
||||
|
||||
- name: Configure git user
|
||||
run: |
|
||||
echo "$GPG_PRIVATE_KEY" | gpg --batch --import
|
||||
KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | grep sec | tail -n1 | awk '{print $2}' | cut -d'/' -f2)
|
||||
|
||||
echo "use-agent" >> ~/.gnupg/gpg.conf
|
||||
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
|
||||
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
|
||||
|
||||
git config --global user.signingkey "$KEY_ID"
|
||||
git config --global commit.gpgsign true
|
||||
git config --global gpg.program gpg
|
||||
git config --global gpg.format openpgp
|
||||
|
||||
export GPG_TTY=$(tty)
|
||||
echo "test" | gpg --batch --yes --passphrase "$GPG_PASSPHRASE" --pinentry-mode loopback -u "$KEY_ID" -s >/dev/null
|
||||
|
||||
echo "Using GPG key: $KEY_ID"
|
||||
git config --global user.name "Arlind-dev"
|
||||
git config --global user.email "arlind@sulej.ch"
|
||||
|
||||
- name: Run semantic-release
|
||||
id: semantic
|
||||
uses: cycjimmy/semantic-release-action@v5
|
||||
uses: cycjimmy/semantic-release-action@v6
|
||||
with:
|
||||
extra_plugins: |
|
||||
@semantic-release/changelog
|
||||
@@ -59,18 +58,24 @@ jobs:
|
||||
conventional-changelog-conventionalcommits
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GIT_AUTHOR_NAME: semantic-release-bot
|
||||
GIT_COMMITTER_NAME: semantic-release-bot
|
||||
GIT_AUTHOR_NAME: Arlind-dev
|
||||
GIT_COMMITTER_NAME: Arlind-dev
|
||||
GIT_AUTHOR_EMAIL: arlind@sulej.ch
|
||||
GIT_COMMITTER_EMAIL: arlind@sulej.ch
|
||||
docker:
|
||||
|
||||
docker-prod:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: release
|
||||
needs: [release]
|
||||
if: github.ref == 'refs/heads/main' && needs.release.outputs.new_release_published == 'true'
|
||||
timeout-minutes: 60
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
@@ -82,8 +87,13 @@ jobs:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Normalize repository owner to lowercase
|
||||
run: echo "OWNER_LC=${GITHUB_REPOSITORY_OWNER,,}" >> $GITHUB_ENV
|
||||
- name: Prepare build metadata
|
||||
id: meta
|
||||
run: |
|
||||
echo "owner_lc=${GITHUB_REPOSITORY_OWNER,,}" >> "$GITHUB_OUTPUT"
|
||||
echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
|
||||
|
||||
- name: Build and push build-stage image
|
||||
uses: docker/build-push-action@v6
|
||||
@@ -92,32 +102,108 @@ jobs:
|
||||
file: Dockerfile.build
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
provenance: false
|
||||
provenance: mode=max
|
||||
sbom: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
outputs: type=registry,oci-mediatypes=true
|
||||
tags: |
|
||||
ghcr.io/${{ env.OWNER_LC }}/${{ vars.IMAGE_NAME }}:build-latest
|
||||
ghcr.io/${{ env.OWNER_LC }}/${{ vars.IMAGE_NAME }}:build-${{ needs.release.outputs.new_release_version }}
|
||||
ghcr.io/${{ steps.meta.outputs.owner_lc }}/${{ vars.IMAGE_NAME }}:build-latest
|
||||
ghcr.io/${{ steps.meta.outputs.owner_lc }}/${{ vars.IMAGE_NAME }}:build-${{ needs.release.outputs.new_release_version }}
|
||||
|
||||
- name: Build and push main image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/386,linux/ppc64le,linux/riscv64,linux/s390x
|
||||
push: true
|
||||
provenance: false
|
||||
provenance: mode=max
|
||||
sbom: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
outputs: type=registry,oci-mediatypes=true
|
||||
build-args: |
|
||||
BUILD_IMAGE=ghcr.io/${{ env.OWNER_LC }}/${{ vars.IMAGE_NAME }}:build-latest
|
||||
BUILD_IMAGE=ghcr.io/${{ steps.meta.outputs.owner_lc }}/${{ vars.IMAGE_NAME }}:build-${{ needs.release.outputs.new_release_version }}
|
||||
tags: |
|
||||
ghcr.io/${{ env.OWNER_LC }}/${{ vars.IMAGE_NAME }}:latest
|
||||
ghcr.io/${{ env.OWNER_LC }}/${{ vars.IMAGE_NAME }}:${{ needs.release.outputs.new_release_version }}
|
||||
ghcr.io/${{ steps.meta.outputs.owner_lc }}/${{ vars.IMAGE_NAME }}:latest
|
||||
ghcr.io/${{ steps.meta.outputs.owner_lc }}/${{ vars.IMAGE_NAME }}:${{ needs.release.outputs.new_release_version }}
|
||||
|
||||
docker-dev:
|
||||
runs-on: ubuntu-24.04
|
||||
if: github.ref != 'refs/heads/main'
|
||||
timeout-minutes: 60
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Prepare metadata and branch vars
|
||||
id: meta
|
||||
run: |
|
||||
echo "owner_lc=${GITHUB_REPOSITORY_OWNER,,}" >> "$GITHUB_OUTPUT"
|
||||
BRANCH_NAME=${GITHUB_REF#refs/heads/}
|
||||
SANITIZED_BRANCH=$(echo "$BRANCH_NAME" | tr '/' '-' | tr '_' '-' | tr -cd '[:alnum:]-')
|
||||
echo "sanitized_branch=$SANITIZED_BRANCH" >> "$GITHUB_OUTPUT"
|
||||
echo "sha_short=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
|
||||
echo "build_date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
|
||||
|
||||
- name: Build and push build-stage image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.build
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
provenance: mode=max
|
||||
sbom: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
outputs: type=registry,oci-mediatypes=true
|
||||
tags: |
|
||||
ghcr.io/${{ steps.meta.outputs.owner_lc }}/${{ vars.IMAGE_NAME }}:build-${{ steps.meta.outputs.sanitized_branch }}-${{ steps.meta.outputs.sha_short }}
|
||||
|
||||
- name: Build and push main image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6,linux/386,linux/ppc64le,linux/riscv64,linux/s390x
|
||||
push: true
|
||||
provenance: mode=max
|
||||
sbom: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
outputs: type=registry,oci-mediatypes=true
|
||||
build-args: |
|
||||
BUILD_IMAGE=ghcr.io/${{ steps.meta.outputs.owner_lc }}/${{ vars.IMAGE_NAME }}:build-${{ steps.meta.outputs.sanitized_branch }}-${{ steps.meta.outputs.sha_short }}
|
||||
tags: |
|
||||
ghcr.io/${{ steps.meta.outputs.owner_lc }}/${{ vars.IMAGE_NAME }}:${{ steps.meta.outputs.sanitized_branch }}-${{ steps.meta.outputs.sha_short }}
|
||||
|
||||
deploy:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: release
|
||||
if: always()
|
||||
if: github.ref == 'refs/heads/main'
|
||||
timeout-minutes: 10
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Trigger Cloudflare Pages deploy
|
||||
run: |
|
||||
|
||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -1,14 +1,21 @@
|
||||
## 1.0.0 (2025-10-12)
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **ci:** add signed commits
|
||||
* Create sulej.ch
|
||||
## [1.1.0](https://github.com/Arlind-dev/sulej.ch/compare/v1.0.1...v1.1.0) (2025-10-28)
|
||||
|
||||
### Features
|
||||
|
||||
* Create sulej.ch ([9814ab8](https://github.com/Arlind-dev/sulej.ch/commit/9814ab83122785f7baefba7da27c9871b926e7e6))
|
||||
* **ui:** add new favicon ([6bfb562](https://github.com/Arlind-dev/sulej.ch/commit/6bfb56264c3752e35369ac167c0149f8a7ca75c6))
|
||||
|
||||
## [1.0.1](https://github.com/Arlind-dev/sulej.ch/compare/v1.0.0...v1.0.1) (2025-10-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ui:** top-align layout and restyle footer version link ([#20](https://github.com/Arlind-dev/sulej.ch/issues/20)) ([6a71380](https://github.com/Arlind-dev/sulej.ch/commit/6a71380297ad9047cb79c7417e513a11bc57e6ad))
|
||||
|
||||
## 1.0.0 (2025-10-12)
|
||||
|
||||
### Features
|
||||
|
||||
* **init:** Create sulej.ch ([40c353f](https://github.com/Arlind-dev/sulej.ch/commit/40c353ff4efe2ed26f4462ecef7dd08a23437474))
|
||||
|
||||
### Miscellaneous Chores
|
||||
|
||||
* **ci:** add signed commits ([c926beb](https://github.com/Arlind-dev/sulej.ch/commit/c926beb5c8a4a75acac59528b696a84b45398fcd))
|
||||
* **ci:** add signed commits ([61fc8af](https://github.com/Arlind-dev/sulej.ch/commit/61fc8af54da54653a5faedcded6ea3830c17e50d))
|
||||
|
||||
12
Dockerfile
12
Dockerfile
@@ -1,10 +1,12 @@
|
||||
FROM ghcr.io/arlind-dev/sulej.ch:build-latest AS build
|
||||
ARG BUILD_IMAGE=ghcr.io/arlind-dev/sulej.ch:build-latest
|
||||
FROM --platform=$BUILDPLATFORM ${BUILD_IMAGE} AS build
|
||||
|
||||
FROM nginx:1.29.3-alpine3.22
|
||||
|
||||
ARG BUILD_IMAGE
|
||||
|
||||
FROM nginx:alpine
|
||||
WORKDIR /usr/share/nginx/html
|
||||
|
||||
COPY --from=build /output ./
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
@@ -1,15 +1,14 @@
|
||||
FROM node:alpine AS build
|
||||
FROM node:24.1.0-alpine3.20 AS build
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
RUN npm install -g --force corepack \
|
||||
&& corepack enable
|
||||
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN pnpm run build
|
||||
|
||||
RUN mkdir -p /output && cp -r /app/build/. /output/
|
||||
|
||||
16
SECURITY.md
Normal file
16
SECURITY.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
This project only supports the **latest release**.
|
||||
Older versions do **not** receive security updates or patches.
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | --------------------- |
|
||||
| Latest | ✅ Supported |
|
||||
| Older | ❌ Not supported |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a security vulnerability, please report it by emailing **arlind@sulej.ch**.
|
||||
Alternatively, you may open a private issue on GitHub or contact the maintainers directly.
|
||||
1553
package-lock.json
generated
1553
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
@@ -1,25 +1,26 @@
|
||||
{
|
||||
"name": "sulej.ch",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"packageManager": "pnpm@10.15.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"prepare": "svelte-kit sync",
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"dev": "svelte-kit sync && vite dev",
|
||||
"build": "svelte-kit sync && vite build",
|
||||
"preview": "svelte-kit sync && vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"svelte": "^5.39.11"
|
||||
"svelte": "^5.45.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-static": "^3.0.10",
|
||||
"@sveltejs/kit": "^2.46.4",
|
||||
"@sveltejs/kit": "^2.49.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
||||
"svelte-check": "^4.3.3",
|
||||
"@types/node": "^24.10.1",
|
||||
"svelte-check": "^4.3.4",
|
||||
"typescript": "^5.9.3",
|
||||
"vite": "^7.1.9"
|
||||
"vite": "^7.2.6"
|
||||
}
|
||||
}
|
||||
|
||||
550
pnpm-lock.yaml
generated
550
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
20
src/app.css
20
src/app.css
@@ -1,26 +1,10 @@
|
||||
@font-face {
|
||||
font-family: 'JetBrains Mono Nerd Font';
|
||||
src: url('/fonts/JetBrainsMonoNerdFont-Regular.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'JetBrains Mono Nerd Font';
|
||||
src: url('/fonts/JetBrainsMonoNerdFont-Bold.ttf') format('truetype');
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
font-family: 'JetBrains Mono Nerd Font', 'JetBrains Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
|
||||
font-family: 'JetBrains Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
|
||||
}
|
||||
|
||||
:root {
|
||||
--font-mono: 'JetBrains Mono Nerd Font', 'JetBrains Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
|
||||
--font-mono: 'JetBrains Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
<meta charset="utf-8" />
|
||||
<link id="fav" rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
|
||||
<meta name="description" content="sulej.ch">
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<script lang="ts">
|
||||
import { site } from "./site.config";
|
||||
const mailto = `mailto:${site.contactEmail}`;
|
||||
</script>
|
||||
|
||||
<section>
|
||||
<div style="margin: 0.5rem 0;">Owner: Arlind Sulejmani</div>
|
||||
<div style="margin: 0.5rem 0;">Contact: <a href="mailto:arlind@sulej.ch">arlind@sulej.ch</a></div>
|
||||
<div style="margin: 0.5rem 0;">Owner: {site.ownerName}</div>
|
||||
<div style="margin: 0.5rem 0;">Contact: <a href={mailto}>{site.contactEmail}</a></div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -1,15 +1,50 @@
|
||||
<script lang="ts">
|
||||
import type { VersionInfo } from "./version";
|
||||
import { site, currentYear } from "./site.config";
|
||||
export let versionInfo: VersionInfo;
|
||||
</script>
|
||||
|
||||
<footer>
|
||||
<div style="display: inline-flex; align-items: baseline; gap: 1rem; margin: 1rem 0 0;">
|
||||
<small>© 2025 sulej.ch</small>
|
||||
<small>© {currentYear} {site.domain}</small>
|
||||
<small>
|
||||
<a href="https://github.com/Arlind-dev/sulej.ch">
|
||||
{versionInfo.version} ({versionInfo.commit})
|
||||
</a>
|
||||
{#if site.githubRepo}
|
||||
<a class="version-link" href={site.githubRepo}>
|
||||
{versionInfo.version} <span class="commit">({versionInfo.commit})</span>
|
||||
</a>
|
||||
{:else}
|
||||
<span class="version-link" aria-label="App version">
|
||||
{versionInfo.version} <span class="commit">({versionInfo.commit})</span>
|
||||
</span>
|
||||
{/if}
|
||||
</small>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
.version-link {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid transparent;
|
||||
opacity: 0.85;
|
||||
transition: border-color 120ms ease, opacity 120ms ease, color 120ms ease;
|
||||
}
|
||||
|
||||
.version-link:hover {
|
||||
border-color: currentColor;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.version-link:focus-visible {
|
||||
outline: 2px solid currentColor;
|
||||
outline-offset: 2px;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.commit {
|
||||
opacity: 0.7;
|
||||
letter-spacing: 0.02em;
|
||||
font-family: var(--font-mono);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { site } from "./site.config";
|
||||
const title = `About ${site.siteTitle}`;
|
||||
// Keep markup minimal and data-driven via config
|
||||
</script>
|
||||
|
||||
<header>
|
||||
<h1 style="margin: 0.5rem 0 1rem;">About sulej.ch</h1>
|
||||
<h1 style="margin: 0.5rem 0 1rem;">{title}</h1>
|
||||
</header>
|
||||
|
||||
17
src/lib/site.config.ts
Normal file
17
src/lib/site.config.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export type SiteConfig = {
|
||||
ownerName: string;
|
||||
contactEmail: string;
|
||||
domain: string; // e.g. "sulej.ch"
|
||||
siteTitle: string; // e.g. "sulej.ch"
|
||||
githubRepo?: string; // optional repo URL
|
||||
};
|
||||
|
||||
export const site: SiteConfig = {
|
||||
ownerName: "Arlind Sulejmani",
|
||||
contactEmail: "arlind@sulej.ch",
|
||||
domain: "sulej.ch",
|
||||
siteTitle: "sulej.ch",
|
||||
githubRepo: "https://github.com/Arlind-dev/sulej.ch"
|
||||
};
|
||||
|
||||
export const currentYear = new Date().getFullYear();
|
||||
@@ -1,14 +1,18 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import '../app.css';
|
||||
import { site } from '../lib/site.config';
|
||||
const title = site.siteTitle;
|
||||
const description = `${site.siteTitle} — ${site.domain}`;
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>sulej.ch</title>
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description} />
|
||||
</svelte:head>
|
||||
|
||||
<div style="height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: clamp(1rem, 1.5vw, 1.5rem); padding: clamp(0.5rem, 2vw, 1.5rem); font-size: clamp(1rem, 1rem + 1vw, 1.5rem);">
|
||||
<div style="min-height: 100vh; padding-top: clamp(1rem, 8vh, 6rem); display: flex; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center; gap: clamp(1rem, 1.5vw, 1.5rem); padding-left: clamp(0.5rem, 2vw, 1.5rem); padding-right: clamp(0.5rem, 2vw, 1.5rem); padding-bottom: clamp(0.5rem, 2vw, 1.5rem); font-size: clamp(1rem, 1rem + 1vw, 1.5rem);">
|
||||
<slot />
|
||||
|
||||
</div>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user