Compare commits

..

1 commit
dev ... main

Author SHA1 Message Date
f5bb4bf78e Merge pull request 'Mergin dev - new header, updated servants' (#29) from dev into main
All checks were successful
/ checking (push) Successful in 14s
/ build-site (push) Successful in 1m41s
/ release (push) Successful in 7s
Reviewed-on: #29
2024-06-15 17:20:51 +00:00
93 changed files with 10086 additions and 4300 deletions

View file

@ -1,59 +1,41 @@
name: Build and deploy preview site
run-name: Building and deploying preview for version ${{ github.ref_name }}
on:
push:
tags:
- '[0-9]+\.[0-9]+\.[0-9]+-pre\.[0-9]+'
- '[0-9]+\.[0-9]+\.[0-9]+pre[0-9]+'
jobs:
check-tag:
runs-on: docker
steps:
- name: Checking Out Repository Code
uses: https://code.forgejo.org/actions/checkout@v3
- name: Check if Version in package.json matches Tag
run: |
VERSION=$(npm pkg get version --workspaces=false | tr -d \")
if test $VERSION != "${{ github.ref_name }}"; then
echo "Expected Version is: '${{ github.ref_name }}' actual Version is: '$VERSION'";
exit 1
else
echo "Version is: '$VERSION'";
fi
checking:
needs: [ check-tag ]
runs-on: docker
container: forgejo.neshweb.net/ci-docker-images/node-alpine-git:latest
container: node:lts
steps:
- name: Checkout source code
uses: https://code.forgejo.org/actions/checkout@v3
- name: Install packages
run: npm i
run: npm install
- name: Run astro check (linting + static analysis)
run: npm run astro check
build-site:
needs: [ checking ]
needs: [checking]
if: success()
runs-on: dind
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log into Docker Package Registry
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: forgejo.neshweb.net
username: ${{ secrets.FORGEJO_USERNAME }}
password: ${{ secrets.FORGEJO_TOKEN }}
- name: Build and push to Docker Package Registry
- name: Push to Package Registry
uses: docker/build-push-action@v5
with:
push: true
tags: forgejo.neshweb.net/firq/firq-dev-website:${{ github.ref_name }}, forgejo.neshweb.net/firq/firq-dev-website:preview
create-release:
needs: [ build-site ]
publish:
needs: [build-site]
if: success()
runs-on: docker
steps:
@ -67,33 +49,22 @@ jobs:
tag: ${{ github.ref_name }}
prerelease: true
auto-deploy-dockge:
needs: [ build-site ]
if: success()
runs-on: docker
container: forgejo.neshweb.net/firq/dockge-cli:0.1.2
steps:
- name: Configure Dockge CLI
run: |
dockge host '${{ vars.DOCKGE_HOST }}'
dockge login --user '${{ secrets.DOCKGE_USER }}' --password '${{ secrets.DOCKGE_CREDENTIAL }}'
- name: Check status and redeploy
run: |
dockge status firq-dev-preview
dockge update firq-dev-preview
dockge status firq-dev-preview
run-unlighthouse:
needs: [ build-site ]
if: success()
runs-on: docker
steps:
- name: Launch workflow
run: |
payload="{\"ref\": \"${GITHUB_REF_NAME}\", \"inputs\": { \"containertag\": \"${GITHUB_REF_NAME}\" }}"
curl -X "POST" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: token ${GITHUB_TOKEN}" \
-d "${payload}" \
"${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/actions/workflows/unlighthouse.yml/dispatches" -v
# doesn't work atm
# unlighthouse:
# needs: [publish]
# if: success()
# runs-on: docker
# container: registry.gitlab.com/gitlab-ci-utils/lighthouse:latest
# services:
# website:
# image: forgejo.neshweb.net/firq/firq-dev-website:preview
# steps:
# - name: Install Dependencies
# run: npm install @unlighthouse/cli puppeteer
# - name: Run unlighthouse
# run: node_modules/.bin/unlighthouse-ci
# - name: Upload reports
# uses: actions/upload-artifact@v3
# with:
# name: unlighthouse-reports
# path: unlighthouse-reports/

View file

@ -1,90 +1,41 @@
name: Build and deploy production site
run-name: Building and deploying release for version ${{ github.ref_name }}
on:
push:
tags:
- '[0-9]+\.[0-9]+\.[0-9]+'
jobs:
check-tag:
runs-on: docker
steps:
- name: Checking Out Repository Code
uses: https://code.forgejo.org/actions/checkout@v3
- name: Check if Version in package.json matches Tag
run: |
VERSION=$(npm pkg get version --workspaces=false | tr -d \")
if test $VERSION != "${{ github.ref_name }}"; then
echo "Expected Version is: '${{ github.ref_name }}' actual Version is: '$VERSION'";
exit 1
else
echo "Version is: '$VERSION'";
fi
checking:
needs: [ check-tag ]
runs-on: docker
container: forgejo.neshweb.net/ci-docker-images/node-alpine-git:latest
container: node:lts
steps:
- name: Checkout source code
uses: https://code.forgejo.org/actions/checkout@v3
- name: Install packages
run: npm i
run: npm install
- name: Run astro check (linting + static analysis)
run: npm run astro check
build-site:
needs: [ checking ]
needs: [checking]
if: success()
runs-on: dind
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log into Docker Package Registry
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: forgejo.neshweb.net
username: ${{ secrets.FORGEJO_USERNAME }}
password: ${{ secrets.FORGEJO_TOKEN }}
- name: Build and push to Docker Package Registry
- name: Push to Package Registry
uses: docker/build-push-action@v5
with:
push: true
tags: forgejo.neshweb.net/firq/firq-dev-website:${{ github.ref_name }}, forgejo.neshweb.net/firq/firq-dev-website:latest
auto-deploy-dockge:
needs: [ build-site ]
if: success()
runs-on: docker
container: forgejo.neshweb.net/firq/dockge-cli:0.1.2
steps:
- name: Configure Dockge CLI
run: |
dockge host '${{ vars.DOCKGE_HOST }}'
dockge login --user '${{ secrets.DOCKGE_USER }}' --password '${{ secrets.DOCKGE_CREDENTIAL }}'
- name: Check status and redeploy
run: |
dockge status firq-dev
dockge update firq-dev
dockge status firq-dev
run-unlighthouse:
needs: [ build-site ]
if: success()
runs-on: docker
steps:
- name: Launch workflow
run: |
payload="{\"ref\": \"${GITHUB_REF_NAME}\", \"inputs\": { \"containertag\": \"${GITHUB_REF_NAME}\" }}"
curl -X "POST" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: token ${GITHUB_TOKEN}" \
-d "${payload}" \
"${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/actions/workflows/unlighthouse.yml/dispatches" -v
create-release:
needs: [ build-site ]
release:
needs: [build-site]
if: success()
runs-on: docker
steps:

View file

@ -1,27 +1,16 @@
name: Linting and checking code
run-name: Linting and checking code
on:
push:
branches:
- '**'
- "**"
jobs:
get-version:
checking:
runs-on: docker
steps:
- name: Checking Out Repository Code
uses: https://code.forgejo.org/actions/checkout@v3
- name: Get version from package.json
run: |
VERSION=$(npm pkg get version --workspaces=false | tr -d \")
echo "Version is: '$VERSION'";
astro-check:
runs-on: docker
container: forgejo.neshweb.net/ci-docker-images/node-alpine-git:latest
container: node:lts
steps:
- name: Checkout source code
uses: https://code.forgejo.org/actions/checkout@v3
- name: Install packages
run: npm i
run: npm install
- name: Run astro check (linting + static analysis)
run: npm run astro check

View file

@ -1,36 +1,18 @@
name: Run unlighthouse-tests [Downstream pipeline]
run-name: Run unlighthouse-tests [Downstream pipeline] for version ${{ inputs.containertag }}
on:
workflow_dispatch:
inputs:
containertag:
description: "Tag of the container to test"
default: "preview"
type: "string"
push:
tags:
- '[0-9]+\.[0-9]+\.[0-9]+unlighthouse[0-9]+'
- '[0-9]+\.[0-9]+\.[0-9]+ulh[0-9]+'
jobs:
unlighthouse:
runs-on: docker
container:
image: forgejo.neshweb.net/ci-docker-images/unlighthouse:0.3.0
services:
website:
image: forgejo.neshweb.net/firq/firq-dev-website:${{ inputs.containertag }}
options: >-
--workdir /
container: forgejo.neshweb.net/ci-docker-images/unlighthouse:latest
steps:
- name: Checkout repository
uses: https://code.forgejo.org/actions/checkout@v3
- name: Check availability
run: |
while [ "$(curl -o /dev/null -s -w '%{http_code}' http://localhost:8081/)" -ne 200 ];
do echo "Waiting...";
sleep 5;
done;
- name: Run unlighthouse
run: unlighthouse-ci --site "http://localhost:8081/"
- name: Replace URLs
run: find ./unlighthouse-reports -type f | xargs sed -i "s|http://localhost:8081|https://preview.firq.dev|g";
run: unlighthouse-ci --site "https://preview.firq.dev/"
- name: Prepare artifacts
run: cp serve.json unlighthouse-reports
- name: Upload reports
@ -38,54 +20,79 @@ jobs:
with:
name: unlighthouse-reports
path: unlighthouse-reports/
- name: Upload Dockerfile
uses: actions/upload-artifact@v3
with:
name: dockerfile
path: Dockerfile.reports
build-site:
deploy-unlighthouse-files:
needs: [ unlighthouse ]
if: success()
runs-on: dind
runs-on: docker
env:
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
steps:
- name: Downloading static site artifacts
uses: actions/download-artifact@v3
with:
name: dockerfile
- name: Install and update ssh + rsync
run: |
which rsync || ( apt update -y && apt install rsync -y)
which ssh-agent || ( apt update -y && apt install openssh-client -y)
- name: Downloading static site artifacts
uses: actions/download-artifact@v3
with:
name: unlighthouse-reports
path: reports
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log into Docker Package Registry
uses: docker/login-action@v3
path: public
- name: Install SSH Key
uses: https://github.com/shimataro/ssh-key-action@v2
with:
registry: forgejo.neshweb.net
username: ${{ secrets.FORGEJO_USERNAME }}
password: ${{ secrets.FORGEJO_TOKEN }}
- name: Build and push to Docker Package Registry
uses: docker/build-push-action@v5
key: ${{ secrets.SSH_PRIVATE_KEY }}
known_hosts: unnecessary
- name: Adding Known Hosts
run: ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
- name: Stop screen session, delete old files
uses: https://github.com/appleboy/ssh-action@master
with:
context: .
file: Dockerfile.reports
push: true
tags: forgejo.neshweb.net/firq/firq-dev-website-unlighthouse:latest
host: ${{ env.DEPLOY_HOST }}
username: ${{ env.DEPLOY_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
screen -X -S firq_dev-unlighthouse kill
rm -r -f firq_dev/unlighthouse/*
- name: Copy files using rsync
run: rsync -az --stats public/* ${{ env.DEPLOY_USER }}@${{ env.DEPLOY_HOST }}:~/firq_dev/unlighthouse
- name: Check files on deploy target
uses: https://github.com/appleboy/ssh-action@master
with:
host: ${{ env.DEPLOY_HOST }}
username: ${{ env.DEPLOY_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd firq_dev
find unlighthouse -maxdepth 1 -printf "%p\n"
auto-deploy-dockge:
needs: [ build-site ]
deploy-unlighthouse-site:
needs: [ deploy-unlighthouse-files ]
if: success()
runs-on: docker
container: forgejo.neshweb.net/firq/dockge-cli:0.1.2
env:
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
steps:
- name: Configure Dockge CLI
- name: Install and update ssh + rsync
run: |
dockge host '${{ vars.DOCKGE_HOST }}'
dockge login --user '${{ secrets.DOCKGE_USER }}' --password '${{ secrets.DOCKGE_CREDENTIAL }}'
- name: Check status and redeploy
run: |
dockge status firq-dev-unlighthouse
dockge update firq-dev-unlighthouse
dockge status firq-dev-unlighthouse
which rsync || ( apt update -y && apt install rsync -y)
which ssh-agent || ( apt update -y && apt install openssh-client -y)
- name: Install SSH Key
uses: https://github.com/shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_PRIVATE_KEY }}
known_hosts: unnecessary
- name: Adding Known Hosts
run: ssh-keyscan -H ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts
- name: Start new screen session
uses: https://github.com/appleboy/ssh-action@master
with:
host: ${{ env.DEPLOY_HOST }}
username: ${{ env.DEPLOY_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
PATH="$HOME/.local/bin:$PATH"
screen -ls | grep 'firq_dev-unlighthouse' | awk '{print $1}' | xargs -I % -t screen -X -S % quit
cd firq_dev
screen -S firq_dev-unlighthouse -dm serve unlighthouse/ -p ${{ secrets.UNLIGHTHOUSE_DEPLOY_PORT }}

14
.gitignore vendored
View file

@ -1,14 +1,9 @@
# build output
dist/
.output/
public/
maintenance/
# astro stuff
.astro/
# config stuff
.vscode/
# Temp Scripts
scripts/
@ -28,3 +23,10 @@ pnpm-debug.log*
# macOS-specific files
.DS_Store
# exclude default png images
static/**/*.png
!static/assets/embed.png
!static/assets/lurker.png
!static/assets/padoru.png
!static/assets/fedora.png

View file

@ -1,5 +0,0 @@
{
"MD013":false,
"MD033": false,
"MD036": false
}

View file

@ -3,5 +3,4 @@
**/.vscode
**/public
**/static
**/scripts
**/dist
**/scripts

4
.vscode/extensions.json vendored Normal file
View file

@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

12
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,12 @@
{
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/Thumbs.db": true,
"**/__pycache__": true
},
"hide-files.files": []
}

View file

@ -1,15 +1,16 @@
FROM node:22-alpine AS build
FROM node:lts AS build
WORKDIR /app
COPY . .
RUN npm i
RUN npm run astro telemetry disable
RUN npm run build
FROM forgejo.neshweb.net/ci-docker-images/website-serve:2 AS runtime
FROM forgejo.neshweb.net/ci-docker-images/website-serve:latest AS runtime
COPY --from=build /app/dist /public
COPY --from=build /app/serve.json /public/serve.json
RUN rm /public/.original.favicon.ico
RUN rm -r /public/data/
ENV PORT 8081
EXPOSE 8081
CMD serve public/ -p 8081
CMD [ "serve", "public/", "-p", "8081" ]

View file

@ -1,6 +0,0 @@
FROM forgejo.neshweb.net/ci-docker-images/website-serve:2 AS runtime
ADD reports /public
EXPOSE 8081
CMD serve public/ -p 8081

View file

@ -2,6 +2,43 @@
This is build using [Astro](https://astro.build)
## 🚀 Project Structure
```
/
├── static/
│ ├── favicon.svg
│ └── other files ...
├── src/
│ ├── components/
│ │ ├── servantCard.astro
│ │ ├── ceCard.astro
│ │ ├── contactCard.astro
│ │ └── taCard.astro
│ │
│ ├── layouts/
│ │ ├── customFooter.astro
│ │ ├── baseSection.astro
│ │ ├── taSection.astro
│ │ ├── contactSection.astro
│ │ └── Layout.astro
│ │
│ └── pages/
│ └── index.astro
├── .gitlab-ci.yml
├── astro.config.mjs
└── package.json
```
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
More routes will follow soon
Any static assets, like images, can be placed in the `static/` directory.
## 🧞 Astro-Specific Commands
All commands are run from the root of the project, from a terminal:
@ -14,3 +51,4 @@ All commands are run from the root of the project, from a terminal:
| `npm run preview` | Preview your build locally, before deploying |
| `npm run astro ...` | Run CLI commands like `astro add`, `astro preview` |
| `npm run astro --help` | Get help using the Astro CLI |

View file

@ -1,15 +1,14 @@
import { defineConfig } from 'astro/config';
import mdx from "@astrojs/mdx";
import sitemap from "@astrojs/sitemap";
import astroMetaTags from "astro-meta-tags";
import mdx from "@astrojs/mdx";
// https://astro.build/config
export default defineConfig({
sitemap: true,
base: '/',
outDir: 'dist',
publicDir: 'public',
publicDir: 'static',
site: 'https://firq.dev/',
integrations: [sitemap(), mdx(), astroMetaTags()]
integrations: [sitemap(), mdx()]
});

11474
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
{
"name": "@firq/fgosite",
"type": "module",
"version": "0.2.0-pre.59",
"version": "0.1.27",
"private": true,
"scripts": {
"dev": "astro dev",
@ -11,17 +11,15 @@
"astro": "astro"
},
"dependencies": {
"@astro-community/astro-embed-youtube": "^0.5.2",
"@astrojs/check": "^0.9.4",
"@astrojs/mdx": "^3.1.8",
"@astrojs/sitemap": "^3.2.1",
"@fontsource-variable/work-sans": "^5.1.0",
"astro": "^4.16.6",
"astro-meta-tags": "^0.3.1",
"autoprefixer": "^10.4.19",
"iconoir": "^7.7.0",
"postcss-preset-env": "^9.6.0",
"typescript": "^5.5.3"
"@astro-community/astro-embed-youtube": "^0.4.3",
"@astrojs/check": "^0.3.3",
"@astrojs/mdx": "^2.0.3",
"@astrojs/sitemap": "^3.0.3",
"astro": "^4.2.1",
"autoprefixer": "^10.4.16",
"iconoir": "^7.2.0",
"postcss-preset-env": "^9.3.0",
"typescript": "^5.3.3"
},
"browserslist": [
"last 2 versions",

View file

@ -1,8 +0,0 @@
User-agent: *
Disallow: /assets/data/
User-agent: GPTBot
User-agent: Bytespider
Disallow: /
Sitemap: https://firq.dev/sitemap-index.xml

View file

@ -17,15 +17,6 @@
"value" : "max-age=31536000"
}]
},
{
"source": "**/*.woff2",
"headers": [
{
"key": "Cache-Control",
"value" : "max-age=31536000"
}
]
},
{
"source" : "**/*.@(jpg|jpeg|gif|png|webp|svg)",
"headers" : [{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36"><path fill="#fff" d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/></svg>

Before

Width:  |  Height:  |  Size: 761 B

View file

@ -1,37 +0,0 @@
<svg viewBox="0 0 212 212" xmlns="http://www.w3.org/2000/svg">
<metadata
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
>
<rdf:RDF>
<cc:Work rdf:about="https://codeberg.org/forgejo/governance/src/branch/main/branding#logo">
<dc:title>Forgejo logo</dc:title>
<cc:creator rdf:resource="https://caesarschinas.com/"><cc:attributionName>Caesar Schinas</cc:attributionName></cc:creator>
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
</rdf:RDF>
</metadata>
<style type="text/css">
:root, svg {
color-scheme: dark light;
}
circle {
fill: none;
stroke: currentColor;
stroke-width: 15;
}
path {
fill: none;
stroke: currentColor;
stroke-width: 25;
}
</style>
<g transform="translate(6,6)">
<path d="M58 168 v-98 a50 50 0 0 1 50-50 h20" />
<path d="M58 168 v-30 a50 50 0 0 1 50-50 h20" />
<circle cx="142" cy="20" r="18" />
<circle cx="142" cy="88" r="18" />
<circle cx="58" cy="180" r="18" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="124.48" height="203.92" version="1.1" viewBox="0 0 124.48 203.92" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x=".0051316" y="-.0039062" width="124.49" height="204" fill="none"/>
<path transform="translate(-58.01 -18.484)" d="m119.56 18.484-61.354 74.137 23.795 27.727-23.992 27.334 62.535 74.725 61.943-75.119-24.582-27.332 17.699-19.666-20.451-24.58-1.377-1.7695-0.01-2.3594 1.1894-4.3262 3.3438-4.3262-2.9512-2.5566-23.006 28.709-12.389-15.141-28.908 35.199-15.141-16.715 43.457-52.111 15.732 19.271 2.7539-3.5391-5.1133-5.5078-3.5391-5.7012-2.5566-5.3105 0.19532-4.5215 3.1465-4.918zm22.811 67.646 2.3613 0.19727 13.223 13.273-8.1113 9.7344-14.748-17.699zm-22.416 9.2422 21.236 24.975-20.844 24.385-21.041-24.777zm-29.105 35.789 29.105 35.594 29.889-35.396 14.158 16.322-43.852 52.896-43.852-52.109z" stroke="#000" stroke-width=".40441"/>
</svg>

Before

Width:  |  Height:  |  Size: 1,002 B

View file

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="Layer_1"
data-name="Layer 1"
viewBox="0 0 204.89999 204.89999"
version="1.1"
sodipodi:docname="Reddit_Icon_2Color.svg"
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
width="204.89999"
height="204.89999"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview11"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="2.3837233"
inkscape:cx="42.999958"
inkscape:cy="93.131617"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<defs
id="defs4">
<style
id="style2">
.cls-1 {
fill: #fff;
}
.cls-1, .cls-2 {
stroke-width: 0px;
}
.cls-2 {
fill: #ff4500;
}
</style>
</defs>
<g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="Layer 1"
style="fill:none;fill-opacity:1;stroke:none;stroke-opacity:1"
transform="translate(-25.54,-34.12)" />
<path
class="cls-1"
d="m 128.5,39.079997 c 2.22,9.41 10.67,16.42 20.76,16.42 11.78,0 21.33,-9.55 21.33,-21.33 0,-11.78 -9.55,-21.33 -21.33,-21.33 -10.3,0 -18.89,7.3 -20.89,17.01 -17.25,1.85 -30.720003,16.48 -30.720003,34.21 0,0.04 0,0.07 0,0.11 -18.76,0.79 -35.89,6.13 -49.49,14.56 -5.05,-3.91 -11.39,-6.24 -18.27,-6.24 -16.51,0 -29.8900000517578,13.38 -29.8900000517578,29.890003 0,11.98 7.0399999517578,22.3 17.2100000517578,27.07 0.99,34.7 38.8,62.61 85.310003,62.61 46.51,0 84.37,-27.94 85.31,-62.67 10.09,-4.8 17.07,-15.09 17.07,-27 0,-16.510003 -13.38,-29.890003 -29.89,-29.890003 -6.85,0 -13.16,2.31 -18.2,6.19 -13.72,-8.49 -31.04,-13.83 -49.99,-14.54 0,-0.03 0,-0.05 0,-0.08 0,-12.7 9.44,-23.24 21.68,-24.97 z M 46.959997,121.35 c 0.5,-10.84 7.7,-19.16 16.07,-19.16 8.37,0 14.77,8.79 14.27,19.63 -0.5,10.84 -6.75,14.78 -15.13,14.78 -8.38,0 -15.71,-4.41 -15.21,-15.25 z M 142.02,102.19 c 8.38,0 15.58,8.32 16.07,19.16 0.5,10.84 -6.84,15.25 -15.21,15.25 -8.37,0 -14.63,-3.93 -15.13,-14.78 -0.5,-10.84 5.89,-19.63 14.27,-19.63 z m -9.96,44.24 c 1.57,0.16 2.57,1.79 1.96,3.25 -5.15,12.31 -17.31,20.96 -31.5,20.96 -14.190003,0 -26.340003,-8.65 -31.500003,-20.96 -0.61,-1.46 0.39,-3.09 1.96,-3.25 9.2,-0.93 19.15,-1.44 29.540003,-1.44 10.39,0 20.33,0.51 29.54,1.44 z"
id="path8" />
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M2.149 0l-1.612 4.119v16.836h5.731v3.045h3.224l3.045-3.045h4.657l6.269-6.269v-14.686h-21.314zm19.164 13.612l-3.582 3.582h-5.731l-3.045 3.045v-3.045h-4.836v-15.045h17.194v11.463zm-3.582-7.343v6.262h-2.149v-6.262h2.149zm-5.731 0v6.262h-2.149v-6.262h2.149z" fill-rule="evenodd" clip-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 554 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

View file

@ -1,53 +0,0 @@
---
---
<div>
<p>
I'm a 24 year old software developer from Germany. Even if my roots are with Electrical Engineering,
I am currently pursuing a Masters Degree in Computer Science after starting to code more during my studies.
I am mostly programming in Python, but I'm also confident in writing Javascript.
</p>
<p>
I enjoy biking and hiking, as well as visiting different anime conventions.
I am a huge fan of the Fate franchise, specifically Fate/Grand Order, which I am playing since the end of 2019.
I also enjoy other games, mainly Honkai: Star Rail and theHunter: Call of the Wild.
</p>
</div>
<style>
div {
font-size: 16px;
font-weight: 400;
line-height: 24px;
font-family: 'Work Sans Variable', sans-serif;
max-width: min(87.5%, 360px);
background-color: var(--c-primary-background);
color: var(--c-primary-text);
border-radius: 1rem;
padding: 1rem 1rem;
margin-top: -0.75rem;
text-align: left;
}
div > p:first-of-type {
margin-top: 0px;
}
div > p:last-of-type {
margin-bottom: 0px;
}
@media (min-width: 512px) {
div {
max-width: 75%;
text-align: justify;
}
}
@media (min-width: 1000px) {
div {
max-width: 65%;
}
}
</style>

View file

@ -1,9 +1,8 @@
---
export interface Props {
url: string
slug: string
url: string | undefined
title: string
pubdate: Date
pubdate: string
description: string
author: string
}
@ -13,11 +12,11 @@ const options_date: Intl.DateTimeFormatOptions = {
month: 'long',
day: '2-digit',
}
const { author, description, pubdate, url, title, slug } = Astro.props
const { author, description, pubdate, url, title } = Astro.props
const date = new Date(pubdate).toLocaleDateString('en-GB', options_date)
---
<a href={`${url}/${slug}`} rel="noopener noreferrer">
<a href={url} rel="noopener noreferrer">
<div class="circle"></div>
<article>
<h2>{title}</h2>
@ -27,38 +26,59 @@ const date = new Date(pubdate).toLocaleDateString('en-GB', options_date)
</a>
<style>
* {
transition: all var(--a-time-default) var(--a-animation-1);
}
.circle {
display: none;
}
@media (min-width: 900px) {
.circle {
margin: 1rem 1rem 1rem 0rem;
position: relative;
display: flex;
visibility: visible;
height: 1.5rem;
width: 1.5rem;
border-radius: 40%;
background-color: var(--c-darkpurple);
transition: transform var(--speed) var(--ease);
}
a:hover > .circle {
height: 1.75rem;
width: 1.75rem;
translate: -0.125rem;
margin-right: 0.825rem;
}
article {
margin-left: 0.5rem;
}
}
a {
align-items: center;
justify-content: center;
display: flex;
text-decoration: none;
height: fit-content;
margin: 0px 0.5rem;
height: auto;
margin: 0.5rem;
width: 100%;
}
p {
color: var(--c-primary-text);
color: white;
text-align: left;
font-size: 1.1em;
margin: 0.5em;
}
article > h2 {
margin: 0.3rem 0.5rem;
color: var(--c-accent-1);
color: var(--c-darkpurple);
font-size: 1.5rem;
line-height: normal;
text-decoration: none;
}
article > h3 {
margin: 0.2em 0.5rem;
color: var(--c-primary-text);
color: white;
font-size: 1rem;
line-height: normal;
text-decoration: none;
@ -68,49 +88,17 @@ const date = new Date(pubdate).toLocaleDateString('en-GB', options_date)
flex: 1;
flex-wrap: wrap;
flex-direction: column;
align-items: center;
align-content: center;
align-items: flex-start;
align-content: flex-start;
justify-content: center;
background-color: var(--c-primary-background);
background-color: var(--c-darkergray);
padding: 10px;
text-align: center;
transition: transform var(--speed) var(--ease);
min-height: 100%;
border: 2px solid var(--c-primary-background);
border-radius: 1.25rem;
}
a:hover article {
border-color: var(--c-accent-1);
}
@media (min-width: 900px) {
.circle {
margin: 1rem 0.5rem 1rem 0.5rem;
position: relative;
display: flex;
visibility: visible;
height: 1rem;
width: 1rem;
background-color: var(--c-accent-1);
border-style: solid;
border-width: 0.25rem;
border-color: var(--c-secondary-background);
border-radius: 40%;
transition: all var(--a-time-short) var(--a-animation-1);
}
a:hover > .circle {
height: 1.25rem;
width: 1.25rem;
translate: -0.125rem;
margin-right: 4px;
}
article {
border: 2px solid var(--c-primary-background);
align-items: flex-start;
align-content: flex-start;
margin-left: 0.5rem;
}
a:hover > article {
transform: scaleY(102.5%) scaleX(101%);
}
</style>

View file

@ -1,8 +1,8 @@
---
import { Image } from 'astro:assets'
import mlb_ce from '@assets/ce/mlb.webp'
import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../../utils/tools'
import mlb_ce from '../assets/ce/mlb.webp'
import type { GlobImage } from '../types/generic'
import { plsLoadImage } from '../utils/tools'
export interface Props {
name: string
@ -28,10 +28,6 @@ const mlb_image = mlb ? 'mlbalign' : 'hidemlb'
</article>
<style>
* {
transition: all var(--a-time-default) var(--a-animation-1);
}
.hidemlb {
display: none;
height: 1em;
@ -39,12 +35,14 @@ const mlb_image = mlb ? 'mlbalign' : 'hidemlb'
article {
border-radius: 1.25rem;
border: 2px var(--c-primary-background) solid;
background-color: var(--c-primary-background);
background-color: var(--c-darkergray);
padding: 20px;
padding-top: 5px;
width: 35%;
height: auto;
justify-content: center;
text-align: center;
transition: transform var(--speed) var(--ease);
margin: 0px;
display: grid;
grid-template-columns: 100%;
@ -57,11 +55,11 @@ const mlb_image = mlb ? 'mlbalign' : 'hidemlb'
}
article:hover {
border: 2px var(--c-accent-1) solid;
transform: scale(var(--hover-scale));
}
article div {
margin: auto;
margin: 0.5em auto;
}
img {
@ -72,17 +70,27 @@ const mlb_image = mlb ? 'mlbalign' : 'hidemlb'
margin-right: auto;
}
.heading-center {
display: flex;
height: 4rem;
width: 100%;
align-items: center;
justify-content: center;
font-size: 1.25em;
color: white;
font-weight: bold;
}
.ce-crop {
width: min(85%, 85px);
height: auto;
width: 6em;
height: 6em;
}
.mlb {
width: min(85%, 85px);
width: 5.5rem;
height: auto;
margin-left: auto;
margin-right: auto;
margin-top: 0px;
}
.mlbalign {
@ -93,18 +101,18 @@ const mlb_image = mlb ? 'mlbalign' : 'hidemlb'
@media (min-width: 512px) {
.ce-crop {
width: 100px;
height: 100px;
width: 7.5em;
height: 7.5em;
}
article {
width: 128px;
width: 10em;
}
.mlbalign {
width: 85px;
width: 7.5em;
}
.mlb {
width: 85px;
width: 7rem;
}
}
</style>

View file

@ -1,7 +1,7 @@
---
import { Image } from 'astro:assets'
import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../../utils/tools'
import type { GlobImage } from '../types/generic'
import { plsLoadImage } from '../utils/tools'
export interface Props {
site: string
@ -10,6 +10,7 @@ export interface Props {
}
const { imageFile, link, site } = Astro.props
const logoAltText = `${site} Logo`
const imagePath = `/src/assets/social/${imageFile}`
const images_logos = import.meta.glob<GlobImage>(
'/src/assets/social/*.{png,webp}'
@ -24,67 +25,74 @@ const loadedLogoImage = plsLoadImage(images_logos, imagePath)
aria-label=`${site} - new window`
>
<article class="contact do-hover">
<Image src={loadedLogoImage} alt="" loading={'eager'} width={128} height={128} quality={100}/>
<Image src={loadedLogoImage} alt={logoAltText} />
<div>
<h2>{site}</h2>
</div>
</article>
<span class="visually-hidden">{site}</span>
<span class="visually-hidden">{logoAltText}</span>
</a>
<style>
a {
text-decoration: none;
--s-image: 80px;
}
article {
display: flex;
position: relative;
align-items: center;
justify-content: center;
text-align: center;
background-color: var(--c-primary-background);
border: 2px solid var(--c-primary-background);
--size-value: 6.25rem;
border-radius: 1.25rem;
padding: 6px;
display: flex;
justify-content: center;
align-items: center;
background-color: var(--c-darkergray);
border-color: var(--c-darkgray);
padding: 10px;
text-align: center;
transition: transform var(--speed) var(--ease);
height: auto;
width: auto;
position: relative;
}
article img {
border-radius: 1.25rem;
width: var(--s-image);
height: auto;
width: var(--size-value);
height: var(--size-value);
}
article:hover div {
border-radius: 1.25rem;
padding: 0 0.5rem;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
background-color: var(--c-darkgray);
height: calc(var(--size-value));
width: calc(var(--size-value) - 1rem);
opacity: 90%;
z-index: 100;
position: absolute;
}
article:hover h2 {
margin: 0;
display: inline-flex;
font-weight: bold;
color: white;
font-size: 18px;
}
article h2 {
position: absolute;
display: none;
}
article div {
display: none;
}
article:hover {
border-color: var(--c-accent-1);
}
article:hover div {
display: flex;
position: absolute;
margin: unset;
align-items: center;
justify-content: center;
text-align: center;
background-color: var(--c-primary-background);
border-radius: 1.25rem;
width: var(--s-image);
height: var(--s-image);
opacity: 90%;
z-index: 100;
}
article:hover h2 {
display: inline-flex;
font-size: 16px;
font-weight: 500;
color: var(--c-primary-text);
a:hover {
transform: scale(var(--hover-scale));
}
</style>

View file

@ -1,7 +1,7 @@
---
import { Image } from 'astro:assets'
import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../../utils/tools'
import type { GlobImage } from '../types/generic'
import { plsLoadImage } from '../utils/tools'
export interface Props {
name: string
@ -25,27 +25,21 @@ const loadedImage = plsLoadImage(images, imagePath)
aria-label=`${name} - new window`
>
<div class="heading">{name}</div>
<Image src={loadedImage} alt={name} loading={'eager'} width={128} height={128} quality={100}/>
<Image src={loadedImage} alt={name} />
<h2 class="subtext">
{origin}
</h2>
</a>
<style>
* {
transition: all var(--a-time-default) var(--a-animation-1);
}
.heading {
display: flex;
height: fit-content;
min-height: 2.5rem;
line-height: 1.75rem;
height: 4rem;
font-size: 24px;
color: var(--c-primary-text);
color: white;
max-width: 200px;
padding-bottom: 0.3rem;
font-weight: 500;
font-weight: bold;
margin: 0px;
justify-content: center;
align-items: center;
@ -56,25 +50,25 @@ const loadedImage = plsLoadImage(images, imagePath)
display: flex;
flex-wrap: wrap;
flex-direction: column;
background-color: var(--c-primary-background);
padding: 0em 0.25em;
width: max(40%, 128px);
background-color: var(--c-darkergray);
border-color: var(--c-darkgray);
padding: 0em 0.75em;
width: 40%;
height: auto;
justify-content: center;
align-items: center;
text-align: center;
transition: transform var(--speed) var(--ease);
text-decoration: none;
border: 2px var(--c-primary-background) solid;
&:hover {
border: 2px var(--c-accent-1) solid;
transform: scale(var(--hover-scale));
}
img {
width: min(90%, 100px);
margin: 0px 0.5rem;
padding: 0px 0.25em;
width: 90%;
height: auto;
border-radius: 1rem;
}
}
@ -84,16 +78,17 @@ const loadedImage = plsLoadImage(images, imagePath)
width: auto;
height: auto;
img {
width: 128px;
padding: 0px 1.5em;
width: 200px;
}
}
}
.subtext {
color: var(--c-primary-text);
color: white;
font-size: 16px;
font-weight: 400;
margin: 0.5rem;
font-weight: 600;
margin: 5;
line-height: 20px;
}
</style>

View file

@ -1,74 +1,27 @@
---
export interface Props {
fadeout?: boolean
}
const { fadeout } = Astro.props
const display = fadeout ? "": "display: none"
---
<div>
<span>
I am currently creating a site to catalogue past and future TAs for the whole community.
I am currently working on a site to catalogue past and future TAs.<br/>
Check it out at <a href="https://fgo-ta.com">fgo-ta.com</a>
</span>
<a href=`https://fgo-ta.com/` target="_blank" rel="noopener noreferrer"><span class="fancy">Visit fgo-ta.com &gt;&gt;</span></a>
<div class="fade" style={display}></div>
</div>
<style>
div {
display: flex;
width: 100%;
flex-wrap: nowrap;
flex-flow: column;
background-color: var(--c-primary-background);
height: 5em;
background-color: var(--c-gray);
text-align: center;
align-items: center;
justify-content: center;
color: var(--c-primary-text);
color: white;
font-size: 1.5em;
padding: 2rem 0rem 0rem 0rem;
font-weight: 400;
font-size: 1.3rem;
}
a {
font-weight: 500;
font-family: 'Work Sans Variable', sans-serif;
color: var(--c-primary-text);
margin: 1rem 0px 0px;
padding: 0.5rem 0.75rem;
color: var(--c-darkpurple);
text-decoration: none;
background: var(--c-primary-background);
border-radius: 10px;
border: 2px var(--c-accent-1) solid;
transition: all var(--a-time-default) var(--a-animation-1);
}
a:hover {
border-color: var(--c-accent-1-alt);
transition: all var(--a-time-default) var(--a-animation-1);
}
.fade {
margin-top: 3rem;
background: linear-gradient(to bottom, transparent, var(--c-secondary-background));
height: 2.5rem;
width: 100%;
}
span {
margin: 0 .5rem;
}
.fancy {
color: var(--c-accent-1);
}
@supports (background-clip: text) {
a:hover .fancy {
background: linear-gradient(125deg, var(--c-accent-1), var(--c-accent-1-alt), var(--c-accent-2) );
background-clip: text;
color: transparent;
}
}
</style>

View file

@ -12,11 +12,11 @@
display: flex;
width: 100%;
height: 5em;
background-color: var(--c-secondary-background);
background-color: var(--c-gray);
text-align: center;
align-items: center;
justify-content: center;
color: var(--c-primary-text);
color: white;
font-size: 1.5em;
}
</style>

View file

@ -1,50 +0,0 @@
---
import type { ImageMetadata } from 'astro'
export interface Props {
text: string
icon: ImageMetadata
link: string
}
const { text, icon, link } = Astro.props
const icon_src_url = `url("${icon.src}")`
---
<a href={link} target="_blank" rel="noopener noreferrer">
<div class="icon"></div>
<span class="visually-hidden">{text}</span>
</a>
<style define:vars={{ icon_src_url }}>
* {
transition: all var(--a-time-default) var(--a-animation-1);
}
a {
display: flex;
align-items: center;
justify-content: center;
width: 2.25em;
height: 2.25em;
background-color: var(--c-primary-background);
border-radius: .35rem;
border: 2px solid var(--c-primary-text);
}
a:hover {
border-color: var(--c-accent-1);
& .icon {
background: var(--c-accent-1);
}
}
.icon {
mask: var(--icon_src_url) no-repeat center;
mask-size: contain;
background-color: var(--c-primary-text);
height: 1.5em;
width: 1.5em;
}
</style>

View file

@ -1,29 +0,0 @@
---
import LinkCard from './linkCard.astro'
import socialData from '@content/data/socials.json'
import { socials } from './socials'
---
<div>
{
socialData.map((item) => (
<LinkCard
{...{ icon: socials[item.icon], text: item.icon, link: item.link }}
/>
))
}
</div>
<style>
div {
margin-top: 0.75rem;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
width: 95%;
height: auto;
column-gap: 0.5rem;
row-gap: 0.5rem;
}
</style>

View file

@ -1,22 +0,0 @@
import discord from '@assets/custom-svg/discord.svg'
import forgejo from '@assets/custom-svg/forgejo.svg'
import rayshift from '@assets/custom-svg/rayshift.svg'
import reddit from '@assets/custom-svg/reddit.svg'
import twitch from '@assets/custom-svg/twitch.svg'
import type { ImageMetadata } from 'astro'
import mastodon from 'iconoir/icons/mastodon.svg'
import twitter from 'iconoir/icons/twitter.svg'
import youtube from 'iconoir/icons/youtube.svg'
export const socials: Record<string, ImageMetadata> = {
forgejo,
rayshift,
reddit,
twitch,
discord,
mastodon,
twitter,
youtube,
}

137
src/components/navbar.astro Normal file
View file

@ -0,0 +1,137 @@
---
import { Image } from 'astro:assets';
import logo from '../assets/logo.svg'
import hamburger from 'iconoir/icons/menu.svg'
const hamburger_src_url = `url("${hamburger.src}")`;
---
<header>
<a href="/" rel="noopener noreferrer" aria-label="Home" role="navigation">
<Image src={logo} alt="Firq Website Logo"/>
<span class="visually-hidden">Firq Website Logo</span>
</a>
<ul class="desktop">
<slot name="desktop"/>
</ul>
<button class="mobile" aria-label="Navigation Button" tabindex="0" onclick="this.focus()" role="navigation">
<ul>
<slot name="mobile"/>
</ul>
<div class="placeholder"></div>
<div class="hamburger-menu" role="navigation"></div>
</button>
</header>
<style define:vars={{ hamburger_src_url }}>
header {
z-index: 1000;
position: sticky;
top: 0px;
background-color: var(--c-darkgray);
display: flex;
height: auto;
width: 100%;
align-items: flex-start;
line-height: 1.5em;
}
header > a {
margin-left: 16px;
padding-top: 8px;
display: block;
height: 48px;
width: 48px;
}
a > img {
height: 100%;
width: 100%;
object-fit: contain;
}
.desktop {
align-items: center;
justify-content: space-around;
display: none;
flex-wrap: wrap;
flex-direction: row;
height: 64px;
width: 100%;
list-style-type: none;
row-gap: 0.5em;
column-gap: 0.5ch;
margin: 0px;
line-height: 1.5em;
}
.mobile > ul {
background-color: var(--c-darkgray);
align-items: center;
flex-wrap: wrap;
flex-direction: column;
display: flex;
width: 100%;
list-style-type: none;
line-height: 3em;
}
.placeholder {
display: flex;
width: 100%;
}
.mobile {
display: flex;
background-color: var(--c-darkgray);
border: 0px;
width: 100%;
height: 64px;
}
.mobile > ul {
display: none;
padding: 0px;
}
.mobile:focus-within > ul {
display: flex;
}
.mobile:focus-within > .placeholder {
display: none;
}
.mobile:focus-within {
justify-content: top;
height: auto;
}
header:focus-within > a {
display: flex;
justify-self: top;
}
.hamburger-menu {
mask: var(--hamburger_src_url) no-repeat center;
background-color: white;
width: 2rem;
height: 2rem;
position: static;
align-self: flex-start;
margin-right: 1rem;
margin-top: 1rem;
}
@media (min-width: 1140px) {
.mobile {
display: none;
}
.desktop {
display: flex;
}
header {
height: 64px;
align-items: center;
}
header > a {
padding-top: 0px;
}
}
</style>

View file

@ -1,37 +0,0 @@
---
import NavbarDesktop from './navbarDesktop.astro'
import NavbarLogo from './navbarLogo.astro'
import NavbarMobile from './navbarMobile.astro'
---
<header>
<NavbarLogo/>
<NavbarDesktop>
<slot name="desktop" />
</NavbarDesktop>
<NavbarMobile>
<slot name="mobile" />
</NavbarMobile>
</header>
<style>
header {
z-index: 1000;
position: sticky;
top: 0px;
background-color: var(--c-primary-background);
display: flex;
height: auto;
width: 100%;
align-items: flex-start;
line-height: 1.5em;
border-bottom: 2px solid var(--c-accent-1) ;
}
@media (min-width: 1140px) {
header {
height: 64px;
align-items: center;
}
}
</style>

View file

@ -1,29 +0,0 @@
---
---
<ul>
<slot />
</ul>
<style>
ul {
align-items: center;
justify-content: space-around;
display: none;
flex-wrap: wrap;
flex-direction: row;
height: 64px;
width: 100%;
list-style-type: none;
row-gap: 0.5em;
column-gap: 0.5ch;
margin: 0px;
line-height: 1.5em;
}
@media (min-width: 1140px) {
ul {
display: flex;
}
}
</style>

View file

@ -1,32 +0,0 @@
---
import { Image } from 'astro:assets'
import logo from '@assets/logo.svg'
---
<a href="/" rel="noopener noreferrer" aria-label="Home" role="button">
<Image src={logo} alt="" loading="eager" />
<span class="visually-hidden">Logo</span>
</a>
<style>
a {
margin-left: 16px;
padding-top: 8px;
height: 48px;
width: 48px;
display: flex;
justify-self: top;
align-items: center;
}
a > img {
height: 42px;
width: 42px;
object-fit: contain;
}
@media (min-width: 1140px) {
a {
padding-top: 0px;
}
}
</style>

View file

@ -1,85 +0,0 @@
---
import hamburger from 'iconoir/icons/menu.svg'
const hamburger_src_url = `url("${hamburger.src}")`
---
<div class="dropdown">
<input type="checkbox" id="dropdown" />
<ul class="dropdown-content">
<slot />
</ul>
<label for="dropdown" class="dropdown-btn" aria-label="Menu Toggle">
<div class="hamburger-menu" role="navigation"></div>
</label>
</div>
<script>
const dropdownBtn = document.querySelector(".dropdown-btn")!;
const dropdownContent = document.querySelector(".dropdown-content")!;
dropdownBtn.addEventListener("click", () => {
dropdownContent.classList.toggle("menu-open");
});
</script>
<style define:vars={{ hamburger_src_url }}>
input[type="checkbox"] {
opacity: 0;
position: absolute;
touch-action: manipulation;
}
.dropdown-content.menu-open {
display: flex;
height: auto;
transform: translateY(0);
transition: transform var(--a-time-default) var(--a-animation-1);
}
.dropdown-content {
display: none;
flex-wrap: wrap;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: var(--c-primary-background);
width: 100%;
list-style-type: none;
line-height: 3em;
margin: 0.5rem 0px 0px;
padding: 0;
transform: translateY(-1em);
transition: transform var(--a-time-default) var(--a-animation-1);
}
.dropdown-btn {
height: 64px;
display:flex;
align-items: center;
justify-content: center;
touch-action: manipulation;
}
.dropdown {
display: flex;
justify-content: flex-end;
background-color: var(--c-primary-background);
border: 0px;
width: 100%;
}
.hamburger-menu {
mask: var(--hamburger_src_url) no-repeat center;
mask-size: cover;
background-color: var(--c-primary-text);
width: 2.25rem;
height: 2.25rem;
margin-right: 10px;
}
@media (min-width: 1140px) {
.dropdown {
display: none;
}
}
</style>

View file

@ -1,7 +1,7 @@
---
export interface Props {
currentPage?: string
navtype: 'mobile' | 'desktop'
navtype: "mobile" | "desktop"
link: string
text: string
icon: ImageMetadata
@ -18,10 +18,10 @@ if (currentPage === slug) {
currPage = 'current'
}
const icon_src_url = `url("${icon.src}")`
const icon_src_url = `url("${icon.src}")`;
const fulllink = `/${slug}`
let extraattributes = navtype === 'mobile' ? { tabindex: '0' } : {}
let extraattributes = navtype === "mobile" ? { tabindex: "0"} : {}
---
<li>
@ -30,7 +30,7 @@ let extraattributes = navtype === 'mobile' ? { tabindex: '0' } : {}
rel="noopener noreferrer"
aria-label={text}
class={currPage}
role="button"
role="navigation"
{...extraattributes}
>
<div class="icon"></div>
@ -39,9 +39,6 @@ let extraattributes = navtype === 'mobile' ? { tabindex: '0' } : {}
</li>
<style define:vars={{ icon_src_url }}>
* {
transition: all var(--a-time-default) var(--a-animation-1);
}
li {
align-items: center;
justify-content: center;
@ -52,7 +49,7 @@ let extraattributes = navtype === 'mobile' ? { tabindex: '0' } : {}
li > a {
display: inline-flex;
color: var(--c-primary-text);
color: white;
text-decoration: none;
justify-content: center;
align-items: center;
@ -63,24 +60,24 @@ let extraattributes = navtype === 'mobile' ? { tabindex: '0' } : {}
}
li > a:hover {
color: var(--c-accent-1-alt) !important;
color: var(--c-purplepink);
}
li > a:hover > .icon {
background-color: var(--c-accent-1-alt) !important;
background-color: var(--c-purplepink);
}
.current {
color: var(--c-accent-1) !important;
color: var(--c-darkpurple) !important;
}
.current > .icon {
background-color: var(--c-accent-1) !important;
background-color: var(--c-darkpurple) !important;
}
.icon {
mask: var(--icon_src_url) no-repeat center;
background-color: var(--c-primary-text);
background-color: white;
width: 1.4em;
height: 1.4em;
}

View file

@ -1,7 +1,7 @@
---
import { Image } from 'astro:assets';
import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../../utils/tools'
import type { GlobImage } from '../types/generic'
import { plsLoadImage } from '../utils/tools'
export interface Props {
name: string
@ -12,10 +12,9 @@ export interface Props {
bondceImageFile: string
ml: string
bond10: boolean
index: number
}
const { bond10, ml, bondceImageFile, servantImageFile, np, skills, level, name, index } = Astro.props
const { bond10, ml, bondceImageFile, servantImageFile, np, skills, level, name } = Astro.props
const servantImagePath = `/src/assets/servant/${servantImageFile}`
const bondceImagePath = `/src/assets/ce/bond-ce/${bondceImageFile}`
const images_servants = import.meta.glob<GlobImage>('/src/assets/servant/*.{png,webp}')
@ -28,12 +27,10 @@ let bondce_css: string = 'bond-ce'
if (bond10 === false) {
bondce_css += ' unobtained'
}
let loading: "eager" | "lazy" = index <= 3 ? "eager" : "lazy";
---
<article>
<Image src={loadedServantImage} width={128} height={128} alt={name} quality={100} loading={loading}/>
<Image src={loadedServantImage} alt={name} />
<h2 class="subtext">
Level {level}<br />
{skills}<br />
@ -46,35 +43,54 @@ let loading: "eager" | "lazy" = index <= 3 ? "eager" : "lazy";
</article>
<style>
.heading {
display: flex;
height: 4rem;
width: 100%;
align-items: center;
justify-content: center;
font-size: 24px;
color: white;
max-width: 200px;
padding-bottom: 0.3rem;
font-weight: bold;
}
.servants-container {
row-gap: 1em;
column-gap: 1em;
justify-content: center;
align-self: center;
}
article:hover {
transition: all var(--a-time-default) var(--a-animation-1);
transform: scale(1);
border-color: var(--c-accent-1);
transform: scale(var(--hover-scale));
}
article {
display: flex;
flex-wrap: wrap;
flex-direction: column;
background-color: var(--c-primary-background);
border: 2px var(--c-primary-background) solid;
padding: 10px;
width: max(30%, 100px);
background-color: var(--c-darkergray);
border-color: var(--c-darkgray);
padding: 0em 0.75em 0.5rem 0.75em;
width: 40%;
height: auto;
justify-content: center;
align-items: center;
text-align: center;
transition: transform var(--speed) var(--ease);
border-radius: 1.25rem;
}
article > img {
width: 90%;
height: auto;
width: 7.5rem;
height: 7.5rem;
border-radius: 2.5rem;
margin-top: 0.75rem;
}
.subtext {
color: var(--c-primary-text);
color: white;
font-size: 16px;
font-weight: 600;
margin: 5;
@ -82,26 +98,25 @@ let loading: "eager" | "lazy" = index <= 3 ? "eager" : "lazy";
}
.expand-on-hover {
background-color: var(--c-primary-background);
border: 2px var(--c-primary-background) solid;
border-top: 0px;
background-color: var(--c-duskgray);
z-index: 99;
transform: scaleY(0);
transform-origin: top;
position: absolute;
top: 92.5%;
left: 0px;
right: 0px;
border-radius: 0px 0px 1.25rem 1.25rem;
width: 100%;
}
article:hover .expand-on-hover {
transform: scaleY(1);
border-color: var(--c-accent-1);
transition: all var(--a-time-default) var(--a-animation-1);
transition: transform 200ms ease-in-out;
background-color: var(--c-duskgray);
}
.bond-ce {
padding-top: 0.25rem;
padding-top: 0.75rem;
width: auto;
height: 3rem;
}
@ -118,12 +133,16 @@ let loading: "eager" | "lazy" = index <= 3 ? "eager" : "lazy";
}
article > img {
width: 128px;
height: 128px;
width: 200px;
height: 200px;
}
.bond-ce {
height: 3rem;
height: 3.5rem;
}
.expand-on-hover {
top: 95%;
}
}
</style>

View file

@ -1,7 +1,7 @@
---
import { Image } from 'astro:assets'
import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../../utils/tools'
import type { GlobImage } from '../types/generic'
import { plsLoadImage } from '../utils/tools'
export interface Props {
date: string
@ -36,131 +36,153 @@ const servant_images = import.meta.glob<GlobImage>(
const loadedServantImage = plsLoadImage(servant_images, servantImagePath)
const loadedTargetImage = plsLoadImage(target_images, targetImagePath)
const hasuser = user !== undefined ? 'display: flex' : 'display: none'
let hasuser = ''
if (user !== undefined) {
hasuser = 'hasuser'
}
---
<a href={link} target="_blank" rel="noopener noreferrer" aria-label={title}>
<div class="imagecontainer">
<Image src={loadedTargetImage} alt={title} />
<article>
<Image src={loadedTargetImage} alt={title} class="icon" />
<div class="title">
<h2>{title}</h2>
</div>
</div>
<p>
<span style={hasuser}>By {user}<br />•</span>
{formatted_date}
</p>
<div class="expand-on-hover">
<Image src={loadedServantImage} alt="" />
<h2>{turns}</h2>
</div>
<p>
<span class={hasuser}>
By {user}<br /> •
</span>
{formatted_date}
</p>
<div class="expand-on-hover">
<Image src={loadedServantImage} alt="" />
<h2>{turns}</h2>
</div>
</article>
</a>
<style>
* {
transition: all var(--a-time-default) var(--a-animation-1);
div {
display: none;
}
span {
display: none;
}
.hasuser {
display: flex;
}
a {
text-decoration: none;
display: flex;
flex-direction: column;
flex-wrap: wrap;
background-color: var(--c-primary-background);
border: 2px var(--c-primary-background) solid;
}
article {
background-color: var(--c-darkergray);
border-color: var(--c-darkgray);
padding: 10px;
text-align: center;
width: max(30%, 100px);
transition: transform var(--speed) var(--ease);
height: auto;
width: auto;
max-width: 8rem;
border-radius: 1.25rem;
padding-bottom: 1.5rem;
--size-value: 7rem;
display: flex;
justify-content: center;
align-items: center;
z-index: 1;
flex-direction: column;
}
a:hover {
transform: scale(1);
border-color: var(--c-accent-1);
z-index: 10;
article:hover {
transform: scale(var(--hover-scale));
}
.imagecontainer {
display: flex;
width: 90%;
height: auto;
position: relative;
}
.imagecontainer > img {
width: 100%;
height: auto;
article > .icon {
border-radius: 1.25rem;
width: var(--size-value);
height: var(--size-value);
margin: 0.5rem;
}
a:hover .title {
article:hover .title {
display: flex;
position: absolute;
align-items: center;
justify-content: center;
text-align: center;
background-color: var(--c-primary-background);
width: 100%;
height: 100%;
background-color: var(--c-darkgray);
height: calc(var(--size-value) + 0.1rem);
width: calc(var(--size-value) + 0.1rem);
opacity: 90%;
box-shadow: 0px 0px 0px 1px var(--c-primary-background);
border-radius: 1.25rem;
top: 1.1em;
}
a:hover .title h2 {
margin: 4px;
article:hover .title h2 {
margin: 0;
display: inline-flex;
font-weight: 500;
color: var(--c-primary-text);
font-size: 1rem;
font-weight: bold;
color: white;
font-size: 18px;
line-height: 150%;
padding: 0.5rem;
}
a .title {
article .title h2 {
display: none;
}
article .title {
display: none;
}
.icon {
display: flex;
justify-content: center;
align-items: center;
}
p {
display: flex;
flex-wrap: wrap;
flex-direction: column;
text-align: center;
justify-content: center;
align-items: center;
line-height: 100%;
text-decoration: none;
color: var(--c-primary-text);
color: white;
font-size: 1rem;
font-weight: 400;
margin: 0.5rem 0px 0.625rem 0px;
font-weight: bold;
padding-top: 0.5rem;
margin: 0.5rem 0px;
flex-wrap: wrap;
flex-direction: column;
}
.expand-on-hover {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: top;
align-items: center;
justify-content: space-evenly;
background-color: var(--c-primary-background);
border: 2px var(--c-primary-background) solid;
border-top: 0px;
background-color: var(--c-duskgray);
z-index: 99;
transform: scaleY(0);
transform-origin: top;
position: absolute;
top: 87.5%;
padding-top: 0.5rem;
margin-top: 0.2rem;
color: var(--c-primary-text);
top: 90%;
left: 0px;
right: 0px;
color: white;
border-radius: 0px 0px 1.25rem 1.25rem;
width: 100%;
}
.expand-on-hover img {
width: 2.5rem;
height: auto;
width: 3rem;
height: 3rem;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
border-radius: 0.5rem;
}
@ -169,23 +191,9 @@ const hasuser = user !== undefined ? 'display: flex' : 'display: none'
margin: 0.5rem;
}
a:hover .expand-on-hover {
article:hover .expand-on-hover {
transform: scaleY(1);
transition: all var(--a-time-default) var(--a-animation-1);
background-color: var(--c-primary-background);
border-color: var(--c-accent-1);
}
@media (min-width: 512px) {
a {
padding: 10px;
width: auto;
height: auto;
}
a > .imagecontainer {
width: 112px;
height: 112px;
}
transition: transform 200ms ease-in-out;
background-color: var(--c-duskgray);
}
</style>

View file

@ -1,7 +1,7 @@
---
import { Image } from 'astro:assets'
import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../../utils/tools'
import type { GlobImage } from '../types/generic'
import { plsLoadImage } from '../utils/tools'
export interface Props {
title: string
@ -10,6 +10,7 @@ export interface Props {
}
const { imageFile, link, title } = Astro.props
const logoAltText = `${title} Logo`
const imagePath = `/src/assets/technologies/${imageFile}`
const images_logos = import.meta.glob<GlobImage>(
'/src/assets/technologies/*.{png,webp}'
@ -19,70 +20,73 @@ const loadedImage = plsLoadImage(images_logos, imagePath)
<a href={link} target="_blank" rel="noopener noreferrer" aria-label={title}>
<article>
<Image src={loadedImage} alt="" loading={'eager'} width={150} height={150} quality={100}/>
<Image src={loadedImage} alt={logoAltText} />
<div>
<h2>{title}</h2>
</div>
</article>
<span class="visually-hidden">{title}</span>
<span class="visually-hidden">{logoAltText}</span>
</a>
<style>
* {
transition: all var(--a-time-default) var(--a-animation-1);
}
a {
text-decoration: none;
}
article {
--size-value: 6.25rem;
background-color: var(--c-darkergray);
border-color: var(--c-darkgray);
padding: 10px;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
transition: transform var(--speed) var(--ease);
height: auto;
width: auto;
line-height: 100px;
border-radius: 1.25rem;
position: relative;
}
article:hover {
transform: scale(var(--hover-scale));
}
article > img {
border-radius: 1.25rem;
width: var(--size-value);
height: var(--size-value);
}
article:hover div {
border-radius: 1.25rem;
padding: 0 0.5rem;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
background-color: var(--c-primary-background);
border: 2px solid var(--c-primary-background);
border-radius: 1.25rem;
padding: 6px;
height: auto;
width: auto;
background-color: var(--c-darkgray);
height: calc(var(--size-value));
width: calc(var(--size-value) - 1rem);
opacity: 90%;
z-index: 100;
position: absolute;
}
article img {
border-radius: 1.25rem;
width: 80px;
height: auto;
article:hover h2 {
margin: 0;
position: absolute;
display: inline-flex;
font-weight: bold;
color: white;
font-size: 18px;
line-height: 150%;
}
article h2 {
display: none;
}
article div {
display: none;
}
article:hover {
border-color: var(--c-accent-1);
}
article:hover div {
display: flex;
position: absolute;
margin: unset;
align-items: center;
justify-content: center;
text-align: center;
background-color: var(--c-primary-background);
border-radius: 1.25rem;
width: 80px;
height: 80px;
opacity: 90%;
z-index: 100;
}
article:hover h2 {
display: inline-flex;
font-size: 16px;
font-weight: 500;
color: var(--c-primary-text);
}
</style>

View file

@ -1,106 +0,0 @@
---
export interface Props {
maintext: string
subtext: string
fadeout?: boolean
baseurl?: string
returnbutton?: boolean
}
const { maintext, subtext, fadeout, baseurl, returnbutton } = Astro.props
const displayFadeout = fadeout ? "": "display: none"
const displayBackButton = returnbutton ? "": "display: none"
---
<div class="wrap">
<div class="head">{maintext}</div>
<div class="sub">{subtext}</div>
<a href=`/${baseurl}` style={displayBackButton}>&lt;&lt; Back to {baseurl}</a>
<div class="fade" style={displayFadeout}></div>
</div>
<style>
a {
font-weight: 500;
font-family: 'Work Sans Variable', sans-serif;
color: var(--c-primary-text);
margin: 1rem 0px 0px;
padding: 0.5rem 0.75rem;
text-decoration: none;
background-color: var(--c-secondary-background);
border-radius: 10px;
border-style: solid;
border-width: 2px;
border-color: var(--c-secondary-background);
text-transform: capitalize;
}
a:hover {
border-color: var(--c-accent-1);
}
.wrap {
position: relative;
width: 100%;
display: flex;
text-align: center;
align-items: center;
flex-wrap: wrap;
flex-direction: column;
color: var(--c-primary-text);
background-color: var(--c-primary-background);
}
.fade {
margin-top: 2rem;
background: linear-gradient(to bottom, transparent, var(--c-secondary-background));
height: 2.5rem;
width: 100%;
}
.head {
margin: 0 .5rem;
hyphens: auto;
padding-top: 2rem;
font-size: 3.25rem;
font-weight: 700;
font-family: 'Work Sans Variable', sans-serif;
}
.sub {
margin: 0 .5rem;
font-size: 0.9rem;
font-weight: 500;
font-family: 'Work Sans Variable', sans-serif;
}
.head {
color: var(--c-accent-1);
}
@supports (background-clip: text) {
.head {
background: linear-gradient(125deg, var(--c-accent-1), var(--c-accent-1-alt), var(--c-accent-2) );
background-clip: text;
color: transparent;
}
}
@media (min-width: 620px) {
.head {
hyphens: none;
font-size: 3.75rem;
}
.sub {
font-size: 1rem;
}
}
@media (min-width: 1000px) {
.head {
font-size: 4rem;
}
.sub {
font-size: 1.2rem;
}
}
</style>

View file

@ -1,76 +0,0 @@
---
import LinkContainer from "../links/linkContainer.astro";
---
<div class="wrap">
<div class="head">Hi, I'm <span class="fancy">Firq</span></div>
<div class="sub">&lt;/ Software dev / Scathach enthusiast / Germany /&gt;</div>
<LinkContainer />
<div class="fade"></div>
</div>
<style>
.wrap {
position: relative;
width: 100%;
display: flex;
text-align: center;
align-items: center;
flex-wrap: wrap;
flex-direction: column;
color: var(--c-primary-text);
background-color: var(--c-primary-background);
}
.fade {
margin-top: 1.5rem;
background: linear-gradient(to bottom, transparent, var(--c-secondary-background));
height: 2.5rem;
width: 100%;
}
.head {
padding-top: 2rem;
font-size: 3rem;
font-weight: 700;
font-family: 'Work Sans Variable', sans-serif;
}
.sub {
font-size: 1rem;
font-weight: 400;
font-family: 'Work Sans Variable', sans-serif;
width: 97.5%;
}
.fancy {
color: var(--c-accent-1);
}
@supports (background-clip: text) {
.fancy {
background: linear-gradient(125deg, var(--c-accent-1), var(--c-accent-1-alt), var(--c-accent-2) );
background-clip: text;
color: transparent;
}
}
@media (min-width: 620px) {
.head {
font-size: 3rem;
}
.sub {
font-size: 1rem;
}
}
@media (min-width: 1000px) {
.head {
font-size: 4rem;
}
.sub {
font-size: 1.25rem;
}
}
</style>

View file

@ -44,7 +44,7 @@ const { id, thumbnail } = Astro.props
.warningtext {
display: flex;
justify-content: center;
background-color: var(--c-primary-background);
background-color: var(--c-darkgray);
width: 640px;
height: 360px;
}

View file

@ -1,16 +0,0 @@
import { z, defineCollection } from 'astro:content'
const blogCollection = defineCollection({
type: 'content', // v2.5.0 and later
schema: z.object({
title: z.string(),
tags: z.array(z.string()),
pubDate: z.date(),
description: z.string(),
author: z.string(),
}),
})
export const collections = {
blog: blogCollection,
}

View file

@ -1,42 +0,0 @@
[
{
"link": "https://www.youtube.com/@Firq_",
"icon": "youtube",
"text": "Youtube"
},
{
"link": "https://mastodon.neshweb.net/@Firq",
"icon": "mastodon",
"text": "Mastodon"
},
{
"link": "https://twitter.com/firq_ow",
"icon": "twitter",
"text": "Twitter"
},
{
"link": "https://twitch.tv/Firq",
"icon": "twitch",
"text": "Twitch"
},
{
"link": "https://discord.com/users/186014064835690496",
"icon": "discord",
"text": "Discord"
},
{
"link": "https://www.reddit.com/user/Firq_ow/",
"icon": "reddit",
"text": "Reddit"
},
{
"link": "https://forgejo.neshweb.net/Firq",
"icon": "forgejo",
"text": "Forgejo"
},
{
"link": "https://rayshift.io/na/firq",
"icon": "rayshift",
"text": "Rayshift"
}
]

1
src/env.d.ts vendored
View file

@ -1,2 +1 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />

View file

@ -1,12 +1,8 @@
---
import '@fontsource-variable/work-sans'
import workSans from '@fontsource-variable/work-sans/files/work-sans-latin-wght-normal.woff2'
import Navbar from '@components/navbar/navbar.astro'
import NavbarEntry from '@components/navbar/navbarEntry.astro'
import navdata from '@content/data/navdata.json'
import embed from '@assets/embed.png'
import favicon from '@assets/favicon.ico'
import Navbar from '../components/navbar.astro'
import NavbarEntry from '../components/navbarEntry.astro'
import navdata from '../../static/data/_navdata.json'
import embed from '../assets/embed.png'
import home from 'iconoir/icons/home.svg'
import servants from 'iconoir/icons/task-list.svg'
@ -72,17 +68,8 @@ const mapped_navdata = navdata.map((item) => ({
name="google-site-verification"
content="SmcWcewh7DCANcLeTe3ntU0R-LESbo_bsolICJnmulE"
/>
<!-- Disable DarkReader, as site is already in dark mode -->
<meta name="darkreader-lock" content="this site only has darkmode" />
<!-- Links -->
<link
rel="preload"
as="font"
crossorigin="anonymous"
href={workSans}
type="font/woff2"
/>
<link rel="icon" type="image/ico" href={favicon} />
<link rel="icon" type="image/ico" href="/favicon.ico" />
<link rel="sitemap" href="/sitemap-index.xml" />
<link href="https://mastodon.neshweb.net/@Firq" rel="me" />
</head>
@ -90,64 +77,34 @@ const mapped_navdata = navdata.map((item) => ({
<Navbar>
{
mapped_navdata.map((item) => (
<NavbarEntry
currentPage={currentpage}
navtype="desktop"
{...item}
slot="desktop"
/>
<NavbarEntry currentPage={currentpage} navtype="desktop" {...item} slot="desktop"/>
))
}
{
mapped_navdata.map((item) => (
<NavbarEntry
currentPage={currentpage}
navtype="mobile"
{...item}
slot="mobile"
/>
<NavbarEntry currentPage={currentpage} navtype="mobile" {...item} slot="mobile"/>
))
}
</Navbar>
<slot />
</body>
</html>
<style is:global>
:root {
/* Animations */
--a-time-default: 200ms;
--a-time-short: 100ms;
--a-time-slow: 1000ms;
--a-animation-1: ease-in-out;
/* Fonts */
--f-default: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
--f-title: 'Work Sans Variable', sans-serif;
font-family: var(--f-default);
/* Colors */
--c-primary-background: #1b1b1b;
--c-secondary-background: #333;
--c-primary-text: #eee;
--c-accent-1: #b86cff;
--c-accent-1-alt: #c105ff;
--c-accent-2: #ff0077;
--c-rgb-primary-background: 27, 27, 27;
--c-rgb-secondary-background: 51, 51, 51;
--c-rgb-primary-text: 238, 238, 238;
--c-rgb-accent-1: 184, 108, 255;
--c-rgb-accent-1-alt: 193, 5, 255;
--c-rgb-accent-2: 255, 0, 119;
/* Scrollbar */
scrollbar-color: var(--c-secondary-background) var(--c-primary-background);
--hover-scale: 1.05;
--speed: 50%;
--ease: 50%;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
--c-darkgray: #1e1e1e;
--c-duskgray: #242424;
--c-gray: #2e2e2e;
--c-lightgray: #3e3e3e;
--c-darkpurple: #b86cff;
--c-purplepink: #c105ff;
--c-darkergray: #1b1b1b;
}
body {
background: var(--c-secondary-background);
background: var(--c-lightgray);
margin: 0px;
}
@ -160,5 +117,5 @@ const mapped_navdata = navdata.map((item) => ({
padding: 0;
position: absolute;
width: 1px;
}
}
</style>

View file

@ -0,0 +1,74 @@
---
export interface Props {
title: string
}
const { title } = Astro.props
---
<section class="base">
<h1>{title}</h1>
<div>
<slot />
</div>
</section>
<style>
h1 {
font-size: 40px;
line-height: 48px;
letter-spacing: -1px;
color: white;
font-size: 2.25rem;
margin-top: 1rem;
margin-bottom: 0;
margin-left: auto;
margin-right: auto;
padding: 0.25rem 0.75rem;
max-width: max-content;
background-color: var(--c-darkgray);
padding: 0.25rem 1.5rem;
border-radius: 0.5rem;
padding-bottom: 0.5rem;
}
div {
row-gap: 1em;
column-gap: 1em;
justify-content: center;
align-self: center;
display: flex;
flex-flow: row wrap;
padding: 1em;
color: white;
font-size: 1em;
}
.base {
margin-left: 1rem;
margin-right: 1rem;
}
@media (min-width: 400px) {
.base {
margin-left: 3rem;
margin-right: 3rem;
}
}
@media (min-width: 1500px) {
.base {
margin-left: 10%;
margin-right: 10%;
}
}
@media (min-width: 512px) {
div {
justify-content: left;
}
}
@media (min-width: 520px) {
h1 {
margin: 0.5rem 0.75rem 0.5rem 0.75rem;
}
}
</style>

View file

@ -30,23 +30,33 @@ const { title } = Astro.props
padding: 1em;
position: relative;
}
h1 {
div h1 {
font-size: 40px;
line-height: 48px;
letter-spacing: -1px;
color: var(--c-primary-text);
margin: 0 auto 0px;
padding: 0.25rem 1.5rem 0.5rem;
color: white;
margin-top: 2rem;
margin-bottom: 0px;
margin-left: auto;
margin-right: auto;
padding: 0.25rem 1.5rem;
border-radius: 0.5rem;
max-width: max-content;
&:after {
content:' ';
display: block;
width: 65%;
height: 3px;
margin: auto;
background-color: var(--c-accent-1);
background-color: var(--c-darkgray);
padding-bottom: 0.5rem;
}
@media (min-width: 512px) {
div {
row-gap: 1.5em;
column-gap: 1.5em;
}
}
.base {
margin-left: 1rem;
margin-right: 1rem;
}
@media (min-width: 1000px) {
.base {
margin-left: 3rem;

View file

@ -1,5 +1,4 @@
---
import SmallTitle from '@components/titles/smallTitle.astro'
import Layout from './Layout.astro'
const { frontmatter } = Astro.props
@ -14,90 +13,108 @@ const date = new Date(frontmatter.pubDate).toLocaleDateString(
'en-GB',
options_date
)
const subtext = `Written by ${frontmatter.author} • Published on ${date}`
---
<Layout title={title} currentpage="blog" descriptionOverride={description}>
<SmallTitle maintext={frontmatter.title} subtext={subtext} fadeout={true} returnbutton={true} baseurl='blog'/>
<article>
<slot />
</article>
<a href="/blog"><i class="iconoir-fast-arrow-left"></i>Back to all posts</a>
<div>
<h1>
{frontmatter.title}
</h1>
<p>by {frontmatter.author} • Published on {date}</p>
<article>
<slot />
</article>
</div>
</Layout>
<style>
article {
color: var(--c-primary-text);
margin: 0.5rem 3rem 0.5rem 3rem;
font-size: 1.1em;
text-align: justify;
padding-bottom: 5rem;
a {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
text-align: center;
color: white;
background-color: var(--c-gray);
padding: 0.5rem 0px;
margin-bottom: 2rem;
text-decoration: none;
}
article :global(h2) {
font-size: 32px;
word-wrap: normal;
color: var(--c-primary-text);
h1 {
font-size: 34px;
line-height: 40px;
letter-spacing: -1px;
color: white;
margin: 0.5rem 3rem 0.5rem 3rem;
padding: 0.25rem 0.75rem;
max-width: max-content;
background-color: var(--c-darkgray);
padding: 0.25rem 1rem;
border-radius: 0.5rem;
padding-bottom: 0.5rem;
}
p {
color: white;
margin: 0.5rem 3rem 0.5rem 3rem;
padding: 0.25rem 0.75rem;
max-width: max-content;
background-color: var(--c-gray);
border-radius: 0.5rem;
padding-bottom: 0.5rem;
}
article :global(h2) {
margin-right: 3rem;
word-wrap: normal;
color: white;
padding: 0.25rem 0.75rem;
max-width: max-content;
background-color: var(--c-darkgray);
padding: 0.25rem 1rem;
border-radius: 0.5rem;
padding-bottom: 0.5rem;
text-align: left;
line-height: 32px;
&:after {
content:' ';
display: block;
width: 75%;
margin-top: 2px;
border: 1px solid var(--c-accent-1);
box-shadow:inset 0 1px 1px rgba(0, 0, 0, .05);
}
}
article :global(h3) {
font-size: 24px;
margin-bottom: 0.5rem;
margin-right: 3rem;
word-wrap: normal;
color: var(--c-primary-text);
color: white;
padding: 0.25rem 0.75rem;
max-width: max-content;
background-color: var(--c-darkgray);
padding: 0.25rem 1rem;
border-radius: 0.5rem;
padding-bottom: 0.5rem;
text-align: left;
line-height: 32px;
&:after {
content:' ';
display: block;
width: 75%;
margin-top: 2px;
border: 1px solid var(--c-accent-1);
box-shadow:inset 0 1px 1px rgba(0, 0, 0, .05);
}
}
article :global(h4) {
font-size: 18px;
margin-bottom: 0.5rem;
margin-right: 3rem;
word-wrap: normal;
color: var(--c-primary-text);
color: white;
padding: 0.25rem 0.75rem;
max-width: max-content;
margin-bottom: 0px;
text-align: left;
line-height: 32px;
&:after {
content:' ';
display: block;
width: 75%;
margin-top: 1px;
border: 1px solid var(--c-accent-1);
box-shadow:inset 0 1px 1px rgba(0, 0, 0, .05);
}
background-color: var(--c-darkgray);
padding: 0.25rem 1rem;
border-radius: 0.5rem;
padding-bottom: 0.5rem;
}
article :global(a) {
color: #dcb7ff;
text-decoration: none;
font-style: italic;
}
article {
color: white;
margin: 0.5rem 3rem 0.5rem 3rem;
font-size: 1.1em;
padding-bottom: 5rem;
}
article :global(.astro-code) {
width: auto;
padding: 1rem 1rem 1rem 2rem;
}
article :global(code) {
font-weight: bold;
color: orange;
@ -105,16 +122,31 @@ const subtext = `Written by ${frontmatter.author} • Published on ${date}`
@media (min-width: 1000px) {
article {
margin-left: 22.5%;
margin-right: 22.5%;
margin-left: 10rem;
margin-right: 10rem;
}
h1 {
margin-left: 20%;
margin-right: 20%;
margin-left: 10rem;
margin-right: 10rem;
}
p {
margin-left: 20%;
margin-right: 20%;
margin-left: 10rem;
margin-right: 10rem;
}
}
@media (min-width: 1500px) {
article {
margin-left: 20rem;
margin-right: 20rem;
}
h1 {
margin-left: 20rem;
margin-right: 20rem;
}
p {
margin-left: 20rem;
margin-right: 20rem;
}
}
</style>

View file

@ -1,59 +1,36 @@
---
export interface Props {
title: string
titlehidden?: boolean
displayLine?: boolean
}
const { title, titlehidden, displayLine } = Astro.props
const display = titlehidden ? "display: none" : ""
const line = displayLine ? "flex" : "none"
const { title } = Astro.props
---
<section>
<h1 style={display}>{title}</h1>
<h1>{title}</h1>
<div class="wrapper">
<div class="start hightlighter"></div>
<div class="line"></div>
<slot />
<div class="drop hightlighter"></div>
<div class="drop"></div>
</div>
</section>
<style define:vars={{ line }}>
section {
padding-left: 0.25em;
padding-right: 0.25em;
padding-bottom: 5rem;
}
.hightlighter {
left: 0;
right: 0;
<style>
.drop {
display: flex;
position: absolute;
visibility: visible;
left: 0;
right: 0;
bottom: -5rem;
margin-left: auto;
margin-right: auto;
height: 1.5rem;
width: 1.5rem;
}
.drop {
bottom: -5rem;
border-radius: 0% 50% 50% 50%;
transform: rotate(45deg);
background-color: var(--c-accent-1);
background-color: var(--c-darkpurple);
}
.start {
top: -2rem;
border-radius: 40%;
border-style: solid;
border-width: 0.25rem;
border-color: var(--c-secondary-background);
background-color: var(--c-accent-1);
}
.line {
display: flex;
position: absolute;
@ -62,41 +39,40 @@ const line = displayLine ? "flex" : "none"
right: 0;
margin-left: auto;
margin-right: auto;
background-color: var(--c-accent-1);
background-color: var(--c-darkpurple);
height: calc(100% + 5rem);
translate: 0% 2rem;
width: 0.25rem;
z-index: -1;
}
h1 {
font-size: 40px;
line-height: 48px;
letter-spacing: -1px;
color: var(--c-primary-text);
font-size: 1.6rem;
color: white;
font-size: 2.25rem;
margin-top: 1rem;
margin-bottom: 0;
margin-left: auto;
margin-right: auto;
padding: 0.25rem 0.75rem;
max-width: max-content;
background-color: var(--c-primary-background);
background-color: var(--c-darkgray);
padding: 0.25rem 1.5rem;
border-radius: 0.5rem;
padding-bottom: 0.5rem;
justify-self: center;
text-align: center;
}
.wrapper {
margin: 2rem 2rem 0.5rem 2rem;
margin: 2rem 3rem 0.5rem 3rem;
display: flex;
flex-flow: column wrap;
row-gap: 1em;
column-gap: 1em;
align-self: center;
align-items: stretch;
align-content: center;
justify-content: space-around;
padding: 1em;
color: var(--c-primary-text);
color: white;
font-size: 1em;
position: relative;
}
@ -104,41 +80,21 @@ const line = displayLine ? "flex" : "none"
.drop {
margin-left: 1.5rem;
}
.start {
margin-left: 1.25rem;
}
.line {
margin-left: 2.1rem;
}
h1 {
margin-left: 3rem;
font-size: 1.85rem;
}
}
@media (min-width: 1100px) {
@media (min-width: 1500px) {
.wrapper {
margin-left: 20%;
margin-right: 20%;
flex-direction: row;
}
section {
padding-bottom: unset;
}
.drop, .start, .line {
display: var(--line);
margin-left: 2rem;
}
.start {
margin-left: 1.75rem;
}
.line {
margin-left: 2.6rem;
height: calc(100% + 6rem);
translate: 0px -2rem;
margin-left: 20rem;
margin-right: 20rem;
}
h1 {
margin-left: 15rem;
margin-right: 15rem;
margin-left: 20rem;
margin-right: 20rem;
}
}
</style>

View file

@ -15,23 +15,18 @@ const { title } = Astro.props
<style>
h1 {
color: var(--c-primary-text);
font-size: 24px;
font-weight: 700;
color: white;
font-size: 26px;
line-height: 32px;
font-family: 'Work Sans Adaptive', sans-serif;
letter-spacing: -1px;
margin: 0.5rem 0px 0.5rem 0.5em;
padding: 0.25rem 0.75rem;
width: max-content;
margin: 0 auto 0.5rem;
&:after {
content:' ';
display: block;
width: 75%;
height: 2px;
margin: -1px auto auto;
background-color: var(--c-accent-1);
}
background-color: var(--c-darkgray);
padding: 0.25rem 1rem;
border-radius: 0.5rem;
padding-bottom: 0.5rem;
}
div {
row-gap: 1em;
column-gap: 1em;
@ -56,14 +51,6 @@ const { title } = Astro.props
margin-left: 3rem;
margin-right: 3rem;
}
h1 {
margin-left: 0;
margin-right: 0;
&:after {
margin: -2px 0 0;
}
}
}
@media (min-width: 1500px) {
.base {

View file

@ -1,8 +1,8 @@
---
import okita from '@assets/okita.png'
import atlas from '@assets/atlas.png'
import foxcat from '@assets/lurker.png'
import padoru from '@assets/padoru.png'
import okita from '../assets/okita.png'
import atlas from '../assets/atlas.png'
import foxcat from '../assets/lurker.png'
import padoru from '../assets/padoru.png'
import { Image } from 'astro:assets'
import packagejson from '../../package.json'
@ -75,7 +75,7 @@ const release = `https://forgejo.neshweb.net/Firq/firq-dev-website/releases/tag/
rel="noopener noreferrer">AnthonyJ</a
> for providing me with the custom Shishou favicon.
<div class="sticky-image-wrapper">
<Image src={padoru} alt="Hashire sori yo ..." width={64} height={64} quality={100}/>
<Image src={padoru} alt="Hashire sori yo ..." />
</div>
</div>
<br />
@ -88,11 +88,11 @@ const release = `https://forgejo.neshweb.net/Firq/firq-dev-website/releases/tag/
<style>
footer {
color: var(--c-primary-text);
color: white;
bottom: 0;
}
footer > div > a {
color: var(--c-primary-text);
color: white;
}
.sticky-image-wrapper {
position: fixed;
@ -108,7 +108,7 @@ const release = `https://forgejo.neshweb.net/Firq/firq-dev-website/releases/tag/
bottom: -100px;
height: 64px;
width: 64px;
transition: transform var(--a-time-slow) var(--a-animation-1);
transition: transform 1s ease-in-out;
transform: translateX(-50%);
}
</style>

View file

@ -1,65 +0,0 @@
---
export interface Props {
title: string
}
const { title } = Astro.props
---
<div class="base">
<h1>{title}</h1>
<div>
<slot />
</div>
</div>
<style>
.base {
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.base div {
display: flex;
position: relative;
flex-flow: row wrap;
row-gap: 1em;
column-gap: 1em;
justify-content: center;
align-self: center;
padding: 1em;
}
.base h1 {
font-size: 40px;
letter-spacing: -1px;
color: var(--c-primary-text);
margin: 0 auto 0px;
padding: 0.25rem 1.5rem 0.5rem;
max-width: max-content;
&:after {
content:' ';
display: block;
width: 65%;
height: 3px;
margin: auto;
background-color: var(--c-accent-1);
}
}
@media (min-width: 1000px) {
.base div {
margin-left: 3rem;
margin-right: 3rem;
}
}
@media (min-width: 1500px) {
.base div {
margin-left: 10%;
margin-right: 10%;
}
}
</style>

View file

@ -24,36 +24,34 @@ if (abovetext === undefined) {
<style>
div > div {
display: flex;
position: relative;
flex-flow: row wrap;
row-gap: 1em;
column-gap: 1em;
row-gap: 1.5em;
column-gap: 1.5em;
justify-content: center;
align-self: center;
display: flex;
flex-flow: row wrap;
padding: 1em;
}
h1 {
font-size: 40px;
line-height: 48px;
letter-spacing: -1px;
color: var(--c-primary-text);
margin: 0 auto 0px;
padding: 0.25rem 1.5rem 0.5rem;
color: white;
margin-top: 2rem;
margin-bottom: 0;
margin-left: auto;
margin-right: auto;
padding: 0.25rem 0.75rem;
max-width: max-content;
&:after {
content:' ';
display: block;
width: 65%;
height: 3px;
margin: auto;
background-color: var(--c-accent-1);
}
background-color: var(--c-darkgray);
padding: 0.25rem 1.5rem;
border-radius: 0.5rem;
padding-bottom: 0.5rem;
}
h2 {
color: var(--c-primary-text);
color: white;
font-size: 16px;
font-weight: 400;
font-weight: 600;
margin: 5;
line-height: 20px;
text-align: center;

View file

@ -1,8 +1,8 @@
---
import { Image } from 'astro:assets'
import Layout from '@layouts/Layout.astro'
import sadshishou from '@assets/shishousad.webp'
import SmallTitle from '@components/titles/smallTitle.astro'
import Layout from '../layouts/Layout.astro'
import BaseSection from '../layouts/baseSection.astro'
import sadshishou from '../assets/shishousad.webp'
const description = "Error. This shouldn't happen :/"
---
@ -12,7 +12,7 @@ const description = "Error. This shouldn't happen :/"
currentpage="404"
descriptionOverride={description}
>
<SmallTitle maintext='Error' subtext='FirqhundredandFirq - Not Found' fadeout={true}/>
<BaseSection title="FirqhundredandFirq - Not Found">
<div>
<Image src={sadshishou} alt="Sad Shishou" />
<h2>Well ... you were not supposed to end up here.</h2>
@ -20,51 +20,44 @@ const description = "Error. This shouldn't happen :/"
&lt;&lt; Go back home
</a>
</div>
</BaseSection>
</Layout>
<style>
div {
padding: 0px 2rem;
display: flex;
flex-wrap: nowrap;
flex-wrap: wrap;
flex-direction: column;
align-items: center;
}
h2 {
font-family: 'Work Sans Variable', sans-serif;
font-weight: 500;
color: var(--c-primary-text);
font-size: 1.25rem;
color: white;
font-size: 2rem;
font-weight: bold;
margin-top: 1rem;
max-width: max-content;
text-align: center;
font-style: italic;
}
a {
display: flex;
align-items: center;
justify-content: center;
width: 75%;
text-align: center;
width: fit-content;
font-weight: 500;
font-family: 'Work Sans Variable', sans-serif;
color: var(--c-primary-text);
margin: 1rem 0px 0px;
padding: 0.5rem 0.75rem;
color: white;
background-color: var(--c-gray);
padding: 0.5rem 0px;
margin-bottom: 2rem;
text-decoration: none;
background-color: var(--c-primary-background);
border-radius: 10px;
border-style: solid;
border-width: 2px;
border-color: var(--c-primary-background);
text-transform: capitalize;
}
font-size: 1.5rem;
font-weight: bold;
a:hover {
border-color: var(--c-accent-1);
&:hover {
color: var(--c-darkpurple);
}
}
img {
width: 200px;
height: auto;
border-radius: 10%;
width: 256px;
height: 256px;
}
</style>

View file

@ -1,17 +1,17 @@
---
import Layout from '@layouts/Layout.astro'
import Layout from '../layouts/Layout.astro'
import AboutSection from '../layouts/aboutSection.astro'
import ContactSection from '@layouts/contactSection.astro'
import ContactSection from '../layouts/contactSection.astro'
import ContactCard from '../components/contactCard.astro'
import contactdata from '../../static/data/_contactdata.json'
import CustomFooter from '@layouts/customFooter.astro'
import TechnologyCard from '@components/cards/technologyCard.astro'
import technologydata from '@content/data/technologydata.json'
import SmallTitle from '@components/titles/smallTitle.astro'
import CustomFooter from '../layouts/customFooter.astro'
import TechnologyCard from '../components/technologyCard.astro'
import technologydata from '../../static/data/_technologydata.json'
const description =
"A summary of the technologies used as well as my contact information. You'll also find disclaimers and thank you notes for the people that helped me."
const subtext =
"This is a small sideproject that I'm creating. First time doing webdev in general, and first project using Typescript."
---
<Layout
@ -19,10 +19,16 @@ const subtext =
currentpage="about"
descriptionOverride={description}
>
<SmallTitle maintext="About this site" subtext={subtext} fadeout={true} />
<ContactSection title="Powered by">
<AboutSection title="About">
This is a small sideproject that I'm creating. First time doing webdev in
general, and first project using Typescript.
</AboutSection>
<ContactSection title="Technologies used">
{technologydata.map((item) => <TechnologyCard {...item} />)}
</ContactSection>
<ContactSection title="Contact me">
{contactdata.map((item) => <ContactCard {...item} />)}
</ContactSection>
<ContactSection title="Disclaimers">
<CustomFooter />
</ContactSection>

35
src/pages/blog.astro Normal file
View file

@ -0,0 +1,35 @@
---
import Layout from '../layouts/Layout.astro'
import BlogCard from '../components/blogCard.astro'
import BlogSection from '../layouts/blogSection.astro'
const description =
'My own small blog. Topics include FGO, TA, Programming, web technologies and more!'
const allPosts = await Astro.glob('../pages/blog/*.{md,mdx}')
allPosts.sort(
(a, b) =>
Date.parse(b.frontmatter.pubDate) - Date.parse(a.frontmatter.pubDate)
)
---
<Layout
title="Blog - Firq FGO Site"
currentpage="blog"
descriptionOverride={description}
>
<BlogSection title="Blog Articles">
{
allPosts.map((post) => (
<BlogCard
url={post.url}
title={post.frontmatter.title}
pubdate={post.frontmatter.pubDate}
description={post.frontmatter.description}
author={post.frontmatter.author}
/>
))
}
</BlogSection>
</Layout>
<style></style>

View file

@ -1,17 +0,0 @@
---
import { getCollection } from 'astro:content'
export async function getStaticPaths() {
const blogEntries = await getCollection('blog')
return blogEntries.map((entry) => ({
params: { slug: entry.slug },
props: { entry },
}))
}
const { entry } = Astro.props
const { Content } = await entry.render()
---
<Content />

View file

@ -75,7 +75,7 @@ allPosts.sort(
The `frontmatter` interface is a kind of header for the markdown files which provides astro with metadata like title, author and such.
It is structured like this:
```yaml
```
---
layout: ../../layouts/blogPost.astro
title: 'How Astro powers this site'

View file

@ -74,7 +74,7 @@ As you can see, I am using a custom container for the runtime stage, which will
### Custom serve docker - My new goto for static site serving
When starting out with the `Dockerfile`, I first used the standard `node:lts` image for the runtime. This meant I also had to install the `serve` package by `@warren-bank` each time I built the container. Since this takes extra time and resources each run, I decided to create a pre-configured docker container that can be used for this instead.
When starting out with the `Dockerfile`, I first used the standard `node:lts` image for the runtime. This meant I also had to install the `serve` package by `@warren-bank` each time I built the container. Since this takes extra time and resources each run, I decided to create a pre-configured docker container that can be used for this instead.
The `Dockerfile` for that one is laughable simple:
@ -89,7 +89,7 @@ The container is also published to the docker registry that the Forgejo instance
Since my website is now using a docker container instead of the previous `rsync` + `screen` approach, a new deployment solution was needed.
In the end, Neshura proposed to use <a href="https://github.com/louislam/dockge" target="_blank" rel="noopener noreferrer" >Dockge</a>, a new, simple container management tool build by the developer of the beloved uptime-kuma. With that set up, getting the website only was really really easy:
In the end, Neshura proposed to use <a href="https://github.com/louislam/dockge" target="_blank" rel="noopener noreferrer" style="font-style: unset">Dockge</a>, a new, simple container management tool build by the developer of the beloved uptime-kuma. With that set up, getting the website only was really really easy:
1. Create a new stack
2. Add a container entry
@ -161,4 +161,4 @@ In the end, I must say migrating was a lot more painless than expected. Sure, Fo
I also updated my about page to now reflect the migration, as the old technologies weren't up-to-date anymore.
If you want to check out the repository by yourself, feel free to do so. <a href="https://forgejo.neshweb.net/Firq/firq-dev-website" target="_blank" rel="noopener noreferrer" >It is available on Neshuras Forgejo instance</a>
If you want to check out the repository by yourself, feel free to do so. <a href="https://forgejo.neshweb.net/Firq/firq-dev-website" target="_blank" rel="noopener noreferrer" style="font-style: unset">It is available on Neshuras Forgejo instance</a>

View file

@ -81,7 +81,7 @@ screen -S website-firq-npx -dm npx serve public/ -p 9000 -c serve.json"
With the following directory structure on the remote host, this can easily be explained:
```plain
```
/
├─ public/
│ ├─ site content

View file

@ -1,39 +0,0 @@
---
import Layout from '@layouts/Layout.astro'
import BlogCard from '@components/cards/blogCard.astro'
import BlogSection from '@layouts/blogSection.astro'
import SmallTitle from '@components/titles/smallTitle.astro'
import { getCollection } from 'astro:content'
const description =
'My own small blog. Topics include FGO, TA, Programming, web technologies and more!'
const blogEntries = await getCollection('blog')
blogEntries.sort(
(a, b) =>
(b.data.pubDate.valueOf() - a.data.pubDate.valueOf() )
)
---
<Layout
title="Blog - Firq FGO Site"
currentpage="blog"
descriptionOverride={description}
>
<SmallTitle maintext="Blog Articles" subtext="" fadeout={true} />
<BlogSection title="Blog Articles" displayLine={true} titlehidden={true}>
{
blogEntries.map((post) => (
<BlogCard
url="blog"
slug={post.slug}
title={post.data.title}
pubdate={post.data.pubDate}
description={post.data.description}
author={post.data.author}
/>
))
}
</BlogSection>
</Layout>
<style></style>

View file

@ -2,7 +2,7 @@
layout: ../../layouts/blogPost.astro
title: 'FGO Mechanics: Instant Death'
pubDate: 2023-08-19
description: 'Blog post talking about instant death in FGO and how you can take advantage.'
description: 'Blog post talking about instant death in FGO, how you can take advantage of it and what its limits are.'
author: 'Firq'
tags: ['fgo', 'games']
---
@ -18,10 +18,10 @@ it doesn't interact with the hitrate, but if you have proof that this is differe
Instant Kill & Instant Death: One of the most rejected systems to exist in FGO. Most players know of it, but discard it because of its unreliability and uselessness against stronger enemies. In this article, I want to dive a bit into the workings of Instant Kill and help you understand how you can, in specific scenarios, use it to your advantage.
There are a multitude of servants that have access to instant-kill, but I will only highlight a few here (You can view the full list on <a href="https://gamepress.gg/grandorder/instant-death" target="_blank" rel="noopener noreferrer" >Gamepress</a>)
There are a multitude of servants that have access to instant-kill, but I will only highlight a few here (You can view the full list on <a href="https://gamepress.gg/grandorder/instant-death" target="_blank" rel="noopener noreferrer" style="font-style: unset">Gamepress</a>)
- **Nitocris (Caster)**: The most prominent figure, as she has easy access to her instant-killing NP and a skill that increases her death hit rate
- **Void Shiki (Saber)**: Another Example of an AOE Instant-Kill servant who also has access to Death Resist debuffs. One quest in her release event even specifically used the Instant Kill mechanic (<a href="https://apps.atlasacademy.io/db/NA/quest/94021308/1" target="_blank" rel="noopener noreferrer" >Quest Link here</a>)
- **Void Shiki (Saber)**: Another Example of an AOE Instant-Kill servant who also has access to Death Resist debuffs. One quest in her release event even specifically used the Instant Kill mechanic (<a href="https://apps.atlasacademy.io/db/NA/quest/94021308/1" target="_blank" rel="noopener noreferrer" style="font-style: unset">Quest Link here</a>)
- **King Hassan (Assassin)**: The only servant that can afflict enemies with instant death on normal attacks (Note: David can do this as well, but only if he has his Bond CE equipped)
But since Instant Kill is based on probability, most players are relucatant to use it in their farming compositions. This thems from the different death rates enemies have:
@ -53,10 +53,10 @@ The parameters here are the following:
## Example
The main reason this came up was because of a farming comp used in <a href="https://apps.atlasacademy.io/db/NA/quest/94061820/1" target="_blank" rel="noopener noreferrer" >Hunting Quest XI - Day 5 - Pride+</a>. The node is structured
The main reason this came up was because of a farming comp used in <a href="https://apps.atlasacademy.io/db/NA/quest/94061820/1" target="_blank" rel="noopener noreferrer" style="font-style: unset">Hunting Quest XI - Day 5 - Pride+</a>. The node is structured
into a 2 - 1 - 1 Layout, meaning using a dual-DPS setup would be the way to go.
Looking at the stats for the first wave, it made sense to use Nitocris: Both Ghouls have a 100% Death Rate <a href="https://apps.atlasacademy.io/db/NA/enemy/9940700" target="_blank" rel="noopener noreferrer" >according to Atlas Academy</a>.
Looking at the stats for the first wave, it made sense to use Nitocris: Both Ghouls have a 100% Death Rate <a href="https://apps.atlasacademy.io/db/NA/enemy/9940700" target="_blank" rel="noopener noreferrer" style="font-style: unset">according to Atlas Academy</a>.
I went with using Nitocris, since she has a 100% NP charge and a skill that increases her Instant Death rate by 100%. Not needing any additional charge meant that no other buffs or AOE charges needed to be used on turn 1.

View file

@ -1,10 +1,9 @@
---
import AboutText from '@components/aboutText.astro'
import FavouriteCard from '@components/cards/favouriteCard.astro'
import Hi from '@components/titles/title.astro'
import favouritesdata from '@content/data/favouritesdata.json'
import Layout from '@layouts/Layout.astro'
import BaseSection from '@layouts/baseSection.astro'
import Layout from '../layouts/Layout.astro'
import Hero from '../components/hero.astro'
import BaseSection from '../layouts/baseSection.astro'
import FavouriteCard from '../components/favouriteCard.astro'
import favouritesdata from '../../static/data/_favouritesdata.json'
const description =
'The very own page of Firq for providing informating about TA servants, listing past TA achievements and hosting a blog for talking about FGO, Programming and other stuff'
@ -15,11 +14,8 @@ const description =
currentpage="home"
descriptionOverride={description}
>
<Hi />
<BaseSection title="About me">
<AboutText/>
</BaseSection>
<BaseSection title="Favourite Things">
<Hero />
<BaseSection title="Favourites">
{favouritesdata.map((item) => <FavouriteCard {...item} />)}
</BaseSection>
</Layout>

View file

@ -1,13 +1,12 @@
---
import Layout from '@layouts/Layout.astro'
import ServantSection from '@layouts/servantSection.astro'
import Layout from '../layouts/Layout.astro'
import BaseSection from '../layouts/baseSection.astro'
import ServantCard from '@components/cards/servantCard.astro'
import servantdata from '@content/data/servantdata.json'
import ServantCard from '../components/servantCard.astro'
import servantdata from '../../static/data/_servantdata.json'
import CeCard from '@components/cards/ceCard.astro'
import cedata from '@content/data/cedata.json'
import SmallTitle from '@components/titles/smallTitle.astro'
import CeCard from '../components/ceCard.astro'
import cedata from '../../static/data/_cedata.json'
const description =
'A list of all the servants and ces that Firq can offer up on support for TA.'
@ -18,14 +17,13 @@ const description =
currentpage="servants"
descriptionOverride={description}
>
<SmallTitle maintext='TA Offering' subtext='Servants and CEs I can offer for your TAs' fadeout={true}/>
<ServantSection title="Servants">
{servantdata.map((item, index) => <ServantCard {...item} index={index} />)}
</ServantSection>
<BaseSection title="Servants">
{servantdata.map((item) => <ServantCard {...item} />)}
</BaseSection>
<div class="placeholder"></div>
<ServantSection title="CEs">
<BaseSection title="CEs">
{cedata.map((item) => <CeCard {...item} />)}
</ServantSection>
</BaseSection>
<div class="placeholder"></div>
</Layout>

View file

@ -5,14 +5,13 @@
// > You could have the notable ones like you do now, but at the bottom, there could be a drop-down or "expand" or "more" or
// > some other section like that which you could click and show the rest
import Layout from '@layouts/Layout.astro'
import Layout from '../layouts/Layout.astro'
import TaSection from '@layouts/taSection.astro'
import TaCard from '@components/cards/taCard.astro'
import tadata from '@content/data/tadata.json'
import featured_data from '@content/data/featureddata.json'
import FgotaHero from '@components/fgotaHero.astro'
import SmallTitle from '@components/titles/smallTitle.astro'
import TaSection from '../layouts/taSection.astro'
import TaCard from '../components/taCard.astro'
import tadata from '../../static/data/_tadata.json'
import featured_data from '../../static/data/_featureddata.json'
import FgotaHero from '../components/fgotaHero.astro'
const important_data = tadata.filter(function (el) {
return [
@ -38,8 +37,7 @@ const description = 'A collection of TAs previously completed be Firq.'
currentpage="ta-collection"
descriptionOverride={description}
>
<SmallTitle maintext='TA Collection' subtext=''/>
<FgotaHero fadeout={true}/>
<FgotaHero />
<TaSection title="Notable TAs" abovetext="My most notable TAs">
{important_data.map((item) => <TaCard {...item} />)}
</TaSection>

View file

@ -37,7 +37,7 @@
{
"name": "Vessel of the Saint",
"imageFile": "vessel.png",
"mlb": true
"mlb": false
},
{
"name": "Devilish Bodhisattva",

View file

@ -0,0 +1,32 @@
[
{
"site": "Youtube: @Firq_",
"link": "https://www.youtube.com/@Firq_",
"imageFile": "youtube.webp"
},
{
"site": "Twitch: Firq",
"link": "https://www.twitch.tv/firq",
"imageFile": "twitch.webp"
},
{
"site": "Discord: firq",
"link": "https://discord.com/users/186014064835690496",
"imageFile": "discord.webp"
},
{
"site": "Twitter: Firq_ow",
"link": "https://twitter.com/firq_ow",
"imageFile": "twitter.webp"
},
{
"site": "Reddit: u/Firq_ow",
"link": "https://www.reddit.com/user/firq_ow",
"imageFile": "reddit.webp"
},
{
"site": "Support Setup on Rayshift",
"link": "https://rayshift.io/na/firq",
"imageFile": "custom-fgo.webp"
}
]

View file

@ -10,11 +10,5 @@
"origin": "Fate/Grand Order",
"imageFile": "skadi.png",
"link": "https://twitter.com/firq_ow/status/1544321985995489280"
},
{
"name": "Summer Skadi",
"origin": "Fate/Grand Order",
"imageFile": "summerskadi.png",
"link": "https://twitter.com/firq_ow/status/1816355501216596073"
}
]

View file

@ -9,16 +9,6 @@
"bondceImageFile": "scathach.png",
"bond10": true
},
{
"name": "Summer Skadi",
"level": "120",
"np": "5",
"skills": "10 / 10 / 10",
"ml": "10",
"servantImageFile": "summerskadi_03.png",
"bondceImageFile": "summerskadi.png",
"bond10": true
},
{
"name": "Skadi",
"level": "120",
@ -29,16 +19,6 @@
"bondceImageFile": "skadi.png",
"bond10": true
},
{
"name": "Summer Skadi",
"level": "70",
"np": "1",
"skills": "10 / 10 / 10",
"ml": "1",
"servantImageFile": "summerskadi_02.png",
"bondceImageFile": "summerskadi.png",
"bond10": true
},
{
"name": "Skadi",
"level": "70",
@ -69,16 +49,6 @@
"bondceImageFile": "koyanlight.png",
"bond10": true
},
{
"name": "Koyanskaya of Light",
"level": "70",
"np": "1",
"skills": "10 / 10 / 10",
"ml": "Not Unlocked",
"servantImageFile": "koyanlight_02.png",
"bondceImageFile": "koyanlight.png",
"bond10": true
},
{
"name": "Castoria",
"level": "90",
@ -187,7 +157,7 @@
"ml": "10",
"servantImageFile": "douman_01.png",
"bondceImageFile": "douman.png",
"bond10": true
"bond10": false
},
{
"name": "Himiko",
@ -220,7 +190,7 @@
"bond10": false
},
{
"name": "Taigong Wang",
"name": "Taigon Wang",
"level": "70",
"np": "1",
"skills": "10 / 9 / 10",
@ -255,16 +225,6 @@
"np": "1",
"skills": "9 / 9 / X",
"ml": "Not Unlocked",
"servantImageFile": "liz_02.png",
"bondceImageFile": "liz.png",
"bond10": false
},
{
"name": "Elisabeth Báthory",
"level": "1",
"np": "1",
"skills": "9 / X / X",
"ml": "Not Unlocked",
"servantImageFile": "liz_01.png",
"bondceImageFile": "liz.png",
"bond10": false

View file

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

7
static/robots.txt Normal file
View file

@ -0,0 +1,7 @@
user-agent:*
Disallow: /assets/data/
User-agent: GPTBot
Disallow: /
Sitemap: https://firq.dev/sitemap-index.xml

View file

@ -1,12 +1,3 @@
{
"extends": "astro/tsconfigs/strict",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@assets/*": [ "src/assets/*" ],
"@components/*": [ "src/components/*" ],
"@content/*": [ "src/content/*" ],
"@layouts/*": [ "src/layouts/*" ]
}
}
"extends": "astro/tsconfigs/strict"
}

View file

@ -1,32 +1,10 @@
export default {
lighthouseOptions: {
throttlingMethod: "devtools",
throttling: {
cpuSlowdownMultiplier: 4,
requestLatencyMs: 150,
downloadThroughputKbps: 1638.4,
uploadThroughputKbps: 1638.4,
},
screenEmulation: {
width: 412,
height: 823,
deviceScaleFactor: 1.75,
}
},
puppeteerOptions: {
args: [
"--no-sandbox",
"--disable-setuid-sandbox"
],
args: ["--no-sandbox", "--disable-setuid-sandbox"],
},
ci: {
budget: 50,
buildStatic: true,
},
scanner: {
sitemap: true,
dynamicSampling: false,
samples: 3,
buildStatic: true
},
outputPath: "unlighthouse-reports",
}