Compare commits

...

30 commits

Author SHA1 Message Date
Sebastian Wendel cf49c06912 added phone number to the footer 2024-03-10 03:16:02 +01:00
Sebastian Wendel 6b723c7279 switch vite-plugin-svgr from dev to main dependencies 2024-03-10 03:15:29 +01:00
Sebastian Wendel a334fb1e4a changed components from react to astro 2024-03-10 03:02:48 +01:00
Sebastian Wendel ce04e9ac82 moved images to src folder 2024-03-10 03:00:35 +01:00
Sebastian Wendel 683838e359 replace colors and fonts with variables 2024-03-10 02:59:20 +01:00
Sebastian Wendel 9bc444d280 changed logo description 2024-03-10 02:57:48 +01:00
Sebastian Wendel e1cc840ea2 set vscodium to use local typescript sdk 2024-03-09 18:59:22 +01:00
Sebastian Wendel c108270a99 added tailwind dependencies and enabled watch mode 2024-03-09 12:37:28 +01:00
Sebastian Wendel 1ee1fa5315 enabled json import types 2024-03-09 12:35:47 +01:00
Sebastian Wendel 09b600778e switched to ts config format and set theme colors and fonts 2024-03-09 12:34:20 +01:00
Sebastian Wendel b77c5cdc92 switched to ts config format and set theme colors and fonts 2024-03-09 12:34:10 +01:00
Sebastian Wendel 2f42f134d7 updated development environment configuration 2024-03-09 12:32:51 +01:00
Sebastian Wendel 74ea07668e set vscodium plugin dependencies and lsp configuration 2024-03-09 12:28:47 +01:00
Sebastian Wendel 54122f8261 set node development build envirnment 2024-03-09 12:27:22 +01:00
Sebastian Wendel 5c97b90444 updated development environment configuration 2024-03-05 21:51:47 +01:00
Sebastian Wendel 94afcc57a8 updated favicon default color 2024-03-05 21:50:20 +01:00
Sebastian Wendel f61265d2f7 added autor profile images 2024-03-05 21:49:22 +01:00
Sebastian Wendel 9439e3b9a8 added simple page sceleton 2024-03-05 21:48:36 +01:00
Sebastian Wendel 3f58216dd9 added logo titel 2024-03-05 11:35:54 +01:00
Sebastian Wendel 8c2322ac6b fixed astro check directories 2024-03-04 18:18:43 +01:00
Sebastian Wendel af9c46d46f added vite svgr support 2024-03-04 18:17:57 +01:00
Sebastian Wendel 4f94948703 added font and icon dependencies 2024-03-04 18:12:20 +01:00
Sebastian Wendel 33a9c147c8 replaced static package name by variable 2024-03-04 18:10:57 +01:00
Sebastian Wendel efd318859b added vite svgr support 2024-03-04 18:00:44 +01:00
Sebastian Wendel 19305a568d added custom srx favicon 2024-03-04 17:48:54 +01:00
Sebastian Wendel 09fa684aad Simplified startup project 2024-03-03 13:45:20 +01:00
Sebastian Wendel 7808b0a414 updated packages and added lockfile 2024-02-29 17:00:09 +01:00
Sebastian Wendel 65f4134c82 upgraded astro config and packes to latest version 2023-10-31 16:42:59 +01:00
Sebastian Wendel a0cf3805e9 upgraded dream2nix config to build node packes 2023-10-31 16:35:47 +01:00
Sebastian Wendel 36d9b9bd1c upgraded dream2nix config to build node packes 2023-10-31 16:35:30 +01:00
95 changed files with 3203 additions and 6745 deletions

9
.envrc
View file

@ -1,7 +1,8 @@
watch_file flake.nix flake.lock package.json yarn.lock nix/*.nix
use flake
yarn install
watch_file **/*.nix *.lock package.json
yarn sync
yarn install
yarn astro sync
export MODE=development

View file

@ -1,20 +0,0 @@
# build output
dist/
result
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store

View file

@ -1,32 +0,0 @@
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: ['plugin:astro/all'],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['@typescript-eslint'],
rules: {},
overrides: [
{
// Define the configuration for `.astro` file.
files: ['*.astro'],
// Allows Astro components to be parsed.
parser: 'astro-eslint-parser',
// Parse the script in `.astro` as TypeScript by adding the following configuration.
// It's the setting you need when using TypeScript.
parserOptions: {
parser: '@typescript-eslint/parser',
extraFileExtensions: ['.astro'],
},
rules: {
// override/add rules settings here, such as:
'astro/no-set-html-directive': 'off',
},
},
],
};

35
.gitignore vendored
View file

@ -1,26 +1,21 @@
# nix env
.direnv/
# node
node_modules
# nix
.direnv
# build
dist
result
# build output
dist/
# generated type files
.astro/
# dependencies
node_modules/
# generated
.astro
.pre-commit-config.yaml
# logs
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*
*.log*
# environment variables
.env
.env.production
src/env.d.ts
# config
.env*
# pre-commit
/.pre-commit-config.yaml
templates

2
.npmrc
View file

@ -1,2 +0,0 @@
# Expose Astro dependencies for `pnpm` users
shamefully-hoist=true

View file

@ -1,4 +0,0 @@
/.vscode
/dist
/result
/.direnv

View file

@ -1,30 +0,0 @@
/** @type {import("@types/prettier").Options} */
module.exports = {
printWidth: 100,
semi: true,
singleQuote: true,
tabWidth: 4,
trailingComma: 'es5',
useTabs: true,
plugins: ['./node_modules/prettier-plugin-astro'],
overrides: [
{
files: '*.astro',
options: {
parser: 'astro',
},
},
{
files: ['.*', '*.md', '*.toml'],
options: {
useTabs: false,
},
},
{
files: ['*.yaml', '*.yml', '*.json'],
options: {
tabWidth: 2,
},
},
],
};

View file

@ -1 +0,0 @@
nodejs 18.15.0

View file

@ -1,7 +1,15 @@
{
"recommendations": [
"arrterian.nix-env-selector",
"astro-build.astro-vscode",
"bradlc.vscode-tailwindcss",
"csstools.postcss",
"ecmel.vscode-html-css",
"formulahendry.auto-complete-tag",
"jnoortheen.nix-ide",
"kamadorueda.alejandra",
"mikestead.dotenv",
"stylelint.vscode-stylelint",
],
"unwantedRecommendations": []
}

51
.vscode/settings.json vendored
View file

@ -1,12 +1,43 @@
{
"alejandra.program": "alejandra",
"[nix]": {
"editor.defaultFormatter": "kamadorueda.alejandra",
"editor.formatOnPaste": true,
"editor.formatOnSave": true,
"editor.insertSpaces": true,
"editor.tabSize": 2,
"editor.codeLens": true
},
"editor.linkedEditing": true,
"editor.formatOnSave": true,
"files.associations": {
"*.mdx": "markdown",
"*.css": "tailwindcss",
"flake.lock": "json"
},
"[nix]": {
"editor.defaultFormatter": "kamadorueda.alejandra"
},
"[html]": {
"editor.defaultFormatter": "vscode.html-language-features"
},
"[css]": {
"editor.defaultFormatter": "vscode.css-language-features"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[jsonc]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[typescriptreact]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[javascript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[tailwindcss]": {
"editor.defaultFormatter": "bradlc.vscode-tailwindcss"
},
"[astro]": {
"editor.defaultFormatter": "astro-build.astro-vscode"
},
"nix.serverPath": "nil",
"nix.enableLanguageServer": true,
"alejandra.program": "alejandra",
"typescript.tsdk": "node_modules/typescript/lib"
}

18
.vscode/tasks.json vendored
View file

@ -1,18 +0,0 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "watch tests",
"type": "shell",
"command": "watch --color 'nix-build test --no-out-link | xargs cat'",
"presentation": {
"echo": false,
"reveal": "always",
"focus": false,
"panel": "dedicated",
"showReuseMessage": false
},
"problemMatcher": []
}
]
}

View file

@ -1,6 +1,6 @@
# srx.dev: Portfolio Sebastian Wendel
# srx.digital: Portfolio Sebastian Wendel
[srx.dev](https://srx.dev/)
[srx.digital](https://srx.digital/)
## 🧞 Commands
@ -19,7 +19,7 @@ All commands are run from the root of the project, from a terminal:
### Nix
| Command | Action |
| :-------------------- | :------------------------------------------ |
| `nix run .#serve` | Starts local dev server at `localhost:3001` |
| `nix build .#srx_dev` | Build your Nix Package |
| Command | Action |
| :------------------------ | :------------------------------------------ |
| `nix run .#serve` | Starts local dev server at `localhost:3001` |
| `nix build .#srx-digital` | Build your Nix Package |

View file

@ -1,32 +1,20 @@
import { defineConfig } from 'astro/config';
import path from 'path';
import mdx from '@astrojs/mdx';
import robotsTxt from 'astro-robots-txt';
import tailwind from '@astrojs/tailwind';
import sitemap from '@astrojs/sitemap';
import { defineConfig } from "astro/config";
import react from "@astrojs/react";
import tailwind from "@astrojs/tailwind";
import svgr from 'vite-plugin-svgr'
const mkPath = (name) => path.resolve(`./src/${name}`);
const cacheDir = process.env.VITE_CACHE ? process.env.VITE_CACHE : 'node_modules/.vite';
const tailwindConfig = { config: { applyBaseStyles: false } };
const external = ['svgo'];
const mdxConfig = {};
const alias = {
'@srx-components': mkPath('components'),
'@srx-layouts': mkPath('layouts'),
'@srx-pages': mkPath('pages'),
'@srx-scripts': mkPath('scripts'),
'@srx-styles': mkPath('styles'),
};
// https://astro.build/config
export default defineConfig({
integrations: [sitemap(), mdx(mdxConfig), tailwind(tailwindConfig), robotsTxt()],
site: 'https://srx.dev',
server: { port: 3001 },
experimental: {
contentCollections: true,
},
vite: {
ssr: { external },
resolve: { alias },
},
// https://astro.build/config
site: "https://srx.digital",
server: { port: 3001 },
integrations: [
react(),
tailwind()
],
vite: {
plugins: [
svgr()
],
},
devToolbar: { enabled: false },
});

View file

@ -1,124 +1,13 @@
{
"nodes": {
"alejandra": {
"inputs": {
"fenix": "fenix",
"flakeCompat": "flakeCompat",
"nixpkgs": [
"d2n",
"nixpkgs"
]
},
"locked": {
"lastModified": 1658427149,
"narHash": "sha256-ToD/1z/q5VHsLMrS2h96vjJoLho59eNRtknOUd19ey8=",
"owner": "kamadorueda",
"repo": "alejandra",
"rev": "f5a22afd2adfb249b4e68e0b33aa1f0fb73fb1be",
"type": "github"
},
"original": {
"owner": "kamadorueda",
"repo": "alejandra",
"type": "github"
}
},
"crane": {
"flake": false,
"locked": {
"lastModified": 1670900067,
"narHash": "sha256-VXVa+KBfukhmWizaiGiHRVX/fuk66P8dgSFfkVN4/MY=",
"owner": "ipetkov",
"repo": "crane",
"rev": "59b31b41a589c0a65e4a1f86b0e5eac68081468b",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"d2n": {
"inputs": {
"alejandra": "alejandra",
"all-cabal-json": [
"nixpkgs"
],
"crane": "crane",
"devshell": "devshell",
"flake-parts": "flake-parts",
"flake-utils-pre-commit": "flake-utils-pre-commit",
"ghc-utils": "ghc-utils",
"gomod2nix": "gomod2nix",
"mach-nix": "mach-nix",
"nix-pypi-fetcher": "nix-pypi-fetcher",
"nixpkgs": "nixpkgs",
"poetry2nix": "poetry2nix",
"pre-commit-hooks": "pre-commit-hooks",
"pruned-racket-catalog": "pruned-racket-catalog"
},
"locked": {
"lastModified": 1676992344,
"narHash": "sha256-TEn5kEi/jL9Dt6O+ZZ7kQwnlAgEv0r4VgQZnav/cfV4=",
"owner": "nix-community",
"repo": "dream2nix",
"rev": "db72710500a80bdf4589b6807d2491a4a0dae3ad",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "dream2nix",
"type": "github"
}
},
"devshell": {
"flake": false,
"locked": {
"lastModified": 1663445644,
"narHash": "sha256-+xVlcK60x7VY1vRJbNUEAHi17ZuoQxAIH4S4iUFUGBA=",
"owner": "numtide",
"repo": "devshell",
"rev": "e3dc3e21594fe07bdb24bdf1c8657acaa4cb8f66",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"fenix": {
"inputs": {
"nixpkgs": [
"d2n",
"alejandra",
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1657607339,
"narHash": "sha256-HaqoAwlbVVZH2n4P3jN2FFPMpVuhxDy1poNOR7kzODc=",
"owner": "nix-community",
"repo": "fenix",
"rev": "b814c83d9e6aa5a28d0cf356ecfdafb2505ad37d",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
@ -128,36 +17,15 @@
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"d2n",
"nixpkgs"
]
},
"locked": {
"lastModified": 1675933616,
"narHash": "sha256-/rczJkJHtx16IFxMmAWu5nNYcSXNg1YYXTHoGjLrLUA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "47478a4a003e745402acf63be7f9a092d51b83d7",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1679737941,
"narHash": "sha256-srSD9CwsVPnUMsIZ7Kt/UegkKUEBcTyU1Rev7mO45S0=",
"lastModified": 1706830856,
"narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "3502ee99d6dade045bdeaf7b0cd8ec703484c25c",
"rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f",
"type": "github"
},
"original": {
@ -167,12 +35,15 @@
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
@ -181,66 +52,16 @@
"type": "github"
}
},
"flake-utils-pre-commit": {
"locked": {
"lastModified": 1644229661,
"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flakeCompat": {
"flake": false,
"locked": {
"lastModified": 1650374568,
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"ghc-utils": {
"flake": false,
"locked": {
"lastModified": 1662774800,
"narHash": "sha256-1Rd2eohGUw/s1tfvkepeYpg8kCEXiIot0RijapUjAkE=",
"ref": "refs/heads/master",
"rev": "bb3a2d3dc52ff0253fb9c2812bd7aa2da03e0fea",
"revCount": 1072,
"type": "git",
"url": "https://gitlab.haskell.org/bgamari/ghc-utils"
},
"original": {
"type": "git",
"url": "https://gitlab.haskell.org/bgamari/ghc-utils"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"pre-commit",
"nixpkgs"
]
"nixpkgs": ["pre-commit", "nixpkgs"]
},
"locked": {
"lastModified": 1660459072,
"narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
"lastModified": 1703887061,
"narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
"rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5",
"type": "github"
},
"original": {
@ -249,44 +70,13 @@
"type": "github"
}
},
"gomod2nix": {
"flake": false,
"locked": {
"lastModified": 1627572165,
"narHash": "sha256-MFpwnkvQpauj799b4QTBJQFEddbD02+Ln5k92QyHOSk=",
"owner": "tweag",
"repo": "gomod2nix",
"rev": "67f22dd738d092c6ba88e420350ada0ed4992ae8",
"type": "github"
},
"original": {
"owner": "tweag",
"repo": "gomod2nix",
"type": "github"
}
},
"mach-nix": {
"flake": false,
"locked": {
"lastModified": 1634711045,
"narHash": "sha256-m5A2Ty88NChLyFhXucECj6+AuiMZPHXNbw+9Kcs7F6Y=",
"owner": "DavHau",
"repo": "mach-nix",
"rev": "4433f74a97b94b596fa6cd9b9c0402104aceef5d",
"type": "github"
},
"original": {
"id": "mach-nix",
"type": "indirect"
}
},
"nix-filter": {
"locked": {
"lastModified": 1678109515,
"narHash": "sha256-C2X+qC80K2C1TOYZT8nabgo05Dw2HST/pSn6s+n6BO8=",
"lastModified": 1705332318,
"narHash": "sha256-kcw1yFeJe9N4PjQji9ZeX47jg0p9A0DuU4djKvg1a7I=",
"owner": "numtide",
"repo": "nix-filter",
"rev": "aa9ff6ce4a7f19af6415fb3721eaa513ea6c763c",
"rev": "3449dc925982ad46246cfc36469baf66e1b64f17",
"type": "github"
},
"original": {
@ -295,45 +85,30 @@
"type": "github"
}
},
"nix-pypi-fetcher": {
"flake": false,
"locked": {
"lastModified": 1669065297,
"narHash": "sha256-UStjXjNIuIm7SzMOWvuYWIHBkPUKQ8Id63BMJjnIDoA=",
"owner": "DavHau",
"repo": "nix-pypi-fetcher",
"rev": "a9885ac6a091576b5195d547ac743d45a2a615ac",
"type": "github"
},
"original": {
"owner": "DavHau",
"repo": "nix-pypi-fetcher",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1665580254,
"narHash": "sha256-hO61XPkp1Hphl4HGNzj1VvDH5URt7LI6LaY/385Eul4=",
"owner": "NixOS",
"lastModified": 1709230475,
"narHash": "sha256-QI/0GiTvWxhBJ/bpredarfAUARnP6zE1vCOifsZ220A=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "f634d427b0224a5f531ea5aa10c3960ba6ec5f0f",
"rev": "b5f6e3881acf8ca8a35b8cdb8d4021e5bd469a4e",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"dir": "lib",
"lastModified": 1675183161,
"narHash": "sha256-Zq8sNgAxDckpn7tJo7V1afRSk2eoVbu3OjI1QklGLNg=",
"lastModified": 1706550542,
"narHash": "sha256-UcsnCG6wx++23yeER4Hg18CXWbgNpqNXcHIo5/1Y+hc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e1e1b192c1a5aab2960bf0a0bd53a2e8124fa18e",
"rev": "97b17f32362e475016f942bbdfda4a4a72a8a652",
"type": "github"
},
"original": {
@ -346,83 +121,50 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1673800717,
"narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=",
"lastModified": 1704874635,
"narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f",
"rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-22.11",
"ref": "nixos-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1677050843,
"narHash": "sha256-3fcFxn58eCtrXrVPeW/nAg6NR5wUERVEf8zOtjPDzuM=",
"owner": "nixos",
"lastModified": 1704842529,
"narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "9e0eed654c705c7cafe192a8eba1610217f70544",
"rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5",
"type": "github"
},
"original": {
"owner": "nixos",
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1671271357,
"narHash": "sha256-xRJdLbWK4v2SewmSStYrcLa0YGJpleufl44A19XSW8k=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "40f79f003b6377bd2f4ed4027dde1f8f922995dd",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"poetry2nix": {
"flake": false,
"locked": {
"lastModified": 1666918719,
"narHash": "sha256-BkK42fjAku+2WgCOv2/1NrPa754eQPV7gPBmoKQBWlc=",
"owner": "nix-community",
"repo": "poetry2nix",
"rev": "289efb187123656a116b915206e66852f038720e",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "1.36.0",
"repo": "poetry2nix",
"type": "github"
}
},
"pre-commit": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"gitignore": "gitignore",
"nixpkgs": "nixpkgs_3",
"nixpkgs": "nixpkgs_2",
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1676879534,
"narHash": "sha256-HU4RXcwsAX1u7AUbGOBDxkYQkeODcn+HZjXqKa1y/hk=",
"lastModified": 1708018599,
"narHash": "sha256-M+Ng6+SePmA8g06CmUZWi1AjG2tFBX9WCXElBHEKnyM=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "c9495f017f67a11e9c9909b032dc7762dfc853cf",
"rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431",
"type": "github"
},
"original": {
@ -431,71 +173,26 @@
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-utils": [
"d2n",
"flake-utils-pre-commit"
],
"nixpkgs": [
"d2n",
"nixpkgs"
]
},
"locked": {
"lastModified": 1646153636,
"narHash": "sha256-AlWHMzK+xJ1mG267FdT8dCq/HvLCA6jwmx2ZUy5O8tY=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "b6bc0b21e1617e2b07d8205e7fae7224036dfa4b",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"pruned-racket-catalog": {
"flake": false,
"locked": {
"lastModified": 1672537287,
"narHash": "sha256-SuOvXVcLfakw18oJB/PuRMyvGyGG1+CQD3R+TGHIv44=",
"owner": "nix-community",
"repo": "pruned-racket-catalog",
"rev": "c8b89557fb53b36efa2ee48a769c7364df0f6262",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "catalog",
"repo": "pruned-racket-catalog",
"type": "github"
}
},
"root": {
"inputs": {
"d2n": "d2n",
"flake-parts": "flake-parts_2",
"flake-parts": "flake-parts",
"nix-filter": "nix-filter",
"nixpkgs": "nixpkgs_2",
"nixpkgs": "nixpkgs",
"pre-commit": "pre-commit"
}
},
"rust-analyzer-src": {
"flake": false,
"systems": {
"locked": {
"lastModified": 1657557289,
"narHash": "sha256-PRW+nUwuqNTRAEa83SfX+7g+g8nQ+2MMbasQ9nt6+UM=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "caf23f29144b371035b864a1017dbc32573ad56d",
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "rust-lang",
"ref": "nightly",
"repo": "rust-analyzer",
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}

View file

@ -1,19 +1,16 @@
{
description = "nobbz.dev - Website";
description = "srx.digital - Website";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable";
d2n.url = "github:nix-community/dream2nix";
d2n.inputs.all-cabal-json.follows = "nixpkgs";
nix-filter.url = "github:numtide/nix-filter";
flake-parts.url = "github:hercules-ci/flake-parts";
nix-filter.url = "github:numtide/nix-filter";
pre-commit.url = "github:cachix/pre-commit-hooks.nix";
};
outputs = {
d2n,
nix-filter,
flake-parts,
nix-filter,
pre-commit,
...
} @ inputs: let
@ -22,29 +19,30 @@
flake-parts.lib.mkFlake {inherit inputs;} {
inherit systems;
imports = [d2n.flakeModuleBeta pre-commit.flakeModule ./nix/site.nix ./nix/hooks.nix];
imports = [
pre-commit.flakeModule
./nix/hooks.nix
./nix/devshell.nix
./nix/package.nix
];
dream2nix.config.projectRoot = ./.;
perSystem = {
self',
config,
pkgs,
self',
inputs',
system,
...
}: {
apps.serve.program = "${pkgs.writeShellScript "serve" ''
${pkgs.miniserve}/bin/miniserve -p 3001 --index index.html ${self'.packages.default}
''}";
apps = {
serve.program = "${pkgs.writeShellScript "serve" ''
${pkgs.miniserve}/bin/miniserve -p 3001 --index index.html ${self'.packages.default}
''}";
};
packages.default = self'.packages.srx_dev;
devShells.default = pkgs.mkShell {
packages = builtins.attrValues {
inherit (pkgs) yarn;
inherit (pkgs) alejandra nil;
};
shellHook = config.pre-commit.installationScript;
packages = {
default = self'.packages.srx-digital;
};
};
};

View file

@ -1,3 +0,0 @@
builds:
exclude:
- 'checks.*.pre-commit'

25
nix/devshell.nix Normal file
View file

@ -0,0 +1,25 @@
{
perSystem = {
pkgs,
config,
...
}: {
devShells.default = pkgs.mkShell {
packages = with pkgs; [
cocogitto
yarn
yarn2nix
alejandra
nil
nodejs
nodePackages.typescript
nodePackages.typescript-language-server
vscodium
vscode-extensions.jnoortheen.nix-ide
vscode-extensions.kamadorueda.alejandra
vscode-extensions.astro-build.astro-vscode
];
shellHook = config.pre-commit.installationScript;
};
};
}

View file

@ -1,13 +1,10 @@
{self, ...}: {
{
perSystem = {pkgs, ...}: {
pre-commit.check.enable = true;
pre-commit.settings.hooks.nixpkgs-fmt.enable = false;
pre-commit.settings.hooks.alejandra.enable = true;
pre-commit.settings.hooks.prettier.enable = true;
pre-commit.settings.hooks.eslint.enable = true;
pre-commit.settings.hooks.eslint.pass_filenames = false;
pre-commit.settings.settings.eslint.binPath = "${pkgs.nodePackages.eslint}/bin/eslint src";
pre-commit.settings.settings.eslint.extensions = "\\.(js|ts|jsx|tsx|astro|md|mdx|cjs|ts)$";
pre-commit = {
check.enable = true;
settings = {
hooks = {};
};
};
};
}

65
nix/package.nix Normal file
View file

@ -0,0 +1,65 @@
{inputs, ...}: let
inherit (inputs.nix-filter.lib) filter inDirectory matchExt;
in {
perSystem = {
config,
pkgs,
inputs',
...
}: {
packages.srx-digital = pkgs.mkYarnPackage rec {
name = "srx-digital";
src = filter {
root = ../.;
include = [
(inDirectory "public")
(inDirectory "src")
(matchExt "js")
(matchExt "cjs")
(matchExt "mjs")
(matchExt "json")
(matchExt "ts")
../package.json
../yarn.lock
];
};
CI = "true";
doDist = false;
packageJSON = ../package.json;
yarnLock = ../yarn.lock;
yarnFlags = ["--offline" "--production=true"];
pkgConfig.sharp = {
nativeBuildInputs = with pkgs; [
pkg-config
python3
nodePackages.node-gyp
];
buildInputs = with pkgs; [
vips.dev
];
postInstall = ''
${pkgs.nodePackages.node-gyp}/bin/node-gyp --node-dir=${pkgs.nodePackages.nodejs}/include/node rebuild
'';
};
postConfigure = "export HOME=$(mktemp -d)";
buildPhase = ''
runHook preBuild
(
shopt -s dotglob
yarn --offline build
)
runHook postBuild
'';
installPhase = "mv -v deps/${name}/dist \${out}";
};
};
}

View file

@ -1,35 +0,0 @@
{inputs, ...}: let
inherit (inputs.nix-filter.lib) filter inDirectory matchExt;
in {
perSystem = {config, ...}: {
dream2nix.inputs.self = {
source = filter {
root = ./..;
include = [
(inDirectory "src")
(inDirectory "public")
(matchExt "js")
(matchExt "cjs")
(matchExt "mjs")
../package.json
../yarn.lock
];
};
projects.srx_dev = {
name = "srx_dev";
subsystem = "nodejs";
translator = "yarn-lock";
subsystemInfo.nodejs = 18;
};
packageOverrides.srx_dev.copySrx_dev = {
installPhase = ''
mkdir -p $out
cp -rv ./dist/* $out
'';
};
};
packages.srx_dev = config.dream2nix.outputs.self.packages.srx_dev;
};
}

View file

@ -1,43 +1,48 @@
{
"name": "srx.dev",
"version": "0.0.1",
"private": true,
"scripts": {
"build": "astro build",
"dev": "astro dev",
"preview": "astro preview",
"start": "astro dev",
"sync": "astro sync"
},
"devDependencies": {
"@astrojs/mdx": "^0.18.2",
"@astrojs/rss": "^2.3.1",
"@astrojs/sitemap": "^1.2.1",
"@astrojs/tailwind": "^3.1.1",
"@types/lodash": "^4.14.192",
"@types/luxon": "^3.2.0",
"@types/marked": "^4.0.8",
"@types/seedrandom": "^3.0.2",
"@typescript-eslint/eslint-plugin": "^5.46.0",
"@typescript-eslint/parser": "^5.46.0",
"astro-forms": "^1.0.11",
"astro-icon": "^0.8.0",
"astro-robots-txt": "^0.4.0",
"astro": "^2.1.8",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-astro": "^0.26.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-n": "^15.6.0",
"eslint-plugin-promise": "^6.1.0",
"eslint": "^8.29.0",
"lodash": "^4.17.21",
"luxon": "^3.0.4",
"marked": "^4.2.4",
"prettier-plugin-astro": "^0.8.0",
"prettier": "^2.8.1",
"sanitize-html": "^2.8.0",
"seedrandom": "^3.0.5",
"tailwindcss": "^3.0.24"
},
"dependencies": {}
}
"name": "srx-digital",
"description": "Static website build with Astro and Nix",
"type": "module",
"version": "0.0.1",
"author": "Sebastian Wendel",
"license": "MIT",
"keywords": [
"astro",
"reactjs",
"tailwindcss"
],
"private": true,
"repository": {
"url": "gitea@https://code.srx.digital:srx/srx.astro.nix.git",
"type": "git"
},
"bugs": {
"url": "https://code.srx.digital/srx/srx.astro.nix/issues"
},
"scripts": {
"dev": "TAILWIND_MODE=watch astro dev",
"start": "TAILWIND_MODE=watch astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.5.6",
"@astrojs/react": "^3.0.10",
"@astrojs/tailwind": "^5.1.0",
"@fontsource-variable/literata": "^5.0.20",
"@fontsource-variable/manrope": "^5.0.19",
"@fontsource-variable/martian-mono": "^5.0.12",
"@tailwindcss/forms": "^0.5.7",
"@tailwindcss/typography": "^0.5.10",
"@types/react-dom": "^18.2.19",
"@types/react": "^18.2.61",
"astro": "^4.4.9",
"lucide-react": "^0.344.0",
"lucide-static": "^0.344.0",
"react-dom": "^18.2.0",
"react": "^18.2.0",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3",
"vite-plugin-svgr": "^4.2.0"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View file

@ -1 +0,0 @@
<svg height="640" width="1440" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset=".58" stop-opacity="0"/><stop offset="1"/></linearGradient><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="793.5" x2="759.5" xlink:href="#a" y1="261.5" y2="149.5"/><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="644.19" x2="645.54" xlink:href="#a" y1="398.02" y2="267.7"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="547" x2="522.36" xlink:href="#a" y1="457.27" y2="342.85"/><g clip-rule="evenodd" fill-rule="evenodd" opacity=".15"><path d="m439.57 249.55a2149.47 2149.47 0 0 1 1193.87-182.45l-12.48 93.17a2055.46 2055.46 0 0 0 -1141.66 174.47l-454.24 211.86-39.73-85.2z" fill="url(#b)"/><path d="m272.3 266.93a2393.36 2393.36 0 0 1 1328.96 205.6l-44.42 94.78a2288.7 2288.7 0 0 0 -1270.84-196.61l-553.29 73.05-13.7-103.77z" fill="url(#c)" opacity=".56"/><path d="m195.26 416.13a2149.46 2149.46 0 0 1 1204.86-83.21l-20.13 91.82a2055.46 2055.46 0 0 0 -1152.17 79.56l-470.18 173.62-32.56-88.18 470.18-173.62z" fill="url(#d)"/></g><path d="m-258.15 719.56 1743.12-517.56 182.93 616.12-1743.1 517.56z" fill="#090b11"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1440" height="640"><g opacity=".15"><path fill="url(#a)" d="M439.57 249.55A2149.47 2149.47 0 0 1 1633.44 67.1l-12.48 93.17A2055.46 2055.46 0 0 0 479.3 334.74L25.06 546.6l-39.73-85.2z"/><path fill="url(#b)" d="M272.3 265.93a2393.36 2393.36 0 0 1 1328.96 205.6l-44.42 94.78A2288.7 2288.7 0 0 0 286 369.7l-553.29 73.05-13.7-103.77z" opacity=".56"/><path fill="url(#c)" d="M195.26 416.13a2149.47 2149.47 0 0 1 1204.86-83.21l-20.13 91.82A2055.46 2055.46 0 0 0 227.82 504.3l-470.18 173.62-32.56-88.18 470.18-173.62z"/></g><path fill="#fff" d="M-258 718.56 1485.12 201l182.93 616.12-1743.11 517.56z"/><defs><linearGradient id="d"><stop offset=".58" stop-opacity="0"/><stop offset="1"/></linearGradient><linearGradient xlink:href="#d" id="a" x1="793.5" x2="759.5" y1="261.5" y2="149.5" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#d" id="b" x1="644.19" x2="645.54" y1="397.02" y2="266.7" gradientUnits="userSpaceOnUse"/><linearGradient xlink:href="#d" id="c" x1="547" x2="522.36" y1="457.27" y2="342.85" gradientUnits="userSpaceOnUse"/></defs></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 639 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 749 B

After

Width:  |  Height:  |  Size: 5.4 KiB

View file

@ -1,8 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:base"],
"assignees": ["Nobbz"],
"rangeStrategy": "update-lockfile",
"schedule": ["* 0-5 * * *"],
"nix": { "enabled": true }
}

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" version="1.1" viewBox="0 0 160 80" enable-background="new 0 0 160 80" class="logo">
<title>Das Logo formt aus den Buchstaben "s", "r", und "x" ein gleichschenkliges Dreieck mit ergänzenden Kreisen, symbolisiert die Einheit von "You, me, technology" und steht für Dynamik, Zusammenarbeit und Harmonie.</title>
<path id="wordmark" d="m14.699 0c-4.6 0-8.0988 0.89961-10.799 2.5996-2.5 1.9-3.8008 4.5008-3.8008 7.8008 0 2.8 0.90117 5 2.7012 6.5 1.8 1.6 4.6996 2.5996 8.5996 3.0996l4.9004 0.69922c2.4 0.4 4.0992 0.90156 5.1992 1.6016 1.1 0.7 1.6992 1.6988 1.6992 2.7988 0 1.8-0.79922 3.1-2.1992 4s-3.5008 1.4004-6.3008 1.4004c-2.7 0-4.8-0.49961-6.5-1.5996-1.6-1.1-2.6992-2.6-3.1992-4.5v0.19922h-5c0.2 3.5 1.5992 6.2012 4.1992 8.2012 2.5 1.9 6 2.8984 10.5 2.8984 3 0 5.5-0.39922 7.5-1.1992 2.1-0.9 3.7008-2.0996 4.8008-3.5996 1.1-1.6 1.6992-3.5012 1.6992-5.7012 0-2.8-0.89922-5-2.6992-6.5-1.7-1.5-4.6-2.4996-8.5-3.0996l-4.9004-0.69922c-2.4-0.3-4.0992-0.8-5.1992-1.5-1.1-0.7-1.7012-1.7008-1.7012-2.8008-1e-7 -1.8 0.80078-3.1 2.3008-4 1.6-0.9 3.7992-1.4004 6.6992-1.4004 2.8-1e-7 5.0012 0.60078 6.7012 1.8008 1.7 1.1 2.7988 2.8 3.2988 5h5c-0.2-3.8-1.5992-6.7008-4.1992-8.8008-2.6-2.1-6.2008-3.1992-10.801-3.1992zm49.801 0c-1.7 0-3.2 0.4-4.5 1s-2.3996 1.4996-3.0996 2.5996h-1.5996v-2.7988h-13.602v5.1992h8.5v23.699h-7.2988v5.1016h24.9v-5.1016h-12.201v-13.1c0-3.8 0.60078-6.6 1.8008-8.5 1.2-1.9 2.9988-2.9004 5.2988-2.9004 3.9 0 5.8008 2.2016 5.8008 6.6016v3.6992h5.6992v-4.5996c0-3.4-0.89961-6.1-2.5996-8-1.7-1.9-4.0996-2.9004-7.0996-2.9004zm-45.199 46.1 11.898 17.701-11.199 16.199h6.1992l8.6016-12.4 0.5-1.4004h0.5l0.5 1.4004 8.5 12.4h6.6992l-11.301-16.6 12-17.201h-6.1992l-9.5 13.5-0.5 1.4004h-0.5l-0.5-1.4004-9.0996-13.6h-6.5996z"/>
<path id="picturemark" d="m117 0c-3 0-6.0008 0.7-8.8008 2-2.7 1.3-5.1996 3.2-7.0996 5.5-1.9 2.3-3.2996 5.1-4.0996 8s-0.90078 6-0.30078 9l6.7012-11.5c1.4-2.4 3.2992-4.4008 5.6992-5.8008 2.4-1.4 5.1004-2.0996 7.9004-2.0996s5.5004 0.69961 7.9004 2.0996c2.4 1.4 4.3992 3.4008 5.6992 5.8008l6.5996 11.4c0.6-3 0.50117-6-0.29883-9-0.8-2.9-2.0996-5.7-4.0996-8-1.9-2.3-4.4016-4.2-7.1016-5.5-2.7-1.2-5.6992-1.9004-8.6992-1.9004zm-0.09961 10.4c-2.7 0-5.3008 1.1-7.3008 3-1.8 1.9-2.9004 4.4992-2.9004 7.1992 0 2 0.60117 4.0012 1.7012 5.7012 1.1 1.7 2.6996 2.9988 4.5996 3.7988 1.9 0.8 3.9004 0.99961 5.9004 0.59961 2-0.4 3.7988-1.3988 5.2988-2.7988 1.4-1.4 2.4008-3.3008 2.8008-5.3008s0.20039-4.1004-0.59961-5.9004c-0.8-1.9-2.1008-3.4996-3.8008-4.5996s-3.6992-1.6992-5.6992-1.6992zm0.19922 5.2988c1.3 0 2.6 0.5 3.5 1.5 0.9 0.8 1.4004 2.1004 1.4004 3.4004 0 1-0.30078 1.9008-0.80078 2.8008-0.5 0.8-1.2992 1.4988-2.1992 1.7988-0.9 0.4-1.9004 0.50078-2.9004 0.30078s-1.9-0.70039-2.5-1.4004c-0.7-0.7-1.2004-1.6-1.4004-2.5-0.2-1-0.09922-2.0004 0.30078-2.9004s1.0008-1.6992 1.8008-2.1992 1.7988-0.80078 2.7988-0.80078zm-14.6 9.6016-3.3008 5.5996c1.8 3.1 4.4 5.7996 7.5 7.5996s6.7008 2.8008 10.301 2.8008 7.2008-1.0008 10.301-2.8008c3.1-1.9 5.7-4.4996 7.5-7.5996l-3.3008-5.5996c-1 3.1-2.9 5.7992-5.5 7.6992s-5.8 3-9 3-6.4-1-9-3c-2.6-1.9-4.6-4.5992-5.5-7.6992zm36.9 13.5c-3.6 0-7.2008 0.89883-10.301 2.7988-3.1 1.8-5.7 4.4-7.5 7.5s-2.7988 6.7008-2.7988 10.301c0 3.6 0.99883 7.1988 2.7988 10.299h6.5c-2.5-2.8-4-6.4988-4-10.299 0-2.3 0.5-4.4996 1.5-6.5996s2.4012-3.9008 4.2012-5.3008 3.8996-2.4 6.0996-3c2.2-0.5 4.4988-0.5 6.7988 0l-3.2988-5.6992zm-44.125 0.09375c-0.22485-0.002295-0.45078-3.9e-4 -0.67578 0.00586l-3.2988 5.6992c3.2-0.7 6.4984-0.39961 9.3984 0.90039 3 1.3 5.4016 3.5008 7.1016 6.3008 1.6 2.8 2.3 6.0988 2 9.2988-0.3 3.2-1.7004 6.3012-3.9004 8.7012h6.5c1.8-3.1 2.7988-6.7008 2.7988-10.301s-0.89883-7.2008-2.7988-10.301c-1.8-3.1-4.3996-5.7-7.5996-7.5-2.8125-1.7812-6.1526-2.7703-9.5254-2.8047zm-7.4746 1.1055c-2.9 1-5.5016 2.5992-7.6016 4.6992-2.2 2.1-3.7984 4.7-4.8984 7.5s-1.5012 5.9004-1.2012 8.9004c0.3 3 1.2012 5.8996 2.7012 8.5996 1.5 2.6 3.5996 4.9016 6.0996 6.6016 2.5 1.7 5.2988 2.8984 8.2988 3.3984 3 0.5 6 0.4 9-0.5 2.9-0.8 5.6004-2.2992 7.9004-4.1992h-13.299c-2.8 0-5.5004-0.69961-7.9004-2.0996-2.4-1.3-4.3012-3.3012-5.7012-5.7012-1.4-2.4-2.0996-5.0984-2.0996-7.8984s0.69961-5.5004 2.0996-7.9004l6.6016-11.4zm58.398 0 6.6016 11.4c1.4 2.4 2.0996 5.1004 2.0996 7.9004s-0.69961 5.4984-2.0996 7.8984c-1.4 2.4-3.4008 4.4008-5.8008 5.8008s-5.1004 2.0996-7.9004 2.0996h-13.1c2.3 2 5.0004 3.4012 7.9004 4.2012s6 1 9 0.5c3-0.5 5.7988-1.7004 8.2988-3.4004 2.5-1.7 4.6016-3.9996 6.1016-6.5996 1.5-2.6 2.3992-5.5016 2.6992-8.6016 0.3-3-0.19922-5.9984-1.1992-8.8984-1-2.8-2.7004-5.4-4.9004-7.5-2.2-2.2-4.8012-3.8008-7.7012-4.8008zm-6.7988 9.1992c-2.7 0-5.3008 1.1-7.3008 3-1.9 1.9-2.9004 4.5012-2.9004 7.2012 0 2 0.60117 3.9992 1.7012 5.6992 1.1 1.7 2.6996 3.0008 4.5996 3.8008 1.9 0.8 3.9004 0.99961 5.9004 0.59961s3.7988-1.4008 5.2988-2.8008c1.4-1.4 2.4008-3.2988 2.8008-5.2988s0.20039-4.1004-0.59961-5.9004c-0.8-1.9-2.1008-3.4996-3.8008-4.5996s-3.6992-1.7012-5.6992-1.7012zm-45.072 0.003906c-1.2617 0.03125-2.5039 0.29688-3.6289 0.79688-1.9 0.8-3.4996 2.1008-4.5996 3.8008-1.1 1.7-1.6992 3.6992-1.6992 5.6992 0 2.7 1.1 5.3008 3 7.3008s4.4992 2.8984 7.1992 2.8984c2 0 4.0012-0.59922 5.7012-1.6992 1.7-1.1 2.9988-2.6996 3.7988-4.5996s0.99961-3.9004 0.59961-5.9004-1.3988-3.8008-2.7988-5.3008c-1.4-1.4-3.3008-2.3988-5.3008-2.7988-0.75-0.15-1.5145-0.21602-2.2715-0.19727zm0.27148 5.2969c1 0 2.0008 0.30078 2.8008 0.80078 0.8 0.5 1.4988 1.2992 1.7988 2.1992 0.4 0.9 0.50078 1.9004 0.30078 2.9004s-0.70039 1.8996-1.4004 2.5996c-0.7 0.7-1.5996 1.2004-2.5996 1.4004-1 0.2-2.0004 0.099218-2.9004-0.30078-0.9-0.4-1.6992-0.99883-2.1992-1.7988-0.5-0.8-0.80078-1.8008-0.80078-2.8008 0-1.3 0.5-2.6 1.5-3.5 0.9-1 2.2-1.5 3.5-1.5zm44.9 0c1.3 0 2.6 0.5 3.5 1.5 0.9 0.8 1.4004 2.1004 1.4004 3.4004 0 1-0.30078 1.8988-0.80078 2.7988-0.5 0.8-1.2992 1.5008-2.1992 1.8008-0.9 0.4-1.9004 0.50078-2.9004 0.30078s-1.9-0.70039-2.5-1.4004c-0.7-0.7-1.2004-1.6-1.4004-2.5-0.2-1-0.09922-2.0004 0.30078-2.9004s0.99883-1.6992 1.7988-2.1992c0.8-0.5 1.8008-0.80078 2.8008-0.80078z"/>
</svg>

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View file

@ -1,56 +0,0 @@
---
interface Props {
href: string;
}
const { href } = Astro.props;
---
<a href={href}><slot /></a>
<style>
a {
position: relative;
display: flex;
place-content: center;
text-align: center;
padding: 0.56em 2em;
gap: 0.8em;
color: var(--accent-text-over);
text-decoration: none;
line-height: 1.1;
border-radius: 999rem;
overflow: hidden;
background: var(--gradient-accent-orange);
box-shadow: var(--shadow-md);
white-space: nowrap;
}
@media (min-width: 20em) {
a {
font-size: var(--text-lg);
}
}
/* Overlay for hover effects. */
a::after {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
transition: background-color var(--theme-transition);
mix-blend-mode: overlay;
}
a:focus::after,
a:hover::after {
background-color: hsla(var(--gray-999-basis), 0.3);
}
@media (min-width: 50em) {
a {
padding: 1.125rem 2.5rem;
font-size: var(--text-xl);
}
}
</style>

View file

@ -1,46 +0,0 @@
---
import CallToAction from './CallToAction.astro';
import Icon from './Icon.astro';
---
<aside>
<h2>Interested in working together?</h2>
<CallToAction href="mailto:h3ll0@srx.dev">
Send Me a Message
<Icon icon="paper-plane-tilt" size="1.2em" />
</CallToAction>
</aside>
<style>
aside {
display: flex;
flex-direction: column;
align-items: center;
gap: 3rem;
border-top: 1px solid var(--gray-800);
border-bottom: 1px solid var(--gray-800);
padding: 5rem 1.5rem;
background-color: var(--gray-999_40);
box-shadow: var(--shadow-sm);
}
h2 {
font-size: var(--text-xl);
text-align: center;
max-width: 15ch;
}
@media (min-width: 50em) {
aside {
padding: 7.5rem;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
h2 {
font-size: var(--text-3xl);
text-align: left;
}
}
</style>

View file

@ -1,74 +1,81 @@
---
import Icon from './Icon.astro';
const currentYear = new Date().getFullYear();
import SRXLogo from "@srx/assets/srx-digital-logo.svg";
import SrxLogoR from "@srx/assets/srx-digital-logo.svg?react";
import { Image } from "astro:assets";
import {
GitFork,
AtSign,
GithubIcon,
Phone,
Linkedin,
MessagesSquare,
MessageSquareQuote,
} from "lucide-react";
---
<footer>
<div class="group">
<p>
Designed & Developed in Hamburg with <a href="https://astro.build/">Astro</a>
<Icon icon="rocket-launch" size="1.2em" />
<div class="contact">
<h3>
Du möchtest mit mir zusammenarbeiten? Ich freue mich über deinen
Kontakt.
</h3>
<br />
<p class="socials">
<a href="tel:+4940285387360"><Phone /></a>
<a href="mailto:latigid.xrs@srx.digital"><AtSign /></a>
<a href="https://matrix.to/#/@swendel:curious.bio"
><MessagesSquare /></a
>
<a href="https://social.curious.bio/@swendel"
><MessageSquareQuote /></a
>
<a href="https://code.srx.digital/explore/repos"><GitFork /></a>
<a href="https://github.com/SebastianWendel"><GithubIcon /></a>
<a href="https://www.linkedin.com/in/sebastian-wendel-935b8a9a/"
><Linkedin /></a
>
</p>
<p>&copy; {currentYear} Sebastian Wendel</p>
</div>
<p class="socials">
<a href="https://twitter.com/me"> Twitter</a>
<a href="https://github.com/me"> GitHub</a>
<a href="https://codepen.io/me"> CodePen</a>
</p>
<div class="address">
<div>
srx digital<br />
Development & Operations<br />
</div>
<br />
<address>
Sebastian Wendel<br />
Wohlwillstraße 2<br />
D-20359 Hamburg<br />
</address>
</div>
<SrxLogoR />
</footer>
<style>
footer {
display: flex;
flex-direction: column;
gap: 3rem;
margin-top: auto;
padding: 3rem 2rem 3rem;
text-align: center;
color: var(--gray-400);
font-size: var(--text-sm);
@apply flex flex-col md:flex-row items-start bg-default text-white;
}
footer a {
color: var(--gray-400);
text-decoration: 1px solid underline transparent;
text-underline-offset: 0.25em;
transition: text-decoration-color var(--theme-transition);
address {
@apply not-italic mt-8 md:mt-0;
}
footer a:hover,
footer a:focus {
text-decoration-color: currentColor;
.address {
@apply flex flex-col lg:flex-grow;
}
.group {
display: flex;
flex-direction: column;
gap: 0.5rem;
.contact {
@apply flex flex-col lg:flex-grow;
}
.socials {
display: flex;
justify-content: center;
gap: 1rem;
flex-wrap: wrap;
@apply flex items-stretch gap-5;
}
@media (min-width: 50em) {
footer {
flex-direction: row;
justify-content: space-between;
padding: 2.5rem 5rem;
}
.group {
flex-direction: row;
gap: 1rem;
flex-wrap: wrap;
}
.socials {
justify-content: flex-end;
}
.logo {
@apply fill-primary h-10;
}
</style>

View file

@ -1,65 +0,0 @@
---
interface Props {
variant?: 'offset' | 'small';
}
const { variant } = Astro.props;
---
<ul class:list={['grid', { offset: variant === 'offset', small: variant === 'small' }]}>
<slot />
</ul>
<style>
.grid {
display: grid;
grid-auto-rows: 1fr;
gap: 1rem;
list-style: none;
padding: 0;
}
.grid.small {
grid-template-columns: 1fr 1fr;
gap: 1.5rem;
}
/* If last row contains only one item, make it span both columns. */
.grid.small > :global(:last-child:nth-child(odd)) {
grid-column: 1 / 3;
}
@media (min-width: 50em) {
.grid {
grid-template-columns: 1fr 1fr;
gap: 4rem;
}
.grid.offset {
--row-offset: 7.5rem;
padding-bottom: var(--row-offset);
}
/* Shift first item in each row vertically to create staggered effect. */
.grid.offset > :global(:nth-child(odd)) {
transform: translateY(var(--row-offset));
}
/* If last row contains only one item, display it in the second column. */
.grid.offset > :global(:last-child:nth-child(odd)) {
grid-column: 2 / 3;
transform: none;
}
.grid.small {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 2rem;
}
.grid.small > :global(*) {
flex-basis: 20rem;
}
}
</style>

View file

@ -1,54 +1,54 @@
---
interface Props {
title: string;
tagline?: string;
align?: 'start' | 'center';
}
const { align = 'center', tagline, title } = Astro.props;
import { Picture } from "astro:assets";
import { LinkButton } from "@srx/components";
import SwendelPortrait from "@srx/assets/swendel_portrait.webp";
---
<header class:list={['hero stack gap-4', align]}>
<div class="stack gap-2">
<h1 class="title">{title}</h1>
{tagline && <p class="tagline">{tagline}</p>}
</div>
<slot />
<header>
<div class="hero">
<h1>You, me, technology.</h1>
<p>
Hallo! Ich bin Sebastian aus Hamburg, spezialisiert auf
Softwareentwicklung und Plattformengineering. Meine Welt sind Linux,
Container, Cloud und Hardware, besonders wenn's um Open-Source geht.
Ich helfe Firmen, ihre Digitalstrategien erfolgreich zu realisieren.
</p>
<LinkButton
className={"h-10"}
caption="Schreib mir"
href={"mailto:latigid.xrs@srx.digital?subject=Kontakt%20%C3%BCber%20die%20Website"}
/>
<slot />
</div>
<Picture
src={SwendelPortrait}
formats={["jpeg", "webp"]}
widths={[240, 540, 720, SwendelPortrait.width]}
sizes={`(max-width: 360px) 240px, (max-width: 720px) 540px, (max-width: 1600px) 720px, ${SwendelPortrait.width}px`}
alt="Porträt von Sebastian Wendel"
/>
</header>
<style>
.hero {
font-size: var(--text-lg);
text-align: center;
}
header {
@apply flex flex-col md:flex-row items-center;
}
.title,
.tagline {
max-width: 37ch;
margin-inline: auto;
}
h1 {
@apply mb-4;
}
.title {
font-size: var(--text-3xl);
color: var(--gray-0);
}
p {
@apply mb-8 leading-relaxed text-xl;
}
@media (min-width: 50em) {
.hero {
font-size: var(--text-xl);
}
img {
@apply rounded-xl;
}
.start {
text-align: start;
}
.start .title,
.start .tagline {
margin-inline: unset;
}
.title {
font-size: var(--text-5xl);
}
}
.hero {
@apply flex flex-col lg:flex-grow;
}
</style>

View file

@ -1,56 +0,0 @@
---
import type { HTMLAttributes } from 'astro/types';
import { iconPaths } from './IconPaths';
export interface Props {
icon: keyof typeof iconPaths;
color?: string;
gradient?: boolean;
size?: string;
}
const { color = 'currentcolor', gradient, icon, size } = Astro.props;
const iconPath = iconPaths[icon];
const attrs: HTMLAttributes<'svg'> = {};
if (size) attrs.style = { '--size': size };
const gradientId = 'icon-gradient-' + Math.round(Math.random() * 10e12).toString(36);
---
<svg
xmlns="http://www.w3.org/2000/svg"
width="40"
height="40"
viewBox="0 0 256 256"
aria-hidden="true"
stroke={gradient ? `url(#${gradientId})` : color}
fill={gradient ? `url(#${gradientId})` : color}
{...attrs}
>
<g set:html={iconPath} />
{
gradient && (
<linearGradient
id={gradientId}
x1="23"
x2="235"
y1="43"
y2="202"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="var(--gradient-stop-1)" />
<stop offset=".5" stop-color="var(--gradient-stop-2)" />
<stop offset="1" stop-color="var(--gradient-stop-3)" />
</linearGradient>
)
}
</svg>
<style>
svg {
vertical-align: middle;
width: var(--size, 1em);
height: var(--size, 1em);
}
</style>

View file

@ -1,38 +0,0 @@
/**
* Icons adapted from https://phosphoricons.com/
*
* Want to add more?
* 1. Find the icon you want on Phosphor Icons.
* 2. Click Copy SVG.
* 3. Paste the SVG code in your editor.
* 4. Remove the `<svg>` wrapper so you only have elements like `<path>`, `<circle>`, `<rect>` etc.
* 5. Remove any `stroke="#000000"` attributes
* 6. Replace any `fill="#000000"` attributes with `stroke="none"`
* (or add `stroke="none"` on shapes with no `fill` or `stroke` specified).
*/
export const iconPaths = {
'terminal-window': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m80 96 40 32-40 32m56 0h40"/><rect width="192" height="160" x="32" y="48" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16.97" rx="8.5"/>`,
trophy: `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M56 56v55.1c0 39.7 31.8 72.6 71.5 72.9a72 72 0 0 0 72.5-72V56a8 8 0 0 0-8-8H64a8 8 0 0 0-8 8Zm40 168h64m-32-40v40"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M198.2 128h9.8a32 32 0 0 0 32-32V80a8 8 0 0 0-8-8h-32M58 128H47.9a32 32 0 0 1-32-32V80a8 8 0 0 1 8-8h32"/>`,
strategy: `<circle cx="68" cy="188" r="28" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m40 72 40 40m0-40-40 40m136 56 40 40m0-40-40 40M136 80V40h40"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m136 40 16 16c40 40 8 88-24 96"/>`,
'paper-plane-tilt': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M210.3 35.9 23.9 88.4a8 8 0 0 0-1.2 15l85.6 40.5a7.8 7.8 0 0 1 3.8 3.8l40.5 85.6a8 8 0 0 0 15-1.2l52.5-186.4a7.9 7.9 0 0 0-9.8-9.8Zm-99.4 109.2 45.2-45.2"/>`,
'arrow-right': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M40 128h176m-72-72 72 72-72 72"/>`,
'arrow-left': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M216 128H40m72-72-72 72 72 72"/>`,
code: `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m64 88-48 40 48 40m128-80 48 40-48 40M160 40 96 216"/>`,
'microphone-stage': `<circle cx="168" cy="88" r="64" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m213.3 133.3-90.6-90.6M100 156l-12 12m16.8-70.1L28.1 202.5a7.9 7.9 0 0 0 .8 10.4l14.2 14.2a7.9 7.9 0 0 0 10.4.8l104.6-76.7"/>`,
'pencil-line': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M96 216H48a8 8 0 0 1-8-8v-44.7a7.9 7.9 0 0 1 2.3-5.6l120-120a8 8 0 0 1 11.4 0l44.6 44.6a8 8 0 0 1 0 11.4Zm40-152 56 56"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M216 216H96l-55.5-55.5M164 92l-96 96"/>`,
'rocket-launch': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M94.1 184.6c-11.4 33.9-56.6 33.9-56.6 33.9s0-45.2 33.9-56.6m124.5-56.5L128 173.3 82.7 128l67.9-67.9C176.3 34.4 202 34.7 213 36.3a7.8 7.8 0 0 1 6.7 6.7c1.6 11 1.9 36.7-23.8 62.4Z"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M184.6 116.7v64.6a8 8 0 0 1-2.4 5.6l-32.3 32.4a8 8 0 0 1-13.5-4.1l-8.4-41.9m11.3-101.9H74.7a8 8 0 0 0-5.6 2.4l-32.4 32.3a8 8 0 0 0 4.1 13.5l41.9 8.4"/>`,
list: `<path stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M40 128h176M40 64h176M40 192h176"/>`,
heart: `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M128 216S28 160 28 92a52 52 0 0 1 100-20h0a52 52 0 0 1 100 20c0 68-100 124-100 124Z"/>`,
'moon-stars': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M216 112V64m24 24h-48m-24-64v32m16-16h-32m65 113A92 92 0 0 1 103 39h0a92 92 0 1 0 114 114Z"/>`,
sun: `<circle cx="128" cy="128" r="60" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M128 36V16M63 63 49 49m-13 79H16m47 65-14 14m79 13v20m65-47 14 14m13-79h20m-47-65 14-14"/>`,
'twitter-logo': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M128 88c0-22 18.5-40.3 40.5-40a40 40 0 0 1 36.2 24H240l-32.3 32.3A127.9 127.9 0 0 1 80 224c-32 0-40-12-40-12s32-12 48-36c0 0-64-32-48-120 0 0 40 40 88 48Z"/>`,
'codepen-logo': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m232 101-104 59-104-59 100.1-56.8a8.3 8.3 0 0 1 7.8 0Z"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m232 165-100.1 56.8a8.3 8.3 0 0 1-7.8 0L24 165l104-59Zm0-64v64M24 101v64m104-5v62.8m0-179.6V106"/>`,
'github-logo': `<g stroke-linecap="round" stroke-linejoin="round"><path fill="none" stroke-width="14.7" d="M55.7 167.2c13.9 1 21.3 13.1 22.2 14.6 4.2 7.2 10.4 9.6 18.3 7.1l1.1-3.4a60.3 60.3 0 0 1-25.8-11.9c-12-10.1-18-25.6-18-46.3"/><path fill="none" stroke-width="16" d="M61.4 205.1a24.5 24.5 0 0 1-3-6.1c-3.2-7.9-7.1-10.6-7.8-11.1l-1-.6c-2.4-1.6-9.5-6.5-7.2-13.9 1.4-4.5 6-7.2 12.3-7.2h.8c4 .3 7.6 1.5 10.7 3.2-9.1-10.1-13.6-24.3-13.6-42.3 0-11.3 3.5-21.7 10.1-30.4A46.7 46.7 0 0 1 65 67.3a8.3 8.3 0 0 1 5-4.7c2.8-.9 13.3-2.7 33.2 9.9a105 105 0 0 1 50.5 0c19.9-12.6 30.4-10.8 33.2-9.9 2.3.7 4.1 2.4 5 4.7 5 12.7 4 23.2 2.6 29.4 6.7 8.7 10 18.9 10 30.4 0 42.6-25.8 54.7-43.6 58.7 1.4 4.1 2.2 8.8 2.2 13.7l-.1 23.4v2.3"/><path fill="none" stroke-width="16" d="M160.9 185.7c1.4 4.1 2.2 8.8 2.2 13.7l-.1 23.4v2.3A98.6 98.6 0 1 0 61.4 205c-1.4-2.1-11.3-17.5-11.8-17.8-2.4-1.6-9.5-6.5-7.2-13.9 1.4-4.5 6-7.2 12.3-7.2h.8c4 .3 7.6 1.5 10.7 3.2-9.1-10.1-13.6-24.3-13.6-42.3 0-11.3 3.5-21.7 10.1-30.4A46.4 46.4 0 0 1 65 67.3a8.3 8.3 0 0 1 5-4.7c2.8-.9 13.3-2.7 33.2 9.9a105 105 0 0 1 50.5 0c19.9-12.6 30.4-10.8 33.2-9.9 2.3.7 4.1 2.4 5 4.7 5 12.7 4 23.2 2.6 29.4 6.7 8.7 10 18.9 10 30.4.1 42.6-25.8 54.7-43.6 58.6z"/><path fill="none" stroke-width="18.7" d="m170.1 203.3 17.3-12 17.2-18.7 9.5-26.6v-27.9l-9.5-27.5" /><path fill="none" stroke-width="22.7" d="m92.1 57.3 23.3-4.6 18.7-1.4 29.3 5.4m-110 32.6-8 16-4 21.4.6 20.3 3.4 13" /><path fill="none" stroke-width="13.3" d="M28.8 133a100 100 0 0 0 66.9 94.4v-8.7c-22.4 1.8-33-11.5-35.6-19.8-3.4-8.6-7.8-11.4-8.5-11.8"/></g>`,
'twitch-logo': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M165 200h-42a8 8 0 0 0-5 2l-46 38v-40H48a8 8 0 0 1-8-8V48a8 8 0 0 1 8-8h160a8 8 0 0 1 8 8v108a8 8 0 0 1-3 6l-43 36a8 8 0 0 1-5 2Zm3-112v48m-48-48v48"/>`,
'youtube-logo': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m160 128-48-32v64l48-32z"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M24 128c0 30 3 47 5 56a16 16 0 0 0 10 11c34 13 89 13 89 13s56 0 89-13a16 16 0 0 0 10-11c2-9 5-26 5-56s-3-47-5-56a16 16 0 0 0-10-11c-33-13-89-13-89-13s-55 0-89 13a16 16 0 0 0-10 11c-2 9-5 26-5 56Z"/>`,
'dribbble-logo': `<circle cx="128" cy="128" r="96" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M71 205a160 160 0 0 1 137-77l16 1m-36-76a160 160 0 0 1-124 59 165 165 0 0 1-30-3"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M86 42a161 161 0 0 1 74 177"/>`,
'discord-logo': `<circle stroke="none" cx="96" cy="144" r="12"/><circle stroke="none" cx="160" cy="144" r="12"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M74 80a175 175 0 0 1 54-8 175 175 0 0 1 54 8m0 96a175 175 0 0 1-54 8 175 175 0 0 1-54-8"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="m155 182 12 24a8 8 0 0 0 9 4c25-6 46-16 61-30a8 8 0 0 0 3-8L206 59a8 8 0 0 0-5-5 176 176 0 0 0-30-9 8 8 0 0 0-9 5l-8 24m-53 108-12 24a8 8 0 0 1-9 4c-25-6-46-16-61-30a8 8 0 0 1-3-8L50 59a8 8 0 0 1 5-5 176 176 0 0 1 30-9 8 8 0 0 1 9 5l8 24"/>`,
'linkedin-logo': `<rect width="184" height="184" x="36" y="36" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" rx="8"/><path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M120 112v64m-32-64v64m32-36a28 28 0 0 1 56 0v36"/><circle stroke="none" cx="88" cy="80" r="12"/>`,
'instagram-logo': `<circle cx="128" cy="128" r="40" fill="none" stroke-miterlimit="10" stroke-width="16"/><rect width="184" height="184" x="36" y="36" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" rx="48"/><circle cx="180" cy="76" r="12" stroke="none" />`,
'tiktok-logo': `<path fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" d="M168 106a96 96 0 0 0 56 18V84a56 56 0 0 1-56-56h-40v128a28 28 0 1 1-40-25V89a68 68 0 1 0 80 67Z"/>`,
};

View file

@ -0,0 +1,28 @@
import { ArrowRightIcon } from "lucide-react"
interface Props {
caption: string
className?: string
href?: string
newTab?: boolean
small?: boolean
}
const LinkButton: React.FC<Props> = ({
caption,
className,
href,
newTab,
small,
}: Props) => {
return (
<a href={href} className={`flex w-fit gap-2 py-4 px-5 rounded-full items-center font-medium bg-secondary text-white hover:bg-opacity-75'
} ${small ? 'py-[10px] px-4' : 'py-4 px-5'} ${className || ''}`}
{...(newTab ? { target: '_blank' } : {})}>
{caption}
<ArrowRightIcon className='h-6 w-6' />
</a>
)
}
export default LinkButton

View file

@ -1,48 +0,0 @@
---
import '../styles/global.css';
interface Props {
title?: string | undefined;
description?: string | undefined;
}
const {
title = 'srx.dev: Sebastian Wendel',
description = 'The personal site of Sebastian Wendel',
} = Astro.props;
---
<meta charset="UTF-8" />
<meta name="description" property="og:description" content={description} />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,400;0,700;1,400&family=Rubik:wght@500;600&display=swap"
rel="stylesheet"
/>
<script is:inline>
// This code is inlined in the head to make dark mode instant & blocking.
const getThemePreference = () => {
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
return localStorage.getItem('theme');
}
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
};
const isDark = getThemePreference() === 'dark';
document.documentElement.classList[isDark ? 'add' : 'remove']('theme-dark');
if (typeof localStorage !== 'undefined') {
// Watch the document element and persist user preference when it changes.
const observer = new MutationObserver(() => {
const isDark = document.documentElement.classList.contains('theme-dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
});
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
}
</script>

View file

@ -1,325 +0,0 @@
---
import Icon, { Props as IconProps } from './Icon.astro';
import ThemeToggle from './ThemeToggle.astro';
/** Main menu items */
const textLinks: { label: string; href: string }[] = [
{ label: 'Home', href: '/' },
{ label: 'Work', href: '/work/' },
{ label: 'Engagement', href: '/engagement/' },
{ label: 'About', href: '/about/' },
];
/** Icon links to social media — edit these with links to your profiles! */
const iconLinks: { label: string; href: string; icon: IconProps['icon'] }[] = [
{ label: 'Twitter', href: 'https://twitter.com/me', icon: 'twitter-logo' },
{ label: 'Twitch', href: 'https://twitch.tv/me', icon: 'twitch-logo' },
{ label: 'GitHub', href: 'https://github.com/me', icon: 'github-logo' },
{ label: 'CodePen', href: 'https://codepen.io/me', icon: 'codepen-logo' },
{ label: 'dribbble', href: 'https://dribbble.com/me', icon: 'dribbble-logo' },
{ label: 'YouTube', href: 'https://www.youtube.com/@me/', icon: 'youtube-logo' },
];
---
<nav>
<div class="menu-header">
<a href="/" class="site-title">
<Icon icon="terminal-window" color="var(--accent-regular)" size="1.6em" gradient />
srx.dev
</a>
<menu-button>
<template>
<button class="menu-button" aria-expanded="false">
<span class="sr-only">Menu</span>
<Icon icon="list" />
</button>
</template>
</menu-button>
</div>
<div id="menu-content">
<ul class="nav-items">
{
textLinks.map(({ label, href }) => (
<li>
<a
aria-current={Astro.url.pathname === href}
class:list={[
'link',
{
active:
Astro.url.pathname === href ||
(href !== '/' && Astro.url.pathname.startsWith(href)),
},
]}
href={href}
>
{label}
</a>
</li>
))
}
</ul>
<div class="menu-footer">
<div class="socials">
{
iconLinks.map(({ href, icon, label }) => (
<a href={href} class="social">
<span class="sr-only">{label}</span>
<Icon icon={icon} />
</a>
))
}
</div>
<div class="theme-toggle">
<ThemeToggle />
</div>
</div>
</div>
</nav>
<script>
class MenuButton extends HTMLElement {
constructor() {
super();
// Inject menu toggle button when JS runs.
this.appendChild(this.querySelector('template')!.content.cloneNode(true));
const btn = this.querySelector('button')!;
// Hide menu (shown by default to support no-JS browsers).
const menu = document.getElementById('menu-content')!;
menu.hidden = true;
/** Set whether the menu is currently expanded or collapsed. */
const setExpanded = (expand: boolean) => {
btn.setAttribute('aria-expanded', expand ? 'true' : 'false');
menu.hidden = !expand;
};
// Toggle menu visibility when the menu button is clicked.
btn.addEventListener('click', () => setExpanded(menu.hidden));
// Hide menu button for large screens.
const handleViewports = (e: MediaQueryList | MediaQueryListEvent) => {
setExpanded(e.matches);
btn.hidden = e.matches;
};
const mediaQueries = window.matchMedia('(min-width: 50em)');
handleViewports(mediaQueries);
mediaQueries.addEventListener('change', handleViewports);
}
}
customElements.define('menu-button', MenuButton);
</script>
<style>
nav {
z-index: 9999;
position: relative;
font-family: var(--font-brand);
font-weight: 500;
margin-bottom: 3.5rem;
}
.menu-header {
display: flex;
justify-content: space-between;
gap: 0.5rem;
padding: 1.5rem;
}
.site-title {
display: flex;
gap: 0.5rem;
align-items: center;
line-height: 1.1;
color: var(--gray-0);
text-decoration: none;
}
.menu-button {
position: relative;
display: flex;
border: 0;
border-radius: 999rem;
padding: 0.5rem;
font-size: 1.5rem;
color: var(--gray-300);
background: radial-gradient(var(--gray-900), var(--gray-800) 150%);
box-shadow: var(--shadow-md);
}
.menu-button[aria-expanded='true'] {
color: var(--gray-0);
background: linear-gradient(180deg, var(--gray-600), transparent),
radial-gradient(var(--gray-900), var(--gray-800) 150%);
}
.menu-button[hidden] {
display: none;
}
.menu-button::before {
position: absolute;
inset: -1px;
content: '';
background: var(--gradient-stroke);
border-radius: 999rem;
z-index: -1;
}
#menu-content {
position: absolute;
left: 0;
right: 0;
}
.nav-items {
margin: 0;
display: flex;
flex-direction: column;
gap: 1rem;
font-size: var(--text-md);
line-height: 1.2;
list-style: none;
padding: 2rem;
background-color: var(--gray-999);
border-bottom: 1px solid var(--gray-800);
}
.link {
display: inline-block;
color: var(--gray-300);
text-decoration: none;
}
.link.active {
color: var(--gray-0);
}
.menu-footer {
--icon-size: var(--text-xl);
--icon-padding: 0.5rem;
display: flex;
justify-content: space-between;
gap: 0.75rem;
padding: 1.5rem 2rem 1.5rem 1.5rem;
background-color: var(--gray-999);
border-radius: 0 0 0.75rem 0.75rem;
box-shadow: var(--shadow-lg);
}
.socials {
display: flex;
flex-wrap: wrap;
gap: 0.625rem;
font-size: var(--icon-size);
}
.social {
display: flex;
padding: var(--icon-padding);
text-decoration: none;
color: var(--accent-dark);
transition: color var(--theme-transition);
}
.social:hover,
.social:focus {
color: var(--accent-text-over);
}
.theme-toggle {
display: flex;
align-items: center;
height: calc(var(--icon-size) + 2 * var(--icon-padding));
}
@media (min-width: 50em) {
nav {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
padding: 2.5rem 5rem;
gap: 1rem;
}
.menu-header {
padding: 0;
}
.site-title {
font-size: var(--text-lg);
}
#menu-content {
display: contents;
}
.nav-items {
position: relative;
flex-direction: row;
font-size: var(--text-sm);
border-radius: 999rem;
border: 0;
padding: 0.5rem 0.5625rem;
background: radial-gradient(var(--gray-900), var(--gray-800) 150%);
box-shadow: var(--shadow-md);
}
.nav-items::before {
position: absolute;
inset: -1px;
content: '';
background: var(--gradient-stroke);
border-radius: 999rem;
z-index: -1;
}
.link {
padding: 0.5rem 1rem;
border-radius: 999rem;
transition: color var(--theme-transition), background-color var(--theme-transition);
}
.link:hover,
.link:focus {
color: var(--gray-100);
background-color: var(--accent-subtle-overlay);
}
.link.active {
color: var(--accent-text-over);
background-color: var(--accent-regular);
}
.menu-footer {
--icon-padding: 0.375rem;
justify-self: flex-end;
align-items: center;
padding: 0;
background-color: transparent;
box-shadow: none;
}
.socials {
display: none;
}
}
@media (min-width: 60em) {
.socials {
display: flex;
justify-content: flex-end;
gap: 0;
}
}
@media (forced-colors: active) {
.link.active {
color: SelectedItem;
}
}
</style>

View file

@ -0,0 +1,19 @@
---
import SrxLogo from "@srx/assets/srx-digital-logo.svg?react";
---
<nav class="section">
<a href={"/"}>
<SrxLogo />
</a>
</nav>
<style>
nav {
@apply bg-default h-20 py-5;
}
svg {
@apply fill-primary h-10;
}
</style>

View file

@ -1,16 +0,0 @@
<div class="pill"><slot /></div>
<style>
.pill {
display: flex;
padding: 0.5rem 1rem;
gap: 0.5rem;
color: var(--accent-text-over);
border: 1px solid var(--accent-regular);
background-color: var(--accent-regular);
border-radius: 999rem;
font-size: var(--text-md);
line-height: 1.35;
white-space: nowrap;
}
</style>

View file

@ -1,64 +0,0 @@
---
import type { CollectionEntry } from 'astro:content';
interface Props {
project: CollectionEntry<'work'>;
}
const { data, slug } = Astro.props.project;
---
<a class="card" href={`/work/${slug}`}>
<span class="title">{data.title}</span>
<img src={data.img} alt={data.img_alt || ''} loading="lazy" decoding="async" />
</a>
<style>
.card {
display: grid;
grid-template: auto 1fr / auto 1fr;
height: 11rem;
background: var(--gradient-subtle);
border: 1px solid var(--gray-800);
border-radius: 0.75rem;
overflow: hidden;
box-shadow: var(--shadow-sm);
text-decoration: none;
font-family: var(--font-brand);
font-size: var(--text-lg);
font-weight: 500;
transition: box-shadow var(--theme-transition);
}
.card:hover {
box-shadow: var(--shadow-md);
}
.title {
grid-area: 1 / 1 / 2 / 2;
z-index: 1;
margin: 0.5rem;
padding: 0.5rem 1rem;
background: var(--gray-999);
color: var(--gray-200);
border-radius: 0.375rem;
}
img {
grid-area: 1 / 1 / 3 / 3;
width: 100%;
height: 100%;
object-fit: cover;
}
@media (min-width: 50em) {
.card {
height: 22rem;
border-radius: 1.5rem;
}
.title {
border-radius: 0.9375rem;
}
}
</style>

View file

@ -1,62 +0,0 @@
---
import Icon from './Icon.astro';
---
<section class="box skills">
<div class="stack gap-2 lg:gap-4">
<Icon icon="terminal-window" color="var(--accent-regular)" size="2.5rem" gradient />
<h2>System Engineering</h2>
<p>Linux ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod.</p>
</div>
<div class="stack gap-2 lg:gap-4">
<Icon icon="trophy" color="var(--accent-regular)" size="2.5rem" gradient />
<h2>Data Science</h2>
<p>Neque viverra justo nec ultrices dui. Est ultricies integer quis auctor elit.</p>
</div>
<div class="stack gap-2 lg:gap-4">
<Icon icon="strategy" color="var(--accent-regular)" size="2.5rem" gradient />
<h2>Industrial IoT</h2>
<p>Urna porttitor rhoncus dolor purus non enim praesent ornare.</p>
</div>
</section>
<style>
.box {
border: 1px solid var(--gray-800);
border-radius: 0.75rem;
padding: 1.5rem;
background-color: var(--gray-999_40);
box-shadow: var(--shadow-sm);
}
.skills {
display: flex;
flex-direction: column;
gap: 3rem;
}
.skills h2 {
font-size: var(--text-lg);
}
.skills p {
color: var(--gray-400);
}
@media (min-width: 50em) {
.box {
border-radius: 1.5rem;
padding: 2.5rem;
}
.skills {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 5rem;
}
.skills h2 {
font-size: var(--text-2xl);
}
}
</style>

View file

@ -1,93 +0,0 @@
---
import Icon from './Icon.astro';
---
<theme-toggle>
<button>
<span class="sr-only">Dark theme</span>
<span class="icon light"><Icon icon="sun" /></span>
<span class="icon dark"><Icon icon="moon-stars" /></span>
</button>
</theme-toggle>
<style>
button {
display: flex;
border: 0;
border-radius: 999rem;
padding: 0;
background-color: var(--gray-999);
box-shadow: inset 0 0 0 1px var(--accent-overlay);
cursor: pointer;
}
.icon {
z-index: 1;
position: relative;
display: flex;
padding: 0.5rem;
width: 2rem;
height: 2rem;
font-size: 1rem;
color: var(--accent-overlay);
}
.icon.light::before {
content: '';
z-index: -1;
position: absolute;
inset: 0;
background-color: var(--accent-regular);
border-radius: 999rem;
}
:global(.theme-dark) .icon.light::before {
transform: translateX(100%);
}
:global(.theme-dark) .icon.dark,
:global(html:not(.theme-dark)) .icon.light,
button[aria-pressed='false'] .icon.light {
color: var(--accent-text-over);
}
@media (prefers-reduced-motion: no-preference) {
.icon,
.icon.light::before {
transition: transform var(--theme-transition), color var(--theme-transition);
}
}
@media (forced-colors: active) {
.icon.light::before {
background-color: SelectedItem;
}
}
</style>
<script>
class ThemeToggle extends HTMLElement {
constructor() {
super();
const button = this.querySelector('button')!;
/** Set the theme to dark/light mode. */
const setTheme = (dark: boolean) => {
document.documentElement.classList[dark ? 'add' : 'remove']('theme-dark');
button.setAttribute('aria-pressed', String(dark));
};
// Toggle the theme when a user clicks the button.
button.addEventListener('click', () => setTheme(!this.isDark()));
// Initialize button state to reflect current theme.
setTheme(this.isDark());
}
isDark() {
return document.documentElement.classList.contains('theme-dark');
}
}
customElements.define('theme-toggle', ThemeToggle);
</script>

5
src/components/index.ts Normal file
View file

@ -0,0 +1,5 @@
import LinkButton from "@srx/components/LinkButton";
export {
LinkButton,
}

View file

@ -1,14 +0,0 @@
import { defineCollection, z } from 'astro:content';
export const collections = {
work: defineCollection({
schema: z.object({
title: z.string(),
description: z.string(),
publishDate: z.coerce.date(),
tags: z.array(z.string()),
img: z.string(),
img_alt: z.string().optional(),
}),
}),
};

View file

@ -1,23 +0,0 @@
---
title: Bloom Box
publishDate: 2019-12-01 00:00:00
img: /assets/stock-2.jpg
img_alt: A bright pink sheet of paper used to wrap flowers curves in front of rich blue background
description: |
We paired with a cutting-edge music API and a team of horticulturalists
to build AI-generated playlists that maximize houseplant health.
tags:
- Dev
- Branding
- Backend
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur posuere commodo venenatis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam non ligula vel metus efficitur hendrerit. In hac habitasse platea dictumst. Praesent et mauris ut mi dapibus semper. Curabitur tortor justo, efficitur sit amet pretium cursus, porta eget odio. Cras ac venenatis dolor. Donec laoreet posuere malesuada. Curabitur nec mi tempor, placerat leo sit amet, tincidunt est. Quisque pellentesque venenatis magna, eget tristique nibh pulvinar in. Vestibulum vitae volutpat arcu. Aenean ut malesuada odio, sit amet pellentesque odio. Suspendisse nunc elit, blandit nec hendrerit non, aliquet at magna. Donec id leo ut nulla sagittis sodales.
Integer vitae nibh elit. Suspendisse eget urna eu neque bibendum pharetra. Sed interdum lectus sem, in pulvinar magna dignissim vel. Quisque maximus at urna nec laoreet. Suspendisse potenti. Vestibulum rhoncus sem ut mi pellentesque, in vestibulum erat blandit. Aliquam sodales dui ac maximus consectetur. Duis quis est vehicula, imperdiet nisl nec, fermentum erat. Duis tortor diam, pharetra eu euismod in, vehicula non eros. Curabitur facilisis dui at erat ultrices gravida. In at nunc ultricies, pulvinar mi vel, sagittis mauris. Praesent pharetra posuere purus ac imperdiet. Nulla facilisi.
Sed pulvinar porttitor mi in ultricies. Etiam non dolor gravida eros pulvinar pellentesque et dictum ex. Proin eu ornare ligula, sed condimentum dui. Vivamus tincidunt tellus mi, sed semper ipsum pharetra a. Suspendisse sollicitudin at sapien nec volutpat. Etiam justo urna, laoreet ac lacus sed, ultricies facilisis dolor. Integer posuere, metus vel viverra gravida, risus elit ornare magna, id feugiat erat risus ullamcorper libero. Proin vitae diam auctor, laoreet lorem vitae, varius tellus.
Mauris sed eros in ex maximus volutpat. Suspendisse potenti. Donec lacinia justo consectetur sagittis tempor. Proin ullamcorper nisi vitae auctor rhoncus. Sed tristique aliquam augue. Pellentesque vitae fringilla ligula. Nulla arcu elit, efficitur eu nunc malesuada, eleifend tincidunt orci. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer mattis orci in bibendum ultricies. Quisque a dui erat. Phasellus et vulputate ipsum. Proin metus ex, lobortis nec ornare eget, bibendum ut sapien. Aliquam in dolor lobortis, aliquam tellus a, congue augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean pretium purus augue, ut bibendum erat convallis quis. Cras condimentum quis velit ac mollis. Suspendisse non purus fringilla, venenatis nisl porta, finibus odio. Curabitur aliquet metus faucibus libero interdum euismod. Morbi sed magna nisl. Morbi odio nibh, facilisis vel sapien eu, tempus tincidunt erat. Nullam erat velit, sagittis at purus quis, tristique scelerisque tortor. Pellentesque lacinia tortor id est aliquam viverra. Vestibulum et diam ac ipsum mollis fringilla.

View file

@ -1,14 +0,0 @@
---
title: h2.0
publishDate: 2019-10-02 00:00:00
img: /assets/stock-4.jpg
img_alt: Soft pink and baby blue water ripples together in a subtle texture.
description: |
We developed brand positioning and design assets for the launch
of a new colored water product.
tags:
- Design
- Branding
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur posuere commodo venenatis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam non ligula vel metus efficitur hendrerit. In hac habitasse platea dictumst. Praesent et mauris ut mi dapibus semper. Curabitur tortor justo, efficitur sit amet pretium cursus, porta eget odio. Cras ac venenatis dolor. Donec laoreet posuere malesuada. Curabitur nec mi tempor, placerat leo sit amet, tincidunt est. Quisque pellentesque venenatis magna, eget tristique nibh pulvinar in. Vestibulum vitae volutpat arcu. Aenean ut malesuada odio, sit amet pellentesque odio. Suspendisse nunc elit, blandit nec hendrerit non, aliquet at magna. Donec id leo ut nulla sagittis sodales.

View file

@ -1,35 +0,0 @@
---
title: Markdown Mystery Tour
publishDate: 2020-03-02 00:00:00
img: /assets/stock-1.jpg
img_alt: Iridescent ripples of a bright blue and pink liquid
description: |
We designed a whodunnit-style game to introduce Markdown formatting. Suspense — suspicion — syntax!
tags:
- Design
- Dev
- User Testing
---
## Level-two heading
> Tell me and I forget. Teach me and I remember. Involve me and I learn.
Lorem ipsum dolor sit amet, <a href="https://astro.build/">Astro</a> makes people happy. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Proin nibh nisl condimentum id venenatis a condimentum vitae. Dapibus ultrices in iaculis nunc. Arcu odio ut sem nulla pharetra diam sit amet. Diam quis enim lobortis scelerisque fermentum dui faucibus in ornare.
Arcu dui vivamus arcu felis bibendum ut tristique et egestas. Eget gravida cum sociis natoque penatibus. Cras fermentum odio eu feugiat pretium nibh. Proin nibh nisl condimentum id venenatis. Porta nibh venenatis cras sed felis eget velit. Id diam vel quam elementum pulvinar etiam non.
### Level-three heading
Ultrices tincidunt arcu non sodales neque sodales ut. Sed enim ut sem viverra aliquet eget sit amet. Lacus luctus accumsan tortor posuere ac ut consequat semper viverra. Viverra accumsan in nisl nisi scelerisque eu ultrices. In massa tempor nec feugiat nisl pretium fusce.
### Level-three heading
Sed pulvinar porttitor mi in ultricies. Etiam non dolor gravida eros pulvinar pellentesque et dictum ex. Proin eu ornare ligula, sed condimentum dui. Vivamus tincidunt tellus mi, sed semper ipsum pharetra a. Suspendisse sollicitudin at sapien nec volutpat. Etiam justo urna, laoreet ac lacus sed, ultricies facilisis dolor. Integer posuere, metus vel viverra gravida, risus elit ornare magna, id feugiat erat risus ullamcorper libero. Proin vitae diam auctor, laoreet lorem vitae, varius tellus.
Aenean pretium purus augue, ut bibendum erat convallis quis. Cras condimentum quis velit ac mollis. Suspendisse non purus fringilla, venenatis nisl porta, finibus odio. Curabitur aliquet metus faucibus libero interdum euismod. Morbi sed magna nisl. Morbi odio nibh, facilisis vel sapien eu, tempus tincidunt erat. Nullam erat velit, sagittis at purus quis, tristique scelerisque tortor. Pellentesque lacinia tortor id est aliquam viverra. Vestibulum et diam ac ipsum mollis fringilla.
#### Level-four heading
- We noted this
- And also this other point

View file

@ -1,22 +0,0 @@
---
title: Duvet Genius
publishDate: 2020-03-04 00:00:00
img: /assets/stock-3.jpg
img_alt: Pearls of silky soft white cotton, bubble up under vibrant lighting
description: |
We developed a virtual showcase for the softest bedding imaginable.
tags:
- Design
- Dev
- Branding
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur posuere commodo venenatis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam non ligula vel metus efficitur hendrerit. In hac habitasse platea dictumst. Praesent et mauris ut mi dapibus semper. Curabitur tortor justo, efficitur sit amet pretium cursus, porta eget odio. Cras ac venenatis dolor. Donec laoreet posuere malesuada. Curabitur nec mi tempor, placerat leo sit amet, tincidunt est. Quisque pellentesque venenatis magna, eget tristique nibh pulvinar in. Vestibulum vitae volutpat arcu. Aenean ut malesuada odio, sit amet pellentesque odio. Suspendisse nunc elit, blandit nec hendrerit non, aliquet at magna. Donec id leo ut nulla sagittis sodales.
Integer vitae nibh elit. Suspendisse eget urna eu neque bibendum pharetra. Sed interdum lectus sem, in pulvinar magna dignissim vel. Quisque maximus at urna nec laoreet. Suspendisse potenti. Vestibulum rhoncus sem ut mi pellentesque, in vestibulum erat blandit. Aliquam sodales dui ac maximus consectetur. Duis quis est vehicula, imperdiet nisl nec, fermentum erat. Duis tortor diam, pharetra eu euismod in, vehicula non eros. Curabitur facilisis dui at erat ultrices gravida. In at nunc ultricies, pulvinar mi vel, sagittis mauris. Praesent pharetra posuere purus ac imperdiet. Nulla facilisi.
Sed pulvinar porttitor mi in ultricies. Etiam non dolor gravida eros pulvinar pellentesque et dictum ex. Proin eu ornare ligula, sed condimentum dui. Vivamus tincidunt tellus mi, sed semper ipsum pharetra a. Suspendisse sollicitudin at sapien nec volutpat. Etiam justo urna, laoreet ac lacus sed, ultricies facilisis dolor. Integer posuere, metus vel viverra gravida, risus elit ornare magna, id feugiat erat risus ullamcorper libero. Proin vitae diam auctor, laoreet lorem vitae, varius tellus.
Mauris sed eros in ex maximus volutpat. Suspendisse potenti. Donec lacinia justo consectetur sagittis tempor. Proin ullamcorper nisi vitae auctor rhoncus. Sed tristique aliquam augue. Pellentesque vitae fringilla ligula. Nulla arcu elit, efficitur eu nunc malesuada, eleifend tincidunt orci. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer mattis orci in bibendum ultricies. Quisque a dui erat. Phasellus et vulputate ipsum. Proin metus ex, lobortis nec ornare eget, bibendum ut sapien. Aliquam in dolor lobortis, aliquam tellus a, congue augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean pretium purus augue, ut bibendum erat convallis quis. Cras condimentum quis velit ac mollis. Suspendisse non purus fringilla, venenatis nisl porta, finibus odio. Curabitur aliquet metus faucibus libero interdum euismod. Morbi sed magna nisl. Morbi odio nibh, facilisis vel sapien eu, tempus tincidunt erat. Nullam erat velit, sagittis at purus quis, tristique scelerisque tortor. Pellentesque lacinia tortor id est aliquam viverra. Vestibulum et diam ac ipsum mollis fringilla.

View file

@ -1,23 +0,0 @@
---
title: Bloom Box
publishDate: 2019-12-01 00:00:00
img: /assets/stock-2.jpg
img_alt: A bright pink sheet of paper used to wrap flowers curves in front of rich blue background
description: |
We paired with a cutting-edge music API and a team of horticulturalists
to build AI-generated playlists that maximize houseplant health.
tags:
- Dev
- Branding
- Backend
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur posuere commodo venenatis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam non ligula vel metus efficitur hendrerit. In hac habitasse platea dictumst. Praesent et mauris ut mi dapibus semper. Curabitur tortor justo, efficitur sit amet pretium cursus, porta eget odio. Cras ac venenatis dolor. Donec laoreet posuere malesuada. Curabitur nec mi tempor, placerat leo sit amet, tincidunt est. Quisque pellentesque venenatis magna, eget tristique nibh pulvinar in. Vestibulum vitae volutpat arcu. Aenean ut malesuada odio, sit amet pellentesque odio. Suspendisse nunc elit, blandit nec hendrerit non, aliquet at magna. Donec id leo ut nulla sagittis sodales.
Integer vitae nibh elit. Suspendisse eget urna eu neque bibendum pharetra. Sed interdum lectus sem, in pulvinar magna dignissim vel. Quisque maximus at urna nec laoreet. Suspendisse potenti. Vestibulum rhoncus sem ut mi pellentesque, in vestibulum erat blandit. Aliquam sodales dui ac maximus consectetur. Duis quis est vehicula, imperdiet nisl nec, fermentum erat. Duis tortor diam, pharetra eu euismod in, vehicula non eros. Curabitur facilisis dui at erat ultrices gravida. In at nunc ultricies, pulvinar mi vel, sagittis mauris. Praesent pharetra posuere purus ac imperdiet. Nulla facilisi.
Sed pulvinar porttitor mi in ultricies. Etiam non dolor gravida eros pulvinar pellentesque et dictum ex. Proin eu ornare ligula, sed condimentum dui. Vivamus tincidunt tellus mi, sed semper ipsum pharetra a. Suspendisse sollicitudin at sapien nec volutpat. Etiam justo urna, laoreet ac lacus sed, ultricies facilisis dolor. Integer posuere, metus vel viverra gravida, risus elit ornare magna, id feugiat erat risus ullamcorper libero. Proin vitae diam auctor, laoreet lorem vitae, varius tellus.
Mauris sed eros in ex maximus volutpat. Suspendisse potenti. Donec lacinia justo consectetur sagittis tempor. Proin ullamcorper nisi vitae auctor rhoncus. Sed tristique aliquam augue. Pellentesque vitae fringilla ligula. Nulla arcu elit, efficitur eu nunc malesuada, eleifend tincidunt orci. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer mattis orci in bibendum ultricies. Quisque a dui erat. Phasellus et vulputate ipsum. Proin metus ex, lobortis nec ornare eget, bibendum ut sapien. Aliquam in dolor lobortis, aliquam tellus a, congue augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean pretium purus augue, ut bibendum erat convallis quis. Cras condimentum quis velit ac mollis. Suspendisse non purus fringilla, venenatis nisl porta, finibus odio. Curabitur aliquet metus faucibus libero interdum euismod. Morbi sed magna nisl. Morbi odio nibh, facilisis vel sapien eu, tempus tincidunt erat. Nullam erat velit, sagittis at purus quis, tristique scelerisque tortor. Pellentesque lacinia tortor id est aliquam viverra. Vestibulum et diam ac ipsum mollis fringilla.

View file

@ -1,14 +0,0 @@
---
title: h2.0
publishDate: 2019-10-02 00:00:00
img: /assets/stock-4.jpg
img_alt: Soft pink and baby blue water ripples together in a subtle texture.
description: |
We developed brand positioning and design assets for the launch
of a new colored water product.
tags:
- Design
- Branding
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur posuere commodo venenatis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam non ligula vel metus efficitur hendrerit. In hac habitasse platea dictumst. Praesent et mauris ut mi dapibus semper. Curabitur tortor justo, efficitur sit amet pretium cursus, porta eget odio. Cras ac venenatis dolor. Donec laoreet posuere malesuada. Curabitur nec mi tempor, placerat leo sit amet, tincidunt est. Quisque pellentesque venenatis magna, eget tristique nibh pulvinar in. Vestibulum vitae volutpat arcu. Aenean ut malesuada odio, sit amet pellentesque odio. Suspendisse nunc elit, blandit nec hendrerit non, aliquet at magna. Donec id leo ut nulla sagittis sodales.

View file

@ -1,35 +0,0 @@
---
title: Markdown Mystery Tour
publishDate: 2020-03-02 00:00:00
img: /assets/stock-1.jpg
img_alt: Iridescent ripples of a bright blue and pink liquid
description: |
We designed a whodunnit-style game to introduce Markdown formatting. Suspense — suspicion — syntax!
tags:
- Design
- Dev
- User Testing
---
## Level-two heading
> Tell me and I forget. Teach me and I remember. Involve me and I learn.
Lorem ipsum dolor sit amet, <a href="https://astro.build/">Astro</a> makes people happy. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Proin nibh nisl condimentum id venenatis a condimentum vitae. Dapibus ultrices in iaculis nunc. Arcu odio ut sem nulla pharetra diam sit amet. Diam quis enim lobortis scelerisque fermentum dui faucibus in ornare.
Arcu dui vivamus arcu felis bibendum ut tristique et egestas. Eget gravida cum sociis natoque penatibus. Cras fermentum odio eu feugiat pretium nibh. Proin nibh nisl condimentum id venenatis. Porta nibh venenatis cras sed felis eget velit. Id diam vel quam elementum pulvinar etiam non.
### Level-three heading
Ultrices tincidunt arcu non sodales neque sodales ut. Sed enim ut sem viverra aliquet eget sit amet. Lacus luctus accumsan tortor posuere ac ut consequat semper viverra. Viverra accumsan in nisl nisi scelerisque eu ultrices. In massa tempor nec feugiat nisl pretium fusce.
### Level-three heading
Sed pulvinar porttitor mi in ultricies. Etiam non dolor gravida eros pulvinar pellentesque et dictum ex. Proin eu ornare ligula, sed condimentum dui. Vivamus tincidunt tellus mi, sed semper ipsum pharetra a. Suspendisse sollicitudin at sapien nec volutpat. Etiam justo urna, laoreet ac lacus sed, ultricies facilisis dolor. Integer posuere, metus vel viverra gravida, risus elit ornare magna, id feugiat erat risus ullamcorper libero. Proin vitae diam auctor, laoreet lorem vitae, varius tellus.
Aenean pretium purus augue, ut bibendum erat convallis quis. Cras condimentum quis velit ac mollis. Suspendisse non purus fringilla, venenatis nisl porta, finibus odio. Curabitur aliquet metus faucibus libero interdum euismod. Morbi sed magna nisl. Morbi odio nibh, facilisis vel sapien eu, tempus tincidunt erat. Nullam erat velit, sagittis at purus quis, tristique scelerisque tortor. Pellentesque lacinia tortor id est aliquam viverra. Vestibulum et diam ac ipsum mollis fringilla.
#### Level-four heading
- We noted this
- And also this other point

View file

@ -1,22 +0,0 @@
---
title: Duvet Genius
publishDate: 2020-03-04 00:00:00
img: /assets/stock-3.jpg
img_alt: Pearls of silky soft white cotton, bubble up under vibrant lighting
description: |
We developed a virtual showcase for the softest bedding imaginable.
tags:
- Design
- Dev
- Branding
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur posuere commodo venenatis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam non ligula vel metus efficitur hendrerit. In hac habitasse platea dictumst. Praesent et mauris ut mi dapibus semper. Curabitur tortor justo, efficitur sit amet pretium cursus, porta eget odio. Cras ac venenatis dolor. Donec laoreet posuere malesuada. Curabitur nec mi tempor, placerat leo sit amet, tincidunt est. Quisque pellentesque venenatis magna, eget tristique nibh pulvinar in. Vestibulum vitae volutpat arcu. Aenean ut malesuada odio, sit amet pellentesque odio. Suspendisse nunc elit, blandit nec hendrerit non, aliquet at magna. Donec id leo ut nulla sagittis sodales.
Integer vitae nibh elit. Suspendisse eget urna eu neque bibendum pharetra. Sed interdum lectus sem, in pulvinar magna dignissim vel. Quisque maximus at urna nec laoreet. Suspendisse potenti. Vestibulum rhoncus sem ut mi pellentesque, in vestibulum erat blandit. Aliquam sodales dui ac maximus consectetur. Duis quis est vehicula, imperdiet nisl nec, fermentum erat. Duis tortor diam, pharetra eu euismod in, vehicula non eros. Curabitur facilisis dui at erat ultrices gravida. In at nunc ultricies, pulvinar mi vel, sagittis mauris. Praesent pharetra posuere purus ac imperdiet. Nulla facilisi.
Sed pulvinar porttitor mi in ultricies. Etiam non dolor gravida eros pulvinar pellentesque et dictum ex. Proin eu ornare ligula, sed condimentum dui. Vivamus tincidunt tellus mi, sed semper ipsum pharetra a. Suspendisse sollicitudin at sapien nec volutpat. Etiam justo urna, laoreet ac lacus sed, ultricies facilisis dolor. Integer posuere, metus vel viverra gravida, risus elit ornare magna, id feugiat erat risus ullamcorper libero. Proin vitae diam auctor, laoreet lorem vitae, varius tellus.
Mauris sed eros in ex maximus volutpat. Suspendisse potenti. Donec lacinia justo consectetur sagittis tempor. Proin ullamcorper nisi vitae auctor rhoncus. Sed tristique aliquam augue. Pellentesque vitae fringilla ligula. Nulla arcu elit, efficitur eu nunc malesuada, eleifend tincidunt orci. Interdum et malesuada fames ac ante ipsum primis in faucibus. Integer mattis orci in bibendum ultricies. Quisque a dui erat. Phasellus et vulputate ipsum. Proin metus ex, lobortis nec ornare eget, bibendum ut sapien. Aliquam in dolor lobortis, aliquam tellus a, congue augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean pretium purus augue, ut bibendum erat convallis quis. Cras condimentum quis velit ac mollis. Suspendisse non purus fringilla, venenatis nisl porta, finibus odio. Curabitur aliquet metus faucibus libero interdum euismod. Morbi sed magna nisl. Morbi odio nibh, facilisis vel sapien eu, tempus tincidunt erat. Nullam erat velit, sagittis at purus quis, tristique scelerisque tortor. Pellentesque lacinia tortor id est aliquam viverra. Vestibulum et diam ac ipsum mollis fringilla.

1
src/env.d.ts vendored
View file

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

View file

@ -1,113 +1,97 @@
---
// Learn about using Astro layouts:
// https://docs.astro.build/en/core-concepts/layouts/
// Component Imports
import MainHead from '../components/MainHead.astro';
import Nav from '../components/Nav.astro';
import Footer from '../components/Footer.astro';
import "@srx/styles/base.css";
import "@fontsource-variable/literata";
import "@fontsource-variable/manrope";
import "@fontsource-variable/martian-mono";
import Navbar from "@srx/components/Navbar.astro";
import Footer from "@srx/components/Footer.astro";
interface Props {
title?: string | undefined;
description?: string | undefined;
metaTitle?: string;
metaSubtitle?: string;
metaDescription?: string;
metaImage?: string;
metaAuthors?: string[];
metaType?: string;
metaDate?: string;
metaSchema?: string;
}
const { title, description } = Astro.props;
const {
metaTitle = "srx digital",
metaSubtitle = "Development & Operations",
metaDescription = "",
metaImage = "https://srx.digital/srx_digital_opengraph.jpg",
metaAuthors = ["Sebastian Wendel"],
metaType = "website",
metaDate,
metaSchema,
} = Astro.props;
const isProduction = import.meta.env.MODE === "production";
---
<html lang="en">
<head>
<MainHead title={title} description={description} />
</head>
<body>
<div class="stack backgrounds">
<Nav />
<slot />
<Footer />
</div>
<html lang="de" class="overflow-x-hidden scroll-smooth">
<head>
<meta charset="utf-8" />
<title>{`${metaTitle} - ${metaSubtitle}`}</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="generator" content={Astro.generator} />
<meta name="description" content={metaDescription} />
<meta property="og:type" content={metaType} />
<meta
name="title"
property="og:title"
content={`${metaTitle} - ${metaSubtitle}`}
/>
<meta
name="description"
property="og:description"
content={metaDescription}
/>
<meta property="og:url" content={Astro.url} />
<meta name="image" property="og:image" content={metaImage} />
{
metaDate && (
<meta
name="date"
property="og:article:published_time"
content={metaDate}
/>
)
}
{
metaAuthors?.map((author) => (
<meta
property="og:article:author"
name="author"
content={author}
/>
))
}
{
metaSchema && (
<script
type="application/ld+json"
set:html={metaSchema}
is:inline
/>
)
}
{
isProduction && (
<script
src="https://analytics.srx.digital/script.js"
data-website-id="herimee8win2thiZibohnaichei8uoDo"
async
/>
)
}
</head>
<Navbar />
<slot />
<Footer />
<script>
// Add “loaded” class once the document has completely loaded.
addEventListener('load', () => document.documentElement.classList.add('loaded'));
</script>
<style>
:root {
--_placeholder-bg: linear-gradient(transparent, transparent);
--bg-image-main: url('/assets/backgrounds/bg-main-light-800w.jpg');
--bg-image-main-curves: url('/assets/backgrounds/bg-main-light.svg');
--bg-image-subtle-1: var(--_placeholder-bg);
--bg-image-subtle-2: var(--_placeholder-bg);
--bg-image-footer: var(--_placeholder-bg);
--bg-svg-blend-mode: overlay;
--bg-blend-mode: darken;
--bg-image-aspect-ratio: 2.25;
--bg-scale: 1.68;
--bg-aspect-ratio: calc(var(--bg-image-aspect-ratio) / var(--bg-scale));
--bg-gradient-size: calc(var(--bg-scale) * 100%);
}
:root.theme-dark {
--bg-image-main: url('/assets/backgrounds/bg-main-dark-800w.jpg');
--bg-image-main-curves: url('/assets/backgrounds/bg-main-dark.svg');
--bg-svg-blend-mode: darken;
--bg-blend-mode: lighten;
}
/* These backgrounds are displayed below the fold, so we lazy load them
once the `.loaded` class has been set. */
:root.loaded {
--bg-image-subtle-1: url('/assets/backgrounds/bg-subtle-1-light-800w.jpg');
--bg-image-subtle-2: url('/assets/backgrounds/bg-subtle-2-light-800w.jpg');
--bg-image-footer: url('/assets/backgrounds/bg-footer-light-800w.jpg');
}
:root.loaded.theme-dark {
--bg-image-subtle-1: url('/assets/backgrounds/bg-subtle-1-dark-800w.jpg');
--bg-image-subtle-2: url('/assets/backgrounds/bg-subtle-2-dark-800w.jpg');
--bg-image-footer: url('/assets/backgrounds/bg-footer-dark-800w.jpg');
}
@media (min-width: 50em) {
:root {
--bg-scale: 1;
--bg-image-main: url('/assets/backgrounds/bg-main-light-1440w.jpg');
}
:root.theme-dark {
--bg-image-main: url('/assets/backgrounds/bg-main-dark-1440w.jpg');
}
:root.loaded {
--bg-image-subtle-1: url('/assets/backgrounds/bg-subtle-1-light-1440w.jpg');
--bg-image-subtle-2: url('/assets/backgrounds/bg-subtle-2-light-1440w.jpg');
--bg-image-footer: url('/assets/backgrounds/bg-footer-light-1440w.jpg');
}
:root.loaded.theme-dark {
--bg-image-subtle-1: url('/assets/backgrounds/bg-subtle-1-dark-1440w.jpg');
--bg-image-subtle-2: url('/assets/backgrounds/bg-subtle-2-dark-1440w.jpg');
--bg-image-footer: url('/assets/backgrounds/bg-footer-dark-1440w.jpg');
}
}
.backgrounds {
min-height: 100%;
isolation: isolate;
background:
/*noise*/ url('/assets/backgrounds/noise.png') top center/220px repeat,
/*footer*/ var(--bg-image-footer) bottom center/var(--bg-gradient-size) no-repeat,
/*header1*/ var(--bg-image-main-curves) top center/var(--bg-gradient-size) no-repeat,
/*header2*/ var(--bg-image-main) top center/var(--bg-gradient-size) no-repeat,
/*base*/ var(--gray-999);
background-blend-mode: /*noise*/ overlay, /*footer*/ var(--bg-blend-mode),
/*header1*/ var(--bg-svg-blend-mode), /*header2*/ normal, /*base*/ normal;
}
@media (forced-colors: active) {
/* Deactivate custom backgrounds for high contrast users. */
.backgrounds {
background: none;
background-blend-mode: none;
--bg-gradient-size: none;
}
}
</style>
</body>
</html>

View file

@ -1,8 +0,0 @@
---
import Hero from '../components/Hero.astro';
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout title="Not Found" description="404 Error — this page was not found">
<Hero title="Page Not Found" tagline="Not found" />
</BaseLayout>

View file

@ -1,120 +0,0 @@
---
import BaseLayout from '../layouts/BaseLayout.astro';
import ContactCTA from '../components/ContactCTA.astro';
import Hero from '../components/Hero.astro';
---
<BaseLayout title="About | Sebastian Wendel" description="About Sebastian Wendel Lorem Ipsum">
<div class="stack gap-20">
<main class="wrapper about">
<Hero
title="About"
tagline="Thanks for stopping by. Read below to learn more about myself and my background."
>
<img
width="1553"
height="873"
src="/assets/at-work.jpg"
alt="Sebastian Wendel at work with a colleague"
/>
</Hero>
<section>
<h2 class="section-title">Background</h2>
<div class="content">
<p>
Lorem ipsum dolor sit amet, <a href="https://astro.build/">Astro</a> makes people happy.
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Proin nibh nisl condimentum
id venenatis a condimentum vitae. Dapibus ultrices in iaculis nunc. Arcu odio ut sem nulla
pharetra diam sit amet. Diam quis enim lobortis scelerisque fermentum dui faucibus in ornare.
</p>
<p>
Arcu dui vivamus arcu felis bibendum ut tristique et egestas. Eget gravida cum sociis
natoque penatibus. Cras fermentum odio eu feugiat pretium nibh. Proin nibh nisl
condimentum id venenatis. Porta nibh venenatis cras sed felis eget velit. Id diam vel
quam elementum pulvinar etiam non.
</p>
<p>
Ultrices tincidunt arcu non sodales neque sodales ut. Sed enim ut sem viverra aliquet
eget sit amet. Lacus luctus accumsan tortor posuere ac ut consequat semper viverra.
Viverra accumsan in nisl nisi scelerisque eu ultrices. In massa tempor nec feugiat nisl
pretium fusce.
</p>
</div>
</section>
<section>
<h2 class="section-title">Education</h2>
<div class="content">
<p>Corporis voluptates tenetur laudantium.</p>
</div>
</section>
<section>
<h2 class="section-title">Skills</h2>
<div class="content">
<p>officia unde omnis</p>
</div>
</section>
</main>
<ContactCTA />
</div>
</BaseLayout>
<style>
.about {
display: flex;
flex-direction: column;
gap: 3.5rem;
}
img {
margin-top: 1.5rem;
border-radius: 1.5rem;
box-shadow: var(--shadow-md);
}
section {
display: flex;
flex-direction: column;
gap: 0.5rem;
color: var(--gray-200);
}
.section-title {
grid-column-start: 1;
font-size: var(--text-xl);
color: var(--gray-0);
}
.content {
grid-column: 2 / 4;
}
.content :global(a) {
text-decoration: 1px solid underline transparent;
text-underline-offset: 0.25em;
transition: text-decoration-color var(--theme-transition);
}
.content :global(a:hover),
.content :global(a:focus) {
text-decoration-color: currentColor;
}
@media (min-width: 50em) {
.about {
display: grid;
grid-template-columns: 1fr 60% 1fr;
}
.about > :global(:first-child) {
grid-column-start: 2;
}
section {
display: contents;
font-size: var(--text-lg);
}
}
</style>

View file

@ -1,39 +0,0 @@
---
import { getCollection } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';
import ContactCTA from '../components/ContactCTA.astro';
import PortfolioPreview from '../components/PortfolioPreview.astro';
import Hero from '../components/Hero.astro';
import Grid from '../components/Grid.astro';
const projects = (await getCollection('engagement')).sort(
(a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf()
);
---
<BaseLayout
title="My Engagement | Sebastian Wendel"
description="Learn about Sebastian Wendel's most recent Engagement"
>
<div class="stack gap-20">
<main class="wrapper stack gap-8">
<Hero
title="My Work"
tagline="See my most recent projects below to get an idea of my past experience."
align="start"
/>
<Grid variant="offset">
{
projects.map((project) => (
<li>
<PortfolioPreview project={project} />
</li>
))
}
</Grid>
</main>
<ContactCTA />
</div>
</BaseLayout>

View file

@ -1,151 +0,0 @@
---
import { CollectionEntry, getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
import ContactCTA from '../../components/ContactCTA.astro';
import Hero from '../../components/Hero.astro';
import Icon from '../../components/Icon.astro';
import Pill from '../../components/Pill.astro';
interface Props {
entry: CollectionEntry<'work'>;
}
// This is a dynamic route that generates a page for every Markdown file in src/content/
// Read more about dynamic routes and this `getStaticPaths` function in the Astro docs:
// https://docs.astro.build/en/core-concepts/routing/#dynamic-routes
export async function getStaticPaths() {
const work = await getCollection('engagement');
return work.map((entry) => ({
params: { slug: entry.slug },
props: { entry },
}));
}
const { entry } = Astro.props;
const { Content } = await entry.render();
---
<BaseLayout title={entry.data.title} description={entry.data.description}>
<div class="stack gap-20">
<div class="stack gap-15">
<header>
<div class="wrapper stack gap-2">
<a class="back-link" href="/work/"><Icon icon="arrow-left" /> Work</a>
<Hero title={entry.data.title} align="start">
<div class="details">
<div class="tags">
{entry.data.tags.map((t) => <Pill>{t}</Pill>)}
</div>
<p class="description">{entry.data.description}</p>
</div>
</Hero>
</div>
</header>
<main class="wrapper">
<div class="stack gap-10 content">
{entry.data.img && <img src={entry.data.img} alt={entry.data.img_alt || ''} />}
<div class="content">
<Content />
</div>
</div>
</main>
</div>
<ContactCTA />
</div>
</BaseLayout>
<style>
header {
padding-bottom: 2.5rem;
border-bottom: 1px solid var(--gray-800);
}
.back-link {
display: none;
}
.details {
display: flex;
flex-direction: column;
padding: 0.5rem;
gap: 1.5rem;
justify-content: space-between;
align-items: center;
}
.tags {
display: flex;
gap: 0.5rem;
}
.description {
font-size: var(--text-lg);
max-width: 54ch;
}
.content {
max-width: 65ch;
margin-inline: auto;
}
.content > :global(* + *) {
margin-top: 1rem;
}
.content :global(h1),
.content :global(h2),
.content :global(h3),
.content :global(h4),
.content :global(h5) {
margin: 1.5rem 0;
}
.content :global(img) {
border-radius: 1.5rem;
box-shadow: var(--shadow-sm);
background: var(--gradient-subtle);
border: 1px solid var(--gray-800);
}
.content :global(blockquote) {
font-size: var(--text-lg);
font-family: var(--font-brand);
font-weight: 600;
line-height: 1.1;
padding-inline-start: 1.5rem;
border-inline-start: 0.25rem solid var(--accent-dark);
color: var(--gray-0);
}
.back-link,
.content :global(a) {
text-decoration: 1px solid underline transparent;
text-underline-offset: 0.25em;
transition: text-decoration-color var(--theme-transition);
}
.back-link:hover,
.back-link:focus,
.content :global(a:hover),
.content :global(a:focus) {
text-decoration-color: currentColor;
}
@media (min-width: 50em) {
.back-link {
display: block;
align-self: flex-start;
}
.details {
flex-direction: row;
gap: 2.5rem;
}
.content :global(blockquote) {
font-size: var(--text-2xl);
}
}
</style>

View file

@ -1,249 +1,8 @@
---
import { getCollection } from 'astro:content';
// Layout import — provides basic page elements: <head>, <nav>, <footer> etc.
import BaseLayout from '../layouts/BaseLayout.astro';
// Component Imports
import CallToAction from '../components/CallToAction.astro';
import Grid from '../components/Grid.astro';
import Hero from '../components/Hero.astro';
import Icon from '../components/Icon.astro';
import Pill from '../components/Pill.astro';
import PortfolioPreview from '../components/PortfolioPreview.astro';
// Page section components
import ContactCTA from '../components/ContactCTA.astro';
import Skills from '../components/Skills.astro';
// Content Fetching: List four most recent work projects
const projects = (await getCollection('work'))
.sort((a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf())
.slice(0, 4);
// Full Astro Component Syntax:
// https://docs.astro.build/core-concepts/astro-components/
import BaseLayout from "@srx/layouts/BaseLayout.astro";
import Hero from "@srx/components/Hero.astro";
---
<BaseLayout>
<div class="stack gap-20 lg:gap-48">
<div class="wrapper stack gap-8 lg:gap-20">
<header class="hero">
<Hero
title="Hello, my name is Sebastian Wendel"
tagline="I am a Site Reliability Engineering who is based in Hamburg, Germany."
align="start"
>
<div class="roles">
<Pill><Icon icon="code" size="1.33em" /> Developer</Pill>
<Pill><Icon icon="rocket-launch" size="1.33em" /> Maker</Pill>
</div>
</Hero>
<img
alt="Sebastian Wendel smiling in a red plaid shirt and tortoise shell glasses"
width="480"
height="620"
src="/assets/portrait.jpg"
/>
</header>
<Skills />
</div>
<main class="wrapper stack gap-20 lg:gap-48">
<section class="section with-background with-cta">
<header class="section-header stack gap-2 lg:gap-4">
<h3>Selected Work</h3>
<p>Take a look below at some of my featured work for clients from the past few years.</p>
</header>
<div class="gallery">
<Grid variant="offset">
{
projects.map((project) => (
<li>
<PortfolioPreview project={project} />
</li>
))
}
</Grid>
</div>
<div class="cta">
<CallToAction href="/work/">
View All
<Icon icon="arrow-right" size="1.2em" />
</CallToAction>
</div>
</section>
<section class="section with-background bg-variant">
<header class="section-header stack gap-2 lg:gap-4">
<h3>Mentions</h3>
<p>
I have been fortunate enough to recieve praise for my work in several publications. Take
a look below to learn more.
</p>
</header>
<div class="gallery">
<Grid variant="small">
{
['Medium', 'BuzzFeed', 'The Next Web', 'awwwards.', 'TechCrunch'].map((brand) => (
<li class="mention-card">
<p>{brand}</p>
</li>
))
}
</Grid>
</div>
</section>
</main>
<ContactCTA />
</div>
<Hero />
</BaseLayout>
<style>
.hero {
display: flex;
flex-direction: column;
align-items: center;
gap: 2rem;
}
.roles {
display: none;
}
.hero img {
aspect-ratio: 5 / 4;
object-fit: cover;
object-position: top;
border-radius: 1.5rem;
box-shadow: var(--shadow-md);
}
@media (min-width: 50em) {
.hero {
display: grid;
grid-template-columns: 6fr 4fr;
padding-inline: 2.5rem;
gap: 3.75rem;
}
.roles {
margin-top: 0.5rem;
display: flex;
gap: 0.5rem;
}
.hero img {
aspect-ratio: 3 / 4;
border-radius: 4.5rem;
object-fit: cover;
}
}
/* ====================================================== */
.section {
display: grid;
gap: 2rem;
}
.with-background {
position: relative;
}
.with-background::before {
--hero-bg: var(--bg-image-subtle-2);
content: '';
position: absolute;
pointer-events: none;
left: 50%;
width: 100vw;
aspect-ratio: calc(2.25 / var(--bg-scale));
top: 0;
transform: translateY(-75%) translateX(-50%);
background: url('/assets/backgrounds/noise.png') top center/220px repeat,
var(--hero-bg) center center / var(--bg-gradient-size) no-repeat, var(--gray-999);
background-blend-mode: overlay, normal, normal, normal;
mix-blend-mode: var(--bg-blend-mode);
z-index: -1;
}
.with-background.bg-variant::before {
--hero-bg: var(--bg-image-subtle-1);
}
.section-header {
justify-self: center;
text-align: center;
max-width: 50ch;
font-size: var(--text-md);
color: var(--gray-300);
}
.section-header h3 {
font-size: var(--text-2xl);
}
@media (min-width: 50em) {
.section {
grid-template-columns: repeat(4, 1fr);
grid-template-areas: 'header header header header' 'gallery gallery gallery gallery';
gap: 5rem;
}
.section.with-cta {
grid-template-areas: 'header header header cta' 'gallery gallery gallery gallery';
}
.section-header {
grid-area: header;
font-size: var(--text-lg);
}
.section-header h3 {
font-size: var(--text-4xl);
}
.with-cta .section-header {
justify-self: flex-start;
text-align: left;
}
.gallery {
grid-area: gallery;
}
.cta {
grid-area: cta;
}
}
/* ====================================================== */
.mention-card {
display: flex;
height: 7rem;
justify-content: center;
align-items: center;
text-align: center;
border: 1px solid var(--gray-800);
border-radius: 1.5rem;
color: var(--gray-300);
background: var(--gradient-subtle);
box-shadow: var(--shadow-sm);
}
@media (min-width: 50em) {
.mention-card {
border-radius: 1.5rem;
height: 9.5rem;
}
}
</style>

View file

@ -1,39 +0,0 @@
---
import { getCollection } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';
import ContactCTA from '../components/ContactCTA.astro';
import PortfolioPreview from '../components/PortfolioPreview.astro';
import Hero from '../components/Hero.astro';
import Grid from '../components/Grid.astro';
const projects = (await getCollection('work')).sort(
(a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf()
);
---
<BaseLayout
title="My Work | Sebastian Wendel"
description="Learn about Sebastian Wendel's most recent projects"
>
<div class="stack gap-20">
<main class="wrapper stack gap-8">
<Hero
title="My Work"
tagline="See my most recent projects below to get an idea of my past experience."
align="start"
/>
<Grid variant="offset">
{
projects.map((project) => (
<li>
<PortfolioPreview project={project} />
</li>
))
}
</Grid>
</main>
<ContactCTA />
</div>
</BaseLayout>

View file

@ -1,151 +0,0 @@
---
import { CollectionEntry, getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
import ContactCTA from '../../components/ContactCTA.astro';
import Hero from '../../components/Hero.astro';
import Icon from '../../components/Icon.astro';
import Pill from '../../components/Pill.astro';
interface Props {
entry: CollectionEntry<'work'>;
}
// This is a dynamic route that generates a page for every Markdown file in src/content/
// Read more about dynamic routes and this `getStaticPaths` function in the Astro docs:
// https://docs.astro.build/en/core-concepts/routing/#dynamic-routes
export async function getStaticPaths() {
const work = await getCollection('work');
return work.map((entry) => ({
params: { slug: entry.slug },
props: { entry },
}));
}
const { entry } = Astro.props;
const { Content } = await entry.render();
---
<BaseLayout title={entry.data.title} description={entry.data.description}>
<div class="stack gap-20">
<div class="stack gap-15">
<header>
<div class="wrapper stack gap-2">
<a class="back-link" href="/work/"><Icon icon="arrow-left" /> Work</a>
<Hero title={entry.data.title} align="start">
<div class="details">
<div class="tags">
{entry.data.tags.map((t) => <Pill>{t}</Pill>)}
</div>
<p class="description">{entry.data.description}</p>
</div>
</Hero>
</div>
</header>
<main class="wrapper">
<div class="stack gap-10 content">
{entry.data.img && <img src={entry.data.img} alt={entry.data.img_alt || ''} />}
<div class="content">
<Content />
</div>
</div>
</main>
</div>
<ContactCTA />
</div>
</BaseLayout>
<style>
header {
padding-bottom: 2.5rem;
border-bottom: 1px solid var(--gray-800);
}
.back-link {
display: none;
}
.details {
display: flex;
flex-direction: column;
padding: 0.5rem;
gap: 1.5rem;
justify-content: space-between;
align-items: center;
}
.tags {
display: flex;
gap: 0.5rem;
}
.description {
font-size: var(--text-lg);
max-width: 54ch;
}
.content {
max-width: 65ch;
margin-inline: auto;
}
.content > :global(* + *) {
margin-top: 1rem;
}
.content :global(h1),
.content :global(h2),
.content :global(h3),
.content :global(h4),
.content :global(h5) {
margin: 1.5rem 0;
}
.content :global(img) {
border-radius: 1.5rem;
box-shadow: var(--shadow-sm);
background: var(--gradient-subtle);
border: 1px solid var(--gray-800);
}
.content :global(blockquote) {
font-size: var(--text-lg);
font-family: var(--font-brand);
font-weight: 600;
line-height: 1.1;
padding-inline-start: 1.5rem;
border-inline-start: 0.25rem solid var(--accent-dark);
color: var(--gray-0);
}
.back-link,
.content :global(a) {
text-decoration: 1px solid underline transparent;
text-underline-offset: 0.25em;
transition: text-decoration-color var(--theme-transition);
}
.back-link:hover,
.back-link:focus,
.content :global(a:hover),
.content :global(a:focus) {
text-decoration-color: currentColor;
}
@media (min-width: 50em) {
.back-link {
display: block;
align-self: flex-start;
}
.details {
flex-direction: row;
gap: 2.5rem;
}
.content :global(blockquote) {
font-size: var(--text-2xl);
}
}
</style>

55
src/styles/base.css Normal file
View file

@ -0,0 +1,55 @@
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
:root {
--font-sans: "Manrope";
--font-serif: "Literata";
--font-mono: "Martian";
--color-black: #282828;
--color-grey-dark: #515151;
--color-grey-light: #cccccc;
--color-green: #26d07c;
--color-red: #f0506e;
--color-pumpkin: #f57855;
--color-gold: #ffdc50;
--color-forest: #28aa68;
--color-teal: #008791;
--color-arctic: #0cc0df;
--color-aqua: #5082d2;
--color-default: var(--color-black);
--color-primary: var(--color-green);
--color-secondary: var(--color-red);
--color-muted: var(--color-grey-light);
--color-accent: var(--color-teal);
}
::selection {
@apply bg-accent text-white;
}
nav,
header,
footer {
@apply px-20 py-10 gap-10;
}
h1,
h2,
h3,
h4,
h5,
h6 {
@apply font-serif italic font-medium;
}
h1 {
@apply text-6xl;
}
h3 {
@apply text-xl md:text-2xl;
}

View file

@ -1,255 +0,0 @@
/* Global variables */
:root {
/* Colors */
--gray-0: #090b11;
--gray-50: #141925;
--gray-100: #283044;
--gray-200: #3d4663;
--gray-300: #505d84;
--gray-400: #6474a2;
--gray-500: #8490b5;
--gray-600: #a3acc8;
--gray-700: #c3cadb;
--gray-800: #e3e6ee;
--gray-900: #f3f4f7;
--gray-999-basis: 0, 0%, 100%;
--gray-999_40: hsla(var(--gray-999-basis), 0.4);
--gray-999: #ffffff;
--accent-light: #c561f6;
--accent-regular: #7611a6;
--accent-dark: #1c0056;
--accent-overlay: hsla(280, 89%, 67%, 0.33);
--accent-subtle-overlay: var(--accent-overlay);
--accent-text-over: var(--gray-999);
--link-color: var(--accent-regular);
/* Gradients */
--gradient-stop-1: var(--accent-light);
--gradient-stop-2: var(--accent-regular);
--gradient-stop-3: var(--accent-dark);
--gradient-subtle: linear-gradient(150deg, var(--gray-900) 19%, var(--gray-999) 150%);
--gradient-accent: linear-gradient(
150deg,
var(--gradient-stop-1),
var(--gradient-stop-2),
var(--gradient-stop-3)
);
--gradient-accent-orange: linear-gradient(
150deg,
#ca7879,
var(--accent-regular),
var(--accent-dark)
);
--gradient-stroke: linear-gradient(180deg, var(--gray-900), var(--gray-700));
/* Shadows */
--shadow-sm: 0px 6px 3px rgba(9, 11, 17, 0.01), 0px 4px 2px rgba(9, 11, 17, 0.01),
0px 2px 2px rgba(9, 11, 17, 0.02), 0px 0px 1px rgba(9, 11, 17, 0.03);
--shadow-md: 0px 28px 11px rgba(9, 11, 17, 0.01), 0px 16px 10px rgba(9, 11, 17, 0.03),
0px 7px 7px rgba(9, 11, 17, 0.05), 0px 2px 4px rgba(9, 11, 17, 0.06);
--shadow-lg: 0px 62px 25px rgba(9, 11, 17, 0.01), 0px 35px 21px rgba(9, 11, 17, 0.05),
0px 16px 16px rgba(9, 11, 17, 0.1), 0px 4px 9px rgba(9, 11, 17, 0.12);
/* Text Sizes */
--text-sm: 0.875rem;
--text-base: 1rem;
--text-md: 1.125rem;
--text-lg: 1.25rem;
--text-xl: 1.625rem;
--text-2xl: 2.125rem;
--text-3xl: 2.625rem;
--text-4xl: 3.5rem;
--text-5xl: 4.5rem;
/* Fonts */
--font-system: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
--font-body: 'Public Sans', var(--font-system);
--font-brand: Rubik, var(--font-system);
/* Transitions */
--theme-transition: 0.2s ease-in-out;
}
:root.theme-dark {
--gray-0: #ffffff;
--gray-50: #f3f4f7;
--gray-100: #e3e6ee;
--gray-200: #c3cadb;
--gray-300: #a3acc8;
--gray-400: #8490b5;
--gray-500: #6474a2;
--gray-600: #505d84;
--gray-700: #3d4663;
--gray-800: #283044;
--gray-900: #141925;
--gray-999-basis: 225, 31%, 5%;
--gray-999: #090b11;
--accent-light: #1c0056;
--accent-regular: #7611a6;
--accent-dark: #c561f6;
--accent-overlay: hsla(280, 89%, 67%, 0.33);
--accent-subtle-overlay: hsla(281, 81%, 36%, 0.33);
--accent-text-over: var(--gray-0);
--link-color: var(--accent-dark);
--gradient-stop-1: #4c11c6;
--gradient-subtle: linear-gradient(150deg, var(--gray-900) 19%, var(--gray-999) 81%);
--gradient-accent-orange: linear-gradient(
150deg,
#ca7879,
var(--accent-regular),
var(--accent-light)
);
--gradient-stroke: linear-gradient(180deg, var(--gray-600), var(--gray-800));
--shadow-sm: 0px 6px 3px rgba(255, 255, 255, 0.01), 0px 4px 2px rgba(255, 255, 255, 0.01),
0px 2px 2px rgba(255, 255, 255, 0.02), 0px 0px 1px rgba(255, 255, 255, 0.03);
--shadow-md: 0px 28px 11px rgba(255, 255, 255, 0.01), 0px 16px 10px rgba(255, 255, 255, 0.03),
0px 7px 7px rgba(255, 255, 255, 0.05), 0px 2px 4px rgba(255, 255, 255, 0.06);
--shadow-lg: 0px 62px 25px rgba(255, 255, 255, 0.01), 0px 35px 21px rgba(255, 255, 255, 0.05),
0px 16px 16px rgba(255, 255, 255, 0.1), 0px 4px 9px rgba(255, 255, 255, 0.12);
}
html,
body {
height: 100%;
overflow-x: hidden;
}
body {
background-color: var(--gray-999);
color: var(--gray-200);
font-family: var(--font-body);
-webkit-font-smoothing: antialiased;
line-height: 1.5;
}
*,
*::after,
*::before {
box-sizing: border-box;
margin: 0;
}
img {
max-width: 100%;
height: auto;
}
a {
color: var(--link-color);
}
h1,
h2,
h3,
h4,
h5 {
line-height: 1.1;
font-family: var(--font-brand);
font-weight: 600;
color: var(--gray-100);
}
h1 {
font-size: var(--text-5xl);
}
h2 {
font-size: var(--text-4xl);
}
h3 {
font-size: var(--text-3xl);
}
h4 {
font-size: var(--text-2xl);
}
h5 {
font-size: var(--text-xl);
}
/* Utilities */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
.wrapper {
width: 100%;
max-width: 83rem;
margin-inline: auto;
padding-inline: 1.5rem;
}
.stack {
display: flex;
flex-direction: column;
}
.gap-2 {
gap: 0.5rem;
}
.gap-4 {
gap: 1rem;
}
.gap-8 {
gap: 2rem;
}
.gap-10 {
gap: 2.5rem;
}
.gap-15 {
gap: 3.75rem;
}
.gap-20 {
gap: 5rem;
}
.gap-30 {
gap: 7.5rem;
}
.gap-48 {
gap: 12rem;
}
@media (min-width: 50em) {
.lg\:gap-2 {
gap: 0.5rem;
}
.lg\:gap-4 {
gap: 1rem;
}
.lg\:gap-8 {
gap: 2rem;
}
.lg\:gap-10 {
gap: 2.5rem;
}
.lg\:gap-15 {
gap: 3.75rem;
}
.lg\:gap-20 {
gap: 5rem;
}
.lg\:gap-30 {
gap: 7.5rem;
}
.lg\:gap-48 {
gap: 12rem;
}
}

View file

@ -1,8 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {},
},
plugins: [],
};

29
tailwind.config.ts Normal file
View file

@ -0,0 +1,29 @@
import type { Config } from 'tailwindcss'
import forms from '@tailwindcss/forms';
import typography from '@tailwindcss/typography';
import { fontFamily } from "tailwindcss/defaultTheme";
export default {
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,ts,tsx}"],
theme: {
extend: {
fontFamily: {
sans: ["var(--font-sans)", ...fontFamily.sans],
serif: ["var(--font-serif)", ...fontFamily.serif],
mono: ["var(--font-mono)", ...fontFamily.mono],
},
colors: {
default: "var(--color-default)",
primary: "var(--color-primary)",
secondary: "var(--color-secondary)",
muted: "var(--color-muted)",
accent: "var(--color-accent)",
}
},
},
plugins: [
typography,
forms,
],
} satisfies Config

View file

@ -1,26 +1,53 @@
{
"compilerOptions": {
// Enable top-level await, and other modern ESM features.
"target": "ESNext",
"module": "ESNext",
// Enable node-style module resolution, for things like npm package imports.
"moduleResolution": "node",
// Enable JSON imports.
"resolveJsonModule": true,
// Enable stricter transpilation for better output.
"isolatedModules": true,
// Add type definitions for our Vite runtime.
// "types": ["vite/client"],
// Set up path mapping to be understood similar to vite aliases
"baseUrl": ".",
// "paths": {
// "@nz-components/*": ["src/components/*"],
// "@nz-layouts/*": ["src/layouts/*"],
// "@nz-pages/*": ["src/pages/*"],
// "@nz-scripts/*": ["src/scripts/*"],
// "@nz-styles/*": ["src/styles/*"]
// },
// "extends": "astro/tsconfigs/strict",
"strictNullChecks": true
}
}
"extends": "astro/tsconfigs/strict",
"exclude": [
"dist",
"templates",
"result"
],
"compilerOptions": {
"baseUrl": ".",
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"jsx": "react-jsx",
"jsxImportSource": "react",
"paths": {
"@srx/assets": [
"src/assets"
],
"@srx/assets/*": [
"src/assets/*"
],
"@srx/components": [
"src/components"
],
"@srx/components/*": [
"src/components/*"
],
"@srx/layouts": [
"src/layouts"
],
"@srx/layouts/*": [
"src/layouts/*"
],
"@srx/pages": [
"src/pages"
],
"@srx/pages/*": [
"src/pages/*"
],
"@srx/scripts": [
"src/scripts"
],
"@srx/scripts/*": [
"src/scripts/*"
],
"@srx/styles": [
"src/styles"
],
"@srx/styles/*": [
"src/styles/*"
]
}
}
}

View file

@ -1,5 +0,0 @@
import { defineConfig } from 'vite';
const cacheDir = process.env.VITE_CACHE ? process.env.VITE_CACHE : 'node_modules/.vite';
export default defineConfig({ cacheDir });

6277
yarn.lock

File diff suppressed because it is too large Load diff