Compare commits

..

11 Commits

Author SHA1 Message Date
3b46a33b5d Merge branch 'sanity-cms' of https://gitea.rannes.dev/christian/my-portfolio into sanity-cms 2024-05-12 14:11:17 +02:00
a9c9ab3313 added weather application project. 2024-05-12 14:10:55 +02:00
944d35ff6a sanity stuff 2024-04-29 07:20:57 +02:00
55f4db0054 added pocket text package to unpack sanity blocks 2024-04-28 23:00:50 +02:00
c2c2ad29eb still writing groq queries. 2024-04-28 21:10:38 +02:00
eead28f05a changed queries and loads etc. Learned html basics 2024-04-28 13:05:57 +02:00
77f65c1287 learnings loader is working-ish. It's server side now 2024-04-28 00:19:55 +02:00
ec0e91fcfa fixed queries? 2024-04-27 21:24:58 +02:00
dc8baf8d18 more sanity 2024-04-27 20:41:49 +02:00
7ccd7e5b8c updated workkflow and implemented sanity 2024-04-27 19:17:49 +02:00
91ad452247 removed yarn
All checks were successful
Node.js CI / build_app (push) Successful in 15s
Node.js CI / build_image (push) Successful in 1m1s
2024-04-27 18:43:23 +02:00
71 changed files with 1057 additions and 6056 deletions

View File

@ -0,0 +1,41 @@
name: Node.js CI
on:
push:
branches:
- 'main'
jobs:
build_app:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
- run: npm ci
- run: npm run build --production --if-present
build_image:
needs: build_app
runs-on: ubuntu-latest
steps:
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to gitea registry
uses: docker/login-action@v3
with:
registry: gitea.rannes.dev
username: 'christian'
password: '42e55f16fe0008a71fb5acc6ab674c9776b2df6f'
-
name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: gitea.rannes.dev/rannes.dev/my-portfolio:latest

View File

@ -1,21 +0,0 @@
name: Vercel Preview Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
push:
branches-ignore:
- main
jobs:
Deploy-Preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}

View File

@ -1,21 +0,0 @@
name: Vercel Production Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
push:
branches:
- main
jobs:
Deploy-Production:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

1
.gitignore vendored
View File

@ -8,4 +8,3 @@ node_modules
!.env.example !.env.example
vite.config.js.timestamp-* vite.config.js.timestamp-*
vite.config.ts.timestamp-* vite.config.ts.timestamp-*
.vercel

View File

@ -1,10 +1,38 @@
This is a portfolio application built to showcase my projects and try out the svelte framework. # create-svelte
It is built using: Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
- Svelte / Sveltekit ## Creating a project
- Tailwind CSS
The gitea workflow builds docker image and pushed it to this registry. It is then deploy to my infrastructure which you can read more about [here](https://rannes.dev/homelab) If you're seeing this, you've probably already done this step. Congrats!
The project is hosted at [rannes.dev](https://rannes.dev). ```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.

1952
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@
"format": "prettier --write ." "format": "prettier --write ."
}, },
"devDependencies": { "devDependencies": {
"@portabletext/svelte": "^2.1.11",
"@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0", "@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0",
@ -18,9 +19,6 @@
"eslint": "^8.56.0", "eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.35.1", "eslint-plugin-svelte": "^2.35.1",
"flowbite": "^2.3.0",
"flowbite-svelte": "^0.46.1",
"flowbite-svelte-icons": "^1.6.1",
"postcss": "^8.4.38", "postcss": "^8.4.38",
"prettier": "^3.1.1", "prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2", "prettier-plugin-svelte": "^3.1.2",
@ -30,10 +28,7 @@
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@sveltejs/adapter-vercel": "^5.3.0", "@sanity/client": "^6.15.20",
"@vercel/analytics": "^1.3.1", "@sveltejs/adapter-node": "^5.0.1"
"geist": "^1.3.0",
"moment": "^2.30.1",
"pnpm": "^9.1.1"
} }
} }

View File

@ -2,9 +2,9 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
/* body { body {
transition: transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
background-color 0.2s ease-in-out, @apply bg-stone-100 dark:bg-gray-950 text-black dark:text-stone-100 text-center;
color 0.2s ease-in-out; }
/* @apply bg-stone-200 dark:bg-gray-900 text-gray-900 dark:text-stone-200 text-center; */
/* } */

View File

@ -3,24 +3,13 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" /> <link rel="icon" href="%sveltekit.assets%/favicon.png" />
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link <link href="https://fonts.googleapis.com/css2?family=Josefin+Sans:ital,wght@0,100..700;1,100..700&display=swap" rel="stylesheet">
href="https://fonts.googleapis.com/css2?family=Josefin+Sans:ital,wght@0,100..700;1,100..700&display=swap"
rel="stylesheet"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Christian Rannes Dev Portfolio</title>
<meta
name="description"
content="Welcome to my personal website where I share my projects and repos."
/>
%sveltekit.head% %sveltekit.head%
</head> </head>
<body <body data-sveltekit-preload-data="hover" class="font-jose font-light">
data-sveltekit-preload-data="hover"
class="bg-stone-200 dark:bg-primary-900 text-primary-900 dark:text-stone-200"
>
<div style="display: contents">%sveltekit.body%</div> <div style="display: contents">%sveltekit.body%</div>
</body> </body>
</html> </html>

View File

@ -1,42 +0,0 @@
<script>
import { BottomNav, BottomNavItem, Button, ButtonGroup } from 'flowbite-svelte';
import {
HomeSolid,
ProfileCardOutline,
ImageOutline,
MobilePhoneOutline
} from 'flowbite-svelte-icons';
import { writable } from 'svelte/store';
let activeBtn = writable('');
function handleNavItemClick(btnName) {
activeBtn.set(btnName);
}
</script>
{#if $activeBtn === 'projects'}
<ButtonGroup class="fixed md:hidden bottom-20 flex justify-center w-full">
<Button href="/projects/svelte" outline class="flex-col backdrop-blur ">Svelte</Button>
<Button href="/projects/nextjs" outline class="flex-col backdrop-blur">Next.js</Button>
<Button href="/projects/homelab" outline class="flex-col backdrop-blur">Homelab</Button>
</ButtonGroup>
{/if}
<BottomNav
position="fixed"
classInner="grid-cols-2"
outerClass="md:hidden w-full z-50 border-gray-200 dark:bg-slate-900 dark:border-gray-600"
>
<BottomNavItem btnName="home" href="/" on:click={() => handleNavItemClick('home')}>
<HomeSolid
class="w-6 h-6 mb-1 text-gray-500 dark:text-gray-400 group-hover:text-primary-600 dark:group-hover:text-primary-500"
/>
</BottomNavItem>
<BottomNavItem btnName="projects" on:click={() => handleNavItemClick('projects')}>
<ImageOutline
class="w-6 h-6 mb-1 text-gray-500 dark:text-gray-400 group-hover:text-primary-600 dark:group-hover:text-primary-500"
/>
</BottomNavItem>
</BottomNav>

View File

@ -1 +0,0 @@
<!-- Cloudflare Web Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "cc87b1af28264bd7aaf287ba7f905362"}'></script><!-- End Cloudflare Web Analytics -->

View File

@ -1,17 +0,0 @@
<script>
import { Marquee } from 'flowbite-svelte';
import { projects } from '$lib/projects.js';
import VendorIcon from '../ProjectCard/VendorIcon.svelte';
const allVendors = Array.from(
new Map(
projects.flatMap((project) => project.vendors).map((vendor) => [vendor.name, vendor])
).values()
);
</script>
<div class="p-4 bg-stone-200 dark:bg-slate-800 rounded-xl flex items-center overflow-scroll gap-4">
{#each allVendors as vendor}
<VendorIcon {...vendor} />
{/each}
</div>

View File

@ -1,21 +0,0 @@
<script>
import { Marquee } from 'flowbite-svelte';
import { projects } from '$lib/projects.js';
import VendorIcon from '../ProjectCard/VendorIcon.svelte';
const allVendors = Array.from(
new Map(
projects.flatMap((project) => project.vendors).map((vendor) => [vendor.name, vendor])
).values()
);
</script>
<Marquee
speed={0.5}
hoverSpeed={0.25}
class="py-4 bg-stone-200 dark:bg-slate-800 rounded-xl flex items-center"
>
{#each allVendors as vendor}
<VendorIcon {...vendor} />
{/each}
</Marquee>

View File

@ -1,5 +0,0 @@
<script>
export let title;
</script>
<h1 class="text-center text-4xl">{title}</h1>

View File

@ -1,25 +0,0 @@
<script>
import { AccordionItem } from 'flowbite-svelte';
import moment from 'moment';
export let index;
export let link;
export let title;
export let description;
export let published;
const pubAgo = moment(published).fromNow();
const open = index === 0;
</script>
<AccordionItem borderSharedClass="border-slate-400" {...open ? { open: true } : {}}>
<span slot="header" class="flex justify-between items-center w-full">
<h3>{@html title}</h3>
<p class="text-xs mr-2">{pubAgo}</p>
</span>
<div class="flex flex-col">
{#if description}
<p>with the message:</p>
<code class="overflow-x-clip">{@html description}</code>
{/if}
<a class="hover:text-slate-100" href={link}>view commit for more details</a>
</div>
</AccordionItem>

View File

@ -1,26 +0,0 @@
<script>
import ProjectDescription from './ProjectDescription.svelte';
import ProjectHeader from './ProjectHeader.svelte';
import ProjectLinks from './ProjectLinks.svelte';
import ProjectRepo from './ProjectRepo.svelte';
import VendorGallery from './VendorGallery.svelte';
//Props
export let title;
export let url;
export let description;
export let repo;
export let rss;
export let vendors;
</script>
<div class="pt-12">
<div class="flex justify-start items-center gap-4">
<ProjectHeader {title} />
<ProjectLinks {url} {repo}/>
</div>
<hr class="border-slate-400 border-1" />
<ProjectDescription {description} />
<VendorGallery {vendors} />
<ProjectRepo {repo} {rss} {url} />
</div>

View File

@ -1,5 +0,0 @@
<script>
export let description;
</script>
<p>{@html description}</p>

View File

@ -1,5 +0,0 @@
<script>
export let title;
</script>
<h3 class="text-3xl">{title}</h3>

View File

@ -1,18 +0,0 @@
<script>
import { GithubSolid, GlobeOutline } from "flowbite-svelte-icons";
export let url;
export let repo;
</script>
<div class="flex gap-4">
<div class="hover:scale-110">
<a href={url}>
<GlobeOutline class="mx-auto" />
</a>
</div>
<div class="hover:scale-110">
<a href={repo}>
<GithubSolid class="mx-auto" />
</a>
</div>
</div>

View File

@ -1,6 +0,0 @@
<script>
import RssContainer from './RssContainer.svelte';
export let rss;
</script>
<RssContainer url={rss} />

View File

@ -1,10 +0,0 @@
<script>
import RssFeed from './RssFeed.svelte';
export let url;
</script>
<div>
<h2 class="text-2xl mt-4">recent commits</h2>
<hr class="border-1 border-slate-400" />
<RssFeed {url} />
</div>

View File

@ -1,72 +0,0 @@
<script>
import { onMount } from 'svelte';
import Spinner from '../Spinner.svelte';
import Commit from './Commit.svelte';
import { Accordion } from 'flowbite-svelte';
export let url;
let feed = null;
let error = null;
async function fetchFeed(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const text = await response.text();
const parser = new DOMParser();
const xml = parser.parseFromString(text, 'application/xml');
const items = Array.from(xml.querySelectorAll('item')).map((item) => {
// Parse description
const descriptionElement = item.querySelector('description');
const descriptionContent = descriptionElement ? descriptionElement.textContent : '';
const tempDivDescription = document.createElement('div');
tempDivDescription.innerHTML = descriptionContent;
const firstLinkDescription = tempDivDescription.querySelector('a')
? tempDivDescription.querySelector('a').href
: '';
if (tempDivDescription.querySelector('a')) {
tempDivDescription.querySelector('a').remove();
}
const cleanedDescription = tempDivDescription.innerHTML.trim();
return {
title: item.querySelector('title')?.textContent,
description: cleanedDescription,
commit: firstLinkDescription,
link: item.querySelector('link')?.textContent,
published: item.querySelector('pubDate')?.textContent,
author: item.querySelector('author')?.textContent,
guid: item.querySelector('guid')?.textContent
};
});
feed = items;
} catch (err) {
error = err.message;
}
}
onMount(() => {
fetchFeed(url);
});
</script>
<div class="my-2">
{#if error}
<p>Error: {error}</p>
{:else if !feed}
<Spinner />
{:else}
<div class="flex flex-col gap-2">
<Accordion flush>
{#each feed.slice(0, 5) as commit, i}
<Commit {...commit} index={i} />
{/each}
</Accordion>
</div>
{/if}
</div>

View File

@ -1,14 +0,0 @@
<script>
import VendorIcon from './VendorIcon.svelte';
export let vendors;
</script>
<div class="my-4 dark:bg-slate-800 mx-auto md:w-fit rounded-2xl p-2">
<h3 class="text-xl mb-2 text-center">built with</h3>
<div class="flex justify-center flex-wrap gap-2">
{#each vendors as vendor}
<VendorIcon {...vendor} />
{/each}
</div>
</div>

View File

@ -1,11 +0,0 @@
<script>
export let name;
export let img;
</script>
<div class="flex flex-col justify-center h-16 hover:scale-110 text-center items-center">
<div class="flex justify-center h-12 w-12">
<img src={img} alt={name} class="min-h-12 min-w-12 self-center" />
</div>
<p class="text-slate-900 dark:text-stone-200">{name}</p>
</div>

View File

@ -1,11 +0,0 @@
<script>
import { projects } from '$lib/projects.js';
import ProjectCard from './ProjectCard/ProjectCard.svelte';
export let category;
</script>
{#each projects as project}
{#if project.category === category}
<ProjectCard {...project} />
{/if}
{/each}

View File

@ -1,19 +0,0 @@
<div role="status">
<svg
aria-hidden="true"
class="inline w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-gray-600 dark:fill-gray-300"
viewBox="0 0 100 101"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
fill="currentColor"
/>
<path
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
fill="currentFill"
/>
</svg>
<span class="sr-only">Loading...</span>
</div>

View File

@ -0,0 +1,48 @@
<script>
// On click function for darkmode switch
import { browser } from '$app/environment';
let darkMode = true;
function handleSwitchDarkMode() {
darkMode = !darkMode;
localStorage.setItem('theme', darkMode ? 'dark' : 'light');
darkMode
? document.documentElement.classList.add('dark')
: document.documentElement.classList.remove('dark');
}
if (browser) {
if (
localStorage.theme === 'dark' ||
(!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.documentElement.classList.add('dark');
darkMode = true;
} else {
document.documentElement.classList.remove('dark');
darkMode = false;
}
}
</script>
<div>
<input checked={darkMode} on:click={handleSwitchDarkMode} type="checkbox" id="theme-toggle" />
<label for="theme-toggle" />
</div>
<style>
#theme-toggle {
@apply invisible;
}
#theme-toggle + label {
@apply inline-block cursor-pointer h-6 w-6 fixed top-4 right-4 rounded-full duration-300 content-[''];
}
#theme-toggle:not(:checked) + label {
@apply bg-yellow-200;
}
#theme-toggle:checked + label {
@apply bg-transparent;
box-shadow: inset -7px -5px 1px 1px #ddd;
}
</style>

View File

@ -1,46 +0,0 @@
<script>
import {
Navbar,
NavBrand,
NavLi,
NavUl,
Dropdown,
DropdownItem,
DarkMode
} from 'flowbite-svelte';
import { ChevronDownOutline } from 'flowbite-svelte-icons';
import logo from '$lib/logo.png';
import { page } from '$app/stores';
$: activeUrl = $page.url.pathname;
</script>
<Navbar class="bg-transparent">
<NavBrand href="/">
<img src={logo} class="me-3 h-6 sm:h-9" alt="Flowbite Logo" />
<span class="self-center whitespace-nowrap text-xl font-semibold dark:text-stone-200"
>rannes.dev</span
>
</NavBrand>
<div class="flex">
<DarkMode btnClass="block sm:hidden" />
</div>
<NavUl class="md:flex-row" {activeUrl}>
<NavLi href="/">home</NavLi>
<NavLi class="cursor-pointer">
projects<ChevronDownOutline class="w-6 h-6 text-primary-800 dark:text-stone-200 inline" />
</NavLi>
<Dropdown
{activeUrl}
activeClass="font-bold text-primary-800 dark:text-stone-200"
class="w-44 z-20"
>
<DropdownItem href="/projects/svelte">svelte</DropdownItem>
<DropdownItem href="/projects/nextjs">nextjs</DropdownItem>
<DropdownItem href="/projects/homelab">homelab</DropdownItem>
</Dropdown>
<NavLi class="hidden sm:block">
<DarkMode btnClass="p-0" />
</NavLi>
</NavUl>
</Navbar>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 333334 199332" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"><defs><style>.fil1{fill:#f90}</style></defs><g id="Layer_x0020_1"><g id="amazon-web-services-2.svg"><path d="M93937 72393c0 4102 443 7428 1219 9867 887 2439 1996 5100 3548 7982 554 887 776 1774 776 2550 0 1109-665 2217-2106 3326l-6985 4656c-998 665-1995 998-2882 998-1109 0-2217-554-3326-1552-1552-1663-2882-3437-3991-5211-1109-1885-2217-3991-3437-6541-8648 10200-19512 15299-32594 15299-9312 0-16740-2661-22172-7982-5432-5322-8204-12417-8204-21286 0-9424 3326-17073 10089-22838s15743-8647 27161-8647c3769 0 7650 332 11752 887 4102 554 8315 1441 12749 2439v-8093c0-8426-1774-14301-5211-17738-3548-3437-9534-5100-18071-5100-3880 0-7871 443-11973 1441s-8093 2217-11973 3769c-1774 776-3104 1219-3880 1441s-1330 332-1774 332c-1552 0-2328-1109-2328-3437v-5432c0-1774 222-3104 776-3880s1552-1552 3104-2328c3880-1996 8537-3659 13969-4989C43606 885 49370 220 55468 220c13193 0 22838 2993 29046 8980 6098 5987 9202 15077 9202 27272v35920h222zM48926 89244c3659 0 7428-665 11419-1995s7539-3769 10532-7095c1774-2106 3104-4435 3770-7095 665-2661 1108-5876 1108-9645v-4656c-3215-776-6652-1441-10199-1885-3548-443-6984-665-10421-665-7428 0-12860 1441-16519 4435-3659 2993-5432 7206-5432 12749 0 5211 1330 9091 4102 11751 2661 2772 6541 4102 11641 4102zm89023 11973c-1996 0-3326-332-4213-1109-887-665-1663-2217-2328-4324l-26053-85697c-665-2217-998-3658-998-4434 0-1774 887-2772 2661-2772h10865c2106 0 3548 333 4324 1109 887 665 1552 2217 2217 4324l18625 73391 17295-73391c554-2217 1219-3659 2106-4324s2439-1109 4435-1109h8869c2106 0 3548 333 4435 1109 887 665 1663 2217 2106 4324l17516 74278 19180-74278c665-2217 1441-3659 2217-4324 887-665 2328-1109 4324-1109h10310c1774 0 2772 887 2772 2772 0 554-111 1109-222 1774s-333 1552-776 2772l-26718 85697c-665 2217-1441 3658-2328 4324-887 665-2328 1109-4213 1109h-9534c-2107 0-3548-333-4435-1109s-1663-2217-2106-4435l-17184-71507-17073 71396c-554 2217-1220 3658-2107 4434s-2439 1109-4434 1109h-9534zm142459 2993c-5765 0-11530-665-17073-1995s-9867-2772-12749-4435c-1774-998-2993-2106-3437-3104-443-998-665-2106-665-3104v-5654c0-2328 887-3437 2550-3437 665 0 1330 111 1995 333s1663 665 2772 1109c3769 1663 7871 2993 12195 3880 4435 887 8758 1330 13193 1330 6984 0 12417-1220 16186-3659s5765-5987 5765-10532c0-3104-998-5654-2993-7760-1996-2107-5765-3991-11197-5765l-16075-4989c-8093-2550-14080-6319-17738-11308-3658-4878-5543-10310-5543-16075 0-4656 998-8758 2993-12306s4656-6652 7982-9091c3326-2550 7095-4434 11530-5765S279190-2 284068-2c2439 0 4989 111 7428 443 2550 333 4878 776 7206 1219 2217 554 4324 1109 6319 1774s3548 1330 4656 1996c1552 887 2661 1774 3326 2771 665 887 998 2107 998 3659v5211c0 2328-887 3548-2550 3548-887 0-2328-444-4213-1331-6319-2882-13415-4324-21286-4324-6319 0-11308 998-14745 3104s-5211 5321-5211 9867c0 3104 1109 5765 3326 7871s6319 4213 12195 6097l15743 4989c7982 2550 13747 6098 17184 10643s5100 9756 5100 15521c0 4767-998 9091-2882 12860-1996 3770-4656 7095-8093 9756-3437 2771-7539 4767-12306 6208-4989 1552-10199 2328-15854 2328z" fill="#252f3e"/><path class="fil1" d="M301362 158091c-36474 26940-89467 41241-135031 41241-63858 0-121395-23614-164854-62859-3437-3104-332-7317 3770-4878 47006 27272 104988 43791 164964 43791 40465 0 84921-8426 125830-25721 6097-2772 11308 3991 5321 8426z"/><path class="fil1" d="M316550 140796c-4656-5987-30820-2883-42682-1441-3548 443-4102-2661-887-4989 20842-14634 55099-10421 59090-5543 3991 4989-1109 39246-20620 55653-2993 2550-5876 1220-4545-2106 4435-10976 14301-35698 9645-41574z"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -1,49 +0,0 @@
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M49.0391 25.8854C48.8909 26.9063 48.2177 28.2932 47.4454 29.4991C46.471 31.0206 44.9247 32.0863 43.1551 32.4563L35.3597 34.0864C34.1068 34.3484 32.9707 35.0041 32.1177 35.9576L27.0064 41.671C26.0457 42.7447 25.3744 42.4887 25.3744 41.0485C25.3627 41.1019 22.8376 47.614 29.5295 51.4739C32.1008 52.957 35.802 52.4241 38.3732 50.941L51.997 43.0828C57.092 40.144 60.6893 35.1724 61.885 29.4174C61.9323 29.1897 61.9688 28.9613 62.0083 28.733L49.0391 25.8854Z" fill="url(#paint0_linear_1_55)"/>
<path d="M45.5059 18.0358C48.0771 19.5189 49.1277 21.7269 49.1276 24.6931C49.1276 25.0958 49.096 25.4936 49.0391 25.8854L54.5285 28.2434L62.0083 28.7329C62.966 23.1899 61.0891 17.4844 57.7242 12.9493C55.192 9.53637 51.9336 6.57463 48.0164 4.31512C44.8343 2.47968 41.5275 1.27038 38.2052 0.606812L34.4724 5.44082L33.2932 10.9915L45.5059 18.0358Z" fill="url(#paint1_linear_1_55)"/>
<path d="M1.56719 22.1036C1.5658 22.108 1.56966 22.1092 1.57112 22.1049C1.85917 21.2409 2.22036 20.2771 2.67128 19.2474C5.02669 13.8686 9.56572 10.2812 15.1498 8.45216C20.7339 6.62311 26.831 7.26425 31.9203 10.1998L33.293 10.9916L38.205 0.606824C22.5819 -2.51353 6.61456 6.66507 1.58706 22.0434C1.58465 22.0508 1.57591 22.0765 1.56719 22.1036Z" fill="url(#paint2_linear_1_55)"/>
<path d="M37.8396 50.9409C35.2684 52.424 32.1005 52.424 29.5293 50.9409C29.1803 50.7396 28.8512 50.5132 28.5401 50.2682L24.018 53.3771L20.1205 59.6753C24.4466 63.2755 30.0641 64.4329 35.6778 63.7892C39.9024 63.3048 44.0989 61.9665 48.0162 59.707C51.1983 57.8715 53.9 55.6151 56.1363 53.0724L53.8124 47.4257L50.0523 43.8966L37.8396 50.9409Z" fill="url(#paint3_linear_1_55)"/>
<path d="M28.5401 50.2682C26.5591 48.7077 25.3742 46.3143 25.3742 43.7508V43.4951V22.1448C25.3742 20.9374 25.7299 20.7321 26.7766 21.3359C25.1645 20.406 21.4404 17.214 16.8422 19.8662C14.271 21.3493 12.1537 24.6231 12.1537 27.5892V43.3057C12.1537 49.1833 15.198 55.3145 19.5888 59.2265C19.7625 59.3812 19.9423 59.5271 20.1205 59.6753L28.5401 50.2682Z" fill="url(#paint4_linear_1_55)"/>
<path d="M55.8209 10.6248C55.8178 10.6214 55.8147 10.6241 55.8178 10.6275C56.4227 11.3087 57.0776 12.1032 57.7447 13.0081C61.2296 17.7354 62.5317 23.7228 61.3252 29.4687C60.1186 35.2146 56.5143 40.1693 51.4251 43.1048L50.0523 43.8966L56.1363 53.0724C66.6528 41.1154 66.68 22.711 55.8631 10.672C55.8579 10.6663 55.8401 10.6459 55.8209 10.6248Z" fill="url(#paint5_linear_1_55)"/>
<path d="M12.6871 27.5893C12.6871 24.6231 14.271 21.8823 16.8423 20.3992C17.1913 20.1978 17.552 20.0263 17.92 19.8796L17.4861 14.4127L14.4372 8.15784C9.15342 10.1007 4.8794 14.1159 2.63056 19.2948C0.938193 23.1921 1.9584e-05 27.4921 0 32.0111C0 35.682 0.605098 39.1477 1.69106 42.354L7.74782 43.1666L12.6871 41.6779V27.5893Z" fill="url(#paint6_linear_1_55)"/>
<path d="M17.9201 19.8796C20.2632 18.9459 22.9304 19.1174 25.1526 20.3992L25.3742 20.527L43.165 30.7888C44.413 31.5086 44.2996 32.217 42.889 32.5119L43.9153 32.2973C45.2658 32.0149 46.4996 31.3248 47.4431 30.3191C49.0653 28.5899 49.6609 26.5036 49.6609 24.6931C49.6609 21.727 48.077 18.9861 45.5057 17.503L31.882 9.64479C26.787 6.70596 20.6787 6.0793 15.0922 7.92227C14.8712 7.99516 14.6549 8.07781 14.4373 8.15783L17.9201 19.8796Z" fill="url(#paint7_linear_1_55)"/>
<path d="M38.6444 63.3048C38.6489 63.3039 38.648 63.2999 38.6436 63.3008C37.7506 63.4835 36.7345 63.653 35.6164 63.7777C29.7762 64.4291 23.935 62.5621 19.5575 58.6452C15.1799 54.7283 12.6871 49.1325 12.6871 43.2615L12.6871 41.6779L1.6911 42.354C6.79779 57.4313 22.7379 66.6571 38.5823 63.3177C38.5899 63.3161 38.6165 63.3108 38.6444 63.3048Z" fill="url(#paint8_linear_1_55)"/>
<defs>
<linearGradient id="paint0_linear_1_55" x1="40.1202" y1="47.5399" x2="46.4152" y2="25.6136" gradientUnits="userSpaceOnUse">
<stop stop-color="#1724C9"/>
<stop offset="1" stop-color="#1C64F2"/>
</linearGradient>
<linearGradient id="paint1_linear_1_55" x1="54.6189" y1="20.8006" x2="38.0595" y2="4.29961" gradientUnits="userSpaceOnUse">
<stop stop-color="#1C64F2"/>
<stop offset="1" stop-color="#0092FF"/>
</linearGradient>
<linearGradient id="paint2_linear_1_55" x1="32.3289" y1="10.0423" x2="7.34863" y2="11.6208" gradientUnits="userSpaceOnUse">
<stop stop-color="#0092FF"/>
<stop offset="1" stop-color="#45B2FF"/>
</linearGradient>
<linearGradient id="paint3_linear_1_55" x1="30.6395" y1="57.3253" x2="53.0731" y2="51.2718" gradientUnits="userSpaceOnUse">
<stop stop-color="#1C64F2"/>
<stop offset="1" stop-color="#0092FF"/>
</linearGradient>
<linearGradient id="paint4_linear_1_55" x1="14.5375" y1="31.3654" x2="30.4648" y2="47.8694" gradientUnits="userSpaceOnUse">
<stop stop-color="#1724C9"/>
<stop offset="1" stop-color="#1C64F2"/>
</linearGradient>
<linearGradient id="paint5_linear_1_55" x1="50.9008" y1="43.2713" x2="62.0138" y2="20.8691" gradientUnits="userSpaceOnUse">
<stop stop-color="#0092FF"/>
<stop offset="1" stop-color="#45B2FF"/>
</linearGradient>
<linearGradient id="paint6_linear_1_55" x1="10.7277" y1="18.262" x2="4.78107" y2="40.6131" gradientUnits="userSpaceOnUse">
<stop stop-color="#1C64F2"/>
<stop offset="1" stop-color="#0092FF"/>
</linearGradient>
<linearGradient id="paint7_linear_1_55" x1="41.0862" y1="17.1988" x2="19.3554" y2="22.6094" gradientUnits="userSpaceOnUse">
<stop stop-color="#1724C9"/>
<stop offset="1" stop-color="#1C64F2"/>
</linearGradient>
<linearGradient id="paint8_linear_1_55" x1="12.8135" y1="42.7133" x2="26.6651" y2="63.5493" gradientUnits="userSpaceOnUse">
<stop stop-color="#0092FF"/>
<stop offset="1" stop-color="#45B2FF"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -1,49 +0,0 @@
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M49.0391 25.8854C48.8909 26.9063 48.2177 28.2932 47.4454 29.4991C46.471 31.0206 44.9247 32.0863 43.1551 32.4563L35.3597 34.0864C34.1068 34.3484 32.9707 35.0041 32.1177 35.9576L27.0064 41.671C26.0457 42.7447 25.3744 42.4887 25.3744 41.0485C25.3627 41.1019 22.8376 47.614 29.5295 51.4739C32.1008 52.957 35.802 52.4241 38.3732 50.941L51.997 43.0828C57.092 40.144 60.6893 35.1724 61.885 29.4174C61.9323 29.1897 61.9688 28.9613 62.0083 28.733L49.0391 25.8854Z" fill="url(#paint0_linear_1_55)"/>
<path d="M45.5059 18.0358C48.0771 19.5189 49.1277 21.7269 49.1276 24.6931C49.1276 25.0958 49.096 25.4936 49.0391 25.8854L54.5285 28.2434L62.0083 28.7329C62.966 23.1899 61.0891 17.4844 57.7242 12.9493C55.192 9.53637 51.9336 6.57463 48.0164 4.31512C44.8343 2.47968 41.5275 1.27038 38.2052 0.606812L34.4724 5.44082L33.2932 10.9915L45.5059 18.0358Z" fill="url(#paint1_linear_1_55)"/>
<path d="M1.56719 22.1036C1.5658 22.108 1.56966 22.1092 1.57112 22.1049C1.85917 21.2409 2.22036 20.2771 2.67128 19.2474C5.02669 13.8686 9.56572 10.2812 15.1498 8.45216C20.7339 6.62311 26.831 7.26425 31.9203 10.1998L33.293 10.9916L38.205 0.606824C22.5819 -2.51353 6.61456 6.66507 1.58706 22.0434C1.58465 22.0508 1.57591 22.0765 1.56719 22.1036Z" fill="url(#paint2_linear_1_55)"/>
<path d="M37.8396 50.9409C35.2684 52.424 32.1005 52.424 29.5293 50.9409C29.1803 50.7396 28.8512 50.5132 28.5401 50.2682L24.018 53.3771L20.1205 59.6753C24.4466 63.2755 30.0641 64.4329 35.6778 63.7892C39.9024 63.3048 44.0989 61.9665 48.0162 59.707C51.1983 57.8715 53.9 55.6151 56.1363 53.0724L53.8124 47.4257L50.0523 43.8966L37.8396 50.9409Z" fill="url(#paint3_linear_1_55)"/>
<path d="M28.5401 50.2682C26.5591 48.7077 25.3742 46.3143 25.3742 43.7508V43.4951V22.1448C25.3742 20.9374 25.7299 20.7321 26.7766 21.3359C25.1645 20.406 21.4404 17.214 16.8422 19.8662C14.271 21.3493 12.1537 24.6231 12.1537 27.5892V43.3057C12.1537 49.1833 15.198 55.3145 19.5888 59.2265C19.7625 59.3812 19.9423 59.5271 20.1205 59.6753L28.5401 50.2682Z" fill="url(#paint4_linear_1_55)"/>
<path d="M55.8209 10.6248C55.8178 10.6214 55.8147 10.6241 55.8178 10.6275C56.4227 11.3087 57.0776 12.1032 57.7447 13.0081C61.2296 17.7354 62.5317 23.7228 61.3252 29.4687C60.1186 35.2146 56.5143 40.1693 51.4251 43.1048L50.0523 43.8966L56.1363 53.0724C66.6528 41.1154 66.68 22.711 55.8631 10.672C55.8579 10.6663 55.8401 10.6459 55.8209 10.6248Z" fill="url(#paint5_linear_1_55)"/>
<path d="M12.6871 27.5893C12.6871 24.6231 14.271 21.8823 16.8423 20.3992C17.1913 20.1978 17.552 20.0263 17.92 19.8796L17.4861 14.4127L14.4372 8.15784C9.15342 10.1007 4.8794 14.1159 2.63056 19.2948C0.938193 23.1921 1.9584e-05 27.4921 0 32.0111C0 35.682 0.605098 39.1477 1.69106 42.354L7.74782 43.1666L12.6871 41.6779V27.5893Z" fill="url(#paint6_linear_1_55)"/>
<path d="M17.9201 19.8796C20.2632 18.9459 22.9304 19.1174 25.1526 20.3992L25.3742 20.527L43.165 30.7888C44.413 31.5086 44.2996 32.217 42.889 32.5119L43.9153 32.2973C45.2658 32.0149 46.4996 31.3248 47.4431 30.3191C49.0653 28.5899 49.6609 26.5036 49.6609 24.6931C49.6609 21.727 48.077 18.9861 45.5057 17.503L31.882 9.64479C26.787 6.70596 20.6787 6.0793 15.0922 7.92227C14.8712 7.99516 14.6549 8.07781 14.4373 8.15783L17.9201 19.8796Z" fill="url(#paint7_linear_1_55)"/>
<path d="M38.6444 63.3048C38.6489 63.3039 38.648 63.2999 38.6436 63.3008C37.7506 63.4835 36.7345 63.653 35.6164 63.7777C29.7762 64.4291 23.935 62.5621 19.5575 58.6452C15.1799 54.7283 12.6871 49.1325 12.6871 43.2615L12.6871 41.6779L1.6911 42.354C6.79779 57.4313 22.7379 66.6571 38.5823 63.3177C38.5899 63.3161 38.6165 63.3108 38.6444 63.3048Z" fill="url(#paint8_linear_1_55)"/>
<defs>
<linearGradient id="paint0_linear_1_55" x1="40.1202" y1="47.5399" x2="46.4152" y2="25.6136" gradientUnits="userSpaceOnUse">
<stop stop-color="#1724C9"/>
<stop offset="1" stop-color="#1C64F2"/>
</linearGradient>
<linearGradient id="paint1_linear_1_55" x1="54.6189" y1="20.8006" x2="38.0595" y2="4.29961" gradientUnits="userSpaceOnUse">
<stop stop-color="#1C64F2"/>
<stop offset="1" stop-color="#0092FF"/>
</linearGradient>
<linearGradient id="paint2_linear_1_55" x1="32.3289" y1="10.0423" x2="7.34863" y2="11.6208" gradientUnits="userSpaceOnUse">
<stop stop-color="#0092FF"/>
<stop offset="1" stop-color="#45B2FF"/>
</linearGradient>
<linearGradient id="paint3_linear_1_55" x1="30.6395" y1="57.3253" x2="53.0731" y2="51.2718" gradientUnits="userSpaceOnUse">
<stop stop-color="#1C64F2"/>
<stop offset="1" stop-color="#0092FF"/>
</linearGradient>
<linearGradient id="paint4_linear_1_55" x1="14.5375" y1="31.3654" x2="30.4648" y2="47.8694" gradientUnits="userSpaceOnUse">
<stop stop-color="#1724C9"/>
<stop offset="1" stop-color="#1C64F2"/>
</linearGradient>
<linearGradient id="paint5_linear_1_55" x1="50.9008" y1="43.2713" x2="62.0138" y2="20.8691" gradientUnits="userSpaceOnUse">
<stop stop-color="#0092FF"/>
<stop offset="1" stop-color="#45B2FF"/>
</linearGradient>
<linearGradient id="paint6_linear_1_55" x1="10.7277" y1="18.262" x2="4.78107" y2="40.6131" gradientUnits="userSpaceOnUse">
<stop stop-color="#1C64F2"/>
<stop offset="1" stop-color="#0092FF"/>
</linearGradient>
<linearGradient id="paint7_linear_1_55" x1="41.0862" y1="17.1988" x2="19.3554" y2="22.6094" gradientUnits="userSpaceOnUse">
<stop stop-color="#1724C9"/>
<stop offset="1" stop-color="#1C64F2"/>
</linearGradient>
<linearGradient id="paint8_linear_1_55" x1="12.8135" y1="42.7133" x2="26.6651" y2="63.5493" gradientUnits="userSpaceOnUse">
<stop stop-color="#0092FF"/>
<stop offset="1" stop-color="#45B2FF"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -1,49 +0,0 @@
<svg width="40" height="40" viewBox="0 0 96 96" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M73.5582 38.8281C73.3358 40.3595 72.3261 42.4399 71.1677 44.2486C69.7061 46.5309 67.3867 48.1294 64.7322 48.6845L53.0391 51.1296C51.1598 51.5226 49.4556 52.5062 48.1761 53.9365L40.5091 62.5065C39.0682 64.1171 38.0611 63.733 38.0611 61.5728C38.0436 61.6529 34.2559 71.421 44.2938 77.2108C48.1507 79.4355 53.7025 78.6362 57.5594 76.4115L77.995 64.6242C85.6375 60.216 91.0335 52.7586 92.8271 44.1261C92.898 43.7846 92.9528 43.4419 93.012 43.0995L73.5582 38.8281Z" fill="url(#paint0_linear_2768_3907)"/>
<path d="M68.2584 27.0537C72.1153 29.2783 73.6911 32.5903 73.6911 37.0396C73.6911 37.6436 73.6436 38.2404 73.5583 38.828L81.7924 42.365L93.0121 43.0993C94.4487 34.7848 91.6333 26.2265 86.586 19.4238C82.7877 14.3045 77.9001 9.86189 72.0242 6.47262C67.2511 3.71946 62.2909 1.9055 57.3074 0.910156L51.7082 8.16118L49.9395 16.4873L68.2584 27.0537Z" fill="url(#paint1_linear_2768_3907)"/>
<path d="M2.35055 33.1554C2.34845 33.162 2.35425 33.1639 2.35643 33.1573C2.78851 31.8614 3.33029 30.4156 4.00667 28.8711C7.53979 20.8029 14.3483 15.4219 22.7245 12.6782C31.1006 9.93467 40.2463 10.8964 47.8802 15.2996L49.9393 16.4873L57.3073 0.910235C33.8726 -3.77029 9.92159 9.9976 2.38034 33.0651C2.37674 33.0762 2.36363 33.1147 2.35055 33.1554Z" fill="url(#paint2_linear_2768_3907)"/>
<path d="M56.7594 76.4112C52.9026 78.6359 48.1507 78.6359 44.2939 76.4112C43.7704 76.1092 43.2768 75.7697 42.81 75.4021L36.027 80.0655L30.1807 89.5128C36.6698 94.913 45.0962 96.6491 53.5167 95.6836C59.8535 94.9569 66.1484 92.9495 72.0242 89.5603C76.7974 86.8071 80.8499 83.4225 84.2045 79.6084L80.7186 71.1384L75.0784 65.8447L56.7594 76.4112Z" fill="url(#paint3_linear_2768_3907)"/>
<path d="M42.8101 75.4019C39.8385 73.0612 38.0612 69.4711 38.0612 65.6258V65.2423V33.2168C38.0612 31.4056 38.5948 31.0978 40.1648 32.0034C37.7467 30.6086 32.1606 25.8205 25.2633 29.7989C21.4065 32.0236 18.2305 36.9342 18.2305 41.3834V64.9581C18.2305 73.7746 22.7969 82.9713 29.3832 88.8393C29.6437 89.0714 29.9134 89.2902 30.1807 89.5126L42.8101 75.4019Z" fill="url(#paint4_linear_2768_3907)"/>
<path d="M83.7314 15.9369C83.7268 15.9318 83.7223 15.9359 83.7268 15.941C84.6342 16.9629 85.6166 18.1545 86.6173 19.512C91.8446 26.6029 93.7977 35.5839 91.988 44.2028C90.1781 52.8217 84.7717 60.2537 77.1377 64.657L75.0786 65.8447L84.2047 79.6084C99.9793 61.6728 100.02 34.0663 83.7948 16.0078C83.7871 15.9992 83.7602 15.9686 83.7314 15.9369Z" fill="url(#paint5_linear_2768_3907)"/>
<path d="M19.0306 41.384C19.0306 36.9348 21.4065 32.8234 25.2634 30.5988C25.7869 30.2968 26.328 30.0396 26.8801 29.8195L26.2291 21.6191L21.6558 12.2368C13.7301 15.1511 7.31911 21.1739 3.94584 28.9422C1.40729 34.7882 2.9376e-05 41.2383 0 48.0167C0 53.5231 0.907647 58.7216 2.5366 63.5311L11.6217 64.75L19.0306 62.517V41.384V41.384Z" fill="url(#paint6_linear_2768_3907)"/>
<path d="M26.88 29.8195C30.3947 28.4189 34.3955 28.6762 37.7287 30.5988L38.0612 30.7906L64.7473 46.1832C66.6194 47.263 66.4492 48.3255 64.3334 48.7679L65.8728 48.4461C67.8986 48.0225 69.7492 46.9873 71.1645 45.4787C73.5979 42.8849 74.4912 39.7555 74.4912 37.0398C74.4912 32.5905 72.1153 28.4792 68.2585 26.2546L47.8229 14.4672C40.1804 10.059 31.0179 9.11901 22.6382 11.8835C22.3067 11.9928 21.9822 12.1168 21.6558 12.2368L26.88 29.8195Z" fill="url(#paint7_linear_2768_3907)"/>
<path d="M57.9666 94.9574C57.9733 94.956 57.9721 94.95 57.9653 94.9514C56.6259 95.2255 55.1017 95.4797 53.4247 95.6667C44.6642 96.6439 35.9025 93.8433 29.3362 87.968C22.7698 82.0927 19.0307 73.699 19.0307 64.8925L19.0306 62.5171L2.53662 63.5311C10.1967 86.1472 34.1068 99.9859 57.8734 94.9768C57.8848 94.9744 57.9247 94.9665 57.9666 94.9574Z" fill="url(#paint8_linear_2768_3907)"/>
<defs>
<linearGradient id="paint0_linear_2768_3907" x1="60.1798" y1="71.3098" x2="69.6224" y2="38.4205" gradientUnits="userSpaceOnUse">
<stop stop-color="#A72F09"/>
<stop offset="1" stop-color="#F83C00"/>
</linearGradient>
<linearGradient id="paint1_linear_2768_3907" x1="81.9279" y1="31.2009" x2="57.089" y2="6.44934" gradientUnits="userSpaceOnUse">
<stop stop-color="#F83C00"/>
<stop offset="1" stop-color="#F83C00"/>
</linearGradient>
<linearGradient id="paint2_linear_2768_3907" x1="48.4931" y1="15.0634" x2="11.0227" y2="17.4312" gradientUnits="userSpaceOnUse">
<stop stop-color="#F83C00"/>
<stop offset="1" stop-color="#F83C00"/>
</linearGradient>
<linearGradient id="paint3_linear_2768_3907" x1="45.9592" y1="85.9878" x2="79.6097" y2="76.9076" gradientUnits="userSpaceOnUse">
<stop stop-color="#F83C00"/>
<stop offset="1" stop-color="#F83C00"/>
</linearGradient>
<linearGradient id="paint4_linear_2768_3907" x1="21.8062" y1="47.0477" x2="45.6971" y2="71.8037" gradientUnits="userSpaceOnUse">
<stop stop-color="#A72F09"/>
<stop offset="1" stop-color="#F83C00"/>
</linearGradient>
<linearGradient id="paint5_linear_2768_3907" x1="76.3514" y1="64.9067" x2="93.0208" y2="31.3033" gradientUnits="userSpaceOnUse">
<stop stop-color="#F83C00"/>
<stop offset="1" stop-color="#F83C00"/>
</linearGradient>
<linearGradient id="paint6_linear_2768_3907" x1="16.0916" y1="27.393" x2="7.17161" y2="60.9197" gradientUnits="userSpaceOnUse">
<stop stop-color="#D03504"/>
<stop offset="1" stop-color="#F83C00"/>
</linearGradient>
<linearGradient id="paint7_linear_2768_3907" x1="61.6291" y1="25.7983" x2="29.0329" y2="33.9141" gradientUnits="userSpaceOnUse">
<stop stop-color="#A72E08"/>
<stop offset="1" stop-color="#CF3403"/>
</linearGradient>
<linearGradient id="paint8_linear_2768_3907" x1="19.2203" y1="64.0702" x2="39.9976" y2="95.3241" gradientUnits="userSpaceOnUse">
<stop stop-color="#F83C00"/>
<stop offset="1" stop-color="#F83C00" stop-opacity="0.52"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 122.88 45.91" style="enable-background:new 0 0 122.88 45.91" xml:space="preserve"><style type="text/css">.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#00ACD7;} .st1{fill:#00ACD7;}</style><g><path class="st0" d="M9.27,13.9c-0.24,0-0.3-0.12-0.18-0.3l1.26-1.62c0.12-0.18,0.42-0.3,0.66-0.3l21.36,0 c0.24,0,0.3,0.18,0.18,0.36l-1.02,1.56c-0.12,0.18-0.42,0.36-0.6,0.36L9.27,13.9L9.27,13.9z"/><path class="st0" d="M0.24,19.41c-0.24,0-0.3-0.12-0.18-0.3l1.26-1.62c0.12-0.18,0.42-0.3,0.66-0.3h27.28 c0.24,0,0.36,0.18,0.3,0.36l-0.48,1.44c-0.06,0.24-0.3,0.36-0.54,0.36L0.24,19.41L0.24,19.41z"/><path class="st0" d="M14.72,24.91c-0.24,0-0.3-0.18-0.18-0.36l0.84-1.5c0.12-0.18,0.36-0.36,0.6-0.36l11.97,0 c0.24,0,0.36,0.18,0.36,0.42l-0.12,1.44c0,0.24-0.24,0.42-0.42,0.42L14.72,24.91L14.72,24.91z"/><path class="st0" d="M76.82,12.82c-3.77,0.96-6.34,1.68-10.05,2.63c-0.9,0.24-0.96,0.3-1.74-0.6c-0.9-1.02-1.56-1.67-2.81-2.27 c-3.77-1.85-7.42-1.32-10.83,0.9c-4.07,2.63-6.16,6.52-6.1,11.37c0.06,4.79,3.35,8.73,8.08,9.39c4.07,0.54,7.48-0.9,10.17-3.95 c0.54-0.66,1.02-1.38,1.62-2.21c-2.15,0-4.85,0-11.55,0c-1.26,0-1.56-0.78-1.14-1.79c0.78-1.85,2.21-4.97,3.05-6.52 c0.18-0.36,0.6-0.96,1.5-0.96h21.78c-0.12,1.62-0.12,3.23-0.36,4.85c-0.66,4.31-2.27,8.26-4.91,11.73 c-4.31,5.68-9.93,9.21-17.05,10.17c-5.86,0.78-11.31-0.36-16.09-3.95c-4.43-3.35-6.94-7.78-7.6-13.28 c-0.78-6.52,1.14-12.38,5.09-17.53c4.25-5.56,9.87-9.09,16.75-10.35c5.62-1.02,11.01-0.36,15.85,2.93 c3.17,2.09,5.44,4.97,6.94,8.44C77.78,12.35,77.54,12.64,76.82,12.82L76.82,12.82L76.82,12.82z"/><path class="st1" d="M96.62,45.91c-5.44-0.12-10.41-1.68-14.6-5.26c-3.53-3.05-5.74-6.94-6.46-11.55 c-1.08-6.76,0.78-12.74,4.85-18.07c4.37-5.74,9.63-8.73,16.75-9.99c6.1-1.08,11.85-0.48,17.05,3.05c4.73,3.23,7.66,7.6,8.44,13.34 c1.02,8.08-1.32,14.66-6.88,20.28c-3.95,4.01-8.79,6.52-14.36,7.66C99.79,45.67,98.18,45.73,96.62,45.91L96.62,45.91L96.62,45.91z M110.86,21.74c-0.06-0.78-0.06-1.38-0.18-1.97c-1.08-5.92-6.52-9.27-12.21-7.96c-5.56,1.26-9.15,4.79-10.47,10.41 c-1.08,4.67,1.2,9.39,5.5,11.31c3.29,1.44,6.58,1.26,9.75-0.36C107.99,30.71,110.56,26.88,110.86,21.74L110.86,21.74z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 1.5C4.41015 1.5 1.5 4.41015 1.5 8C1.5 11.5899 4.41015 14.5 8 14.5C9.35329 14.5 10.6088 14.0871 11.6492 13.3799L6 6.57712V11.25C6 11.6642 5.66421 12 5.25 12C4.83579 12 4.5 11.6642 4.5 11.25V4.5C4.5 4.184 4.69807 3.9019 4.99529 3.79458C5.29251 3.68726 5.62511 3.77775 5.82699 4.02085L13.3008 13.0209C13.5622 13.3357 13.523 13.802 13.2127 14.0687C11.813 15.272 9.99057 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8C16 8.76428 15.8926 9.50473 15.6916 10.2065C15.5936 10.5489 15.4733 10.8818 15.3325 11.2037C15.1665 11.5832 14.7243 11.7562 14.3448 11.5902C13.9653 11.4242 13.7922 10.982 13.9583 10.6025C14.0725 10.3413 14.1701 10.0712 14.2496 9.79351C14.4125 9.2247 14.5 8.6232 14.5 8C14.5 4.41015 11.5899 1.5 8 1.5ZM10.5 3.75C10.9142 3.75 11.25 4.08579 11.25 4.5V7.5C11.25 7.91421 10.9142 8.25 10.5 8.25C10.0858 8.25 9.75 7.91421 9.75 7.5V4.5C9.75 4.08579 10.0858 3.75 10.5 3.75Z" fill="#000000"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.6789 15.9759C18.6789 14.5415 17.4796 13.3785 16 13.3785C14.5206 13.3785 13.3211 14.5415 13.3211 15.9759C13.3211 17.4105 14.5206 18.5734 16 18.5734C17.4796 18.5734 18.6789 17.4105 18.6789 15.9759Z" fill="#53C1DE"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.7004 11.1537C25.2661 8.92478 25.9772 4.79148 23.4704 3.39016C20.9753 1.99495 17.7284 4.66843 16.0139 6.27318C14.3044 4.68442 10.9663 2.02237 8.46163 3.42814C5.96751 4.82803 6.73664 8.8928 7.3149 11.1357C4.98831 11.7764 1 13.1564 1 15.9759C1 18.7874 4.98416 20.2888 7.29698 20.9289C6.71658 23.1842 5.98596 27.1909 8.48327 28.5877C10.9973 29.9932 14.325 27.3945 16.0554 25.7722C17.7809 27.3864 20.9966 30.0021 23.4922 28.6014C25.9956 27.1963 25.3436 23.1184 24.7653 20.8625C27.0073 20.221 31 18.7523 31 15.9759C31 13.1835 26.9903 11.7923 24.7004 11.1537ZM24.4162 19.667C24.0365 18.5016 23.524 17.2623 22.8971 15.9821C23.4955 14.7321 23.9881 13.5088 24.3572 12.3509C26.0359 12.8228 29.7185 13.9013 29.7185 15.9759C29.7185 18.07 26.1846 19.1587 24.4162 19.667ZM22.85 27.526C20.988 28.571 18.2221 26.0696 16.9478 24.8809C17.7932 23.9844 18.638 22.9422 19.4625 21.7849C20.9129 21.6602 22.283 21.4562 23.5256 21.1777C23.9326 22.7734 24.7202 26.4763 22.85 27.526ZM9.12362 27.5111C7.26143 26.47 8.11258 22.8946 8.53957 21.2333C9.76834 21.4969 11.1286 21.6865 12.5824 21.8008C13.4123 22.9332 14.2816 23.9741 15.1576 24.8857C14.0753 25.9008 10.9945 28.557 9.12362 27.5111ZM2.28149 15.9759C2.28149 13.874 5.94207 12.8033 7.65904 12.3326C8.03451 13.5165 8.52695 14.7544 9.12123 16.0062C8.51925 17.2766 8.01977 18.5341 7.64085 19.732C6.00369 19.2776 2.28149 18.0791 2.28149 15.9759ZM9.1037 4.50354C10.9735 3.45416 13.8747 6.00983 15.1159 7.16013C14.2444 8.06754 13.3831 9.1006 12.5603 10.2265C11.1494 10.3533 9.79875 10.5569 8.55709 10.8297C8.09125 9.02071 7.23592 5.55179 9.1037 4.50354ZM20.3793 11.5771C21.3365 11.6942 22.2536 11.85 23.1147 12.0406C22.8562 12.844 22.534 13.6841 22.1545 14.5453C21.6044 13.5333 21.0139 12.5416 20.3793 11.5771ZM16.0143 8.0481C16.6054 8.66897 17.1974 9.3623 17.7798 10.1145C16.5985 10.0603 15.4153 10.0601 14.234 10.1137C14.8169 9.36848 15.414 8.67618 16.0143 8.0481ZM9.8565 14.5444C9.48329 13.6862 9.16398 12.8424 8.90322 12.0275C9.75918 11.8418 10.672 11.69 11.623 11.5748C10.9866 12.5372 10.3971 13.5285 9.8565 14.5444ZM11.6503 20.4657C10.6679 20.3594 9.74126 20.2153 8.88556 20.0347C9.15044 19.2055 9.47678 18.3435 9.85796 17.4668C10.406 18.4933 11.0045 19.4942 11.6503 20.4657ZM16.0498 23.9915C15.4424 23.356 14.8365 22.6531 14.2448 21.8971C15.4328 21.9423 16.6231 21.9424 17.811 21.891C17.2268 22.6608 16.6369 23.3647 16.0498 23.9915ZM22.1667 17.4222C22.5677 18.3084 22.9057 19.1657 23.1742 19.9809C22.3043 20.1734 21.3652 20.3284 20.3757 20.4435C21.015 19.4607 21.6149 18.4536 22.1667 17.4222ZM18.7473 20.5941C16.9301 20.72 15.1016 20.7186 13.2838 20.6044C12.2509 19.1415 11.3314 17.603 10.5377 16.0058C11.3276 14.4119 12.2404 12.8764 13.2684 11.4158C15.0875 11.2825 16.9178 11.2821 18.7369 11.4166C19.7561 12.8771 20.6675 14.4086 21.4757 15.9881C20.6771 17.5812 19.7595 19.1198 18.7473 20.5941ZM22.8303 4.4666C24.7006 5.51254 23.8681 9.22726 23.4595 10.8426C22.2149 10.5641 20.8633 10.3569 19.4483 10.2281C18.6239 9.09004 17.7698 8.05518 16.9124 7.15949C18.1695 5.98441 20.9781 3.43089 22.8303 4.4666Z" fill="#53C1DE"/>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><title>file_type_svelte</title><path d="M26.47,5.7A8.973,8.973,0,0,0,14.677,3.246L7.96,7.4a7.461,7.461,0,0,0-3.481,5.009,7.686,7.686,0,0,0,.8,5.058,7.358,7.358,0,0,0-1.151,2.8,7.789,7.789,0,0,0,1.4,6.028,8.977,8.977,0,0,0,11.794,2.458L24.04,24.6a7.468,7.468,0,0,0,3.481-5.009,7.673,7.673,0,0,0-.8-5.062,7.348,7.348,0,0,0,1.152-2.8A7.785,7.785,0,0,0,26.47,5.7" style="fill:#ff3e00"/><path d="M14.022,26.64A5.413,5.413,0,0,1,8.3,24.581a4.678,4.678,0,0,1-.848-3.625,4.307,4.307,0,0,1,.159-.61l.127-.375.344.238a8.76,8.76,0,0,0,2.628,1.274l.245.073-.025.237a1.441,1.441,0,0,0,.271.968,1.63,1.63,0,0,0,1.743.636,1.512,1.512,0,0,0,.411-.175l6.7-4.154a1.366,1.366,0,0,0,.633-.909,1.407,1.407,0,0,0-.244-1.091,1.634,1.634,0,0,0-1.726-.622,1.509,1.509,0,0,0-.413.176l-2.572,1.584a4.934,4.934,0,0,1-1.364.582,5.415,5.415,0,0,1-5.727-2.06A4.678,4.678,0,0,1,7.811,13.1,4.507,4.507,0,0,1,9.9,10.09l6.708-4.154a4.932,4.932,0,0,1,1.364-.581A5.413,5.413,0,0,1,23.7,7.414a4.679,4.679,0,0,1,.848,3.625,4.272,4.272,0,0,1-.159.61l-.127.375-.344-.237a8.713,8.713,0,0,0-2.628-1.274l-.245-.074.025-.237a1.438,1.438,0,0,0-.272-.968,1.629,1.629,0,0,0-1.725-.622,1.484,1.484,0,0,0-.411.176l-6.722,4.14a1.353,1.353,0,0,0-.631.908,1.394,1.394,0,0,0,.244,1.092,1.634,1.634,0,0,0,1.726.621,1.538,1.538,0,0,0,.413-.175l2.562-1.585a4.9,4.9,0,0,1,1.364-.581,5.417,5.417,0,0,1,5.728,2.059,4.681,4.681,0,0,1,.843,3.625A4.5,4.5,0,0,1,22.1,21.905l-6.707,4.154a4.9,4.9,0,0,1-1.364.581" style="fill:#fff"/></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.5 3C5.63333 3 4.46667 4 4 5.99999C4.7 4.99999 5.51667 4.625 6.45 4.87499C6.98252 5.01763 7.36314 5.43155 7.78443 5.88974C8.47074 6.63613 9.26506 7.49999 11 7.49999C12.8667 7.49999 14.0333 6.49999 14.5 4.5C13.8 5.49999 12.9833 5.87499 12.05 5.62499C11.5175 5.48235 11.1369 5.06844 10.7156 4.61025C10.0293 3.86386 9.23494 3 7.5 3ZM4 7.49999C2.13333 7.49999 0.966667 8.49998 0.5 10.5C1.2 9.49998 2.01667 9.12498 2.95 9.37498C3.48252 9.51762 3.86314 9.93154 4.28443 10.3897C4.97074 11.1361 5.76506 12 7.5 12C9.36667 12 10.5333 11 11 8.99998C10.3 9.99998 9.48333 10.375 8.55 10.125C8.01748 9.98234 7.63686 9.56843 7.21557 9.11023C6.52926 8.36385 5.73494 7.49999 4 7.49999Z" stroke="#000000" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 991 B

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 1L24 22H0L12 1Z" fill="#000000"/>
</svg>

Before

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 186 KiB

View File

@ -1,161 +0,0 @@
import svelteIcon from '$lib/images/vendorIcons/svelteIcon.svg';
import tailwindIcon from '$lib/images/vendorIcons/tailwindIcon.svg';
import vercelIcon from '$lib/images/vendorIcons/vercelIcon.svg';
import flowbiteSvelteIcon from '$lib/images/vendorIcons/flowbiteSvelteIcon.svg';
import reactIcon from '$lib/images/vendorIcons/reactIcon.svg';
import nextjsIcon from '$lib/images/vendorIcons/nextjsIcon.svg';
import drizzleIcon from '$lib/images/vendorIcons/drizzleIcon.webp';
import zustandIcon from '$lib/images/vendorIcons/zustandIcon.png';
import shadcnIcon from '$lib/images/vendorIcons/shadcnIcon.png';
import goIcon from '$lib/images/vendorIcons/goIcon.svg';
import awsIcon from '$lib/images/vendorIcons/awsIcon.svg';
export const projects = [
{
category: 'nextjs',
title: 'Software Jobs',
url: 'https://jobs.rannes.dev',
description:
'I wanted an excuse to try out Go, and I also want to find a job. The scraper is built with Go and the Colly package. It runs on a AWS EC2 instance, and the frontend is built with Next.js which is deployed to Vercel.',
repo: 'https://gitea.rannes.dev/rannes.dev/sw-jobs-frontend',
rss: 'https://gitea.rannes.dev/rannes.dev/sw-jobs-frontend.rss',
image: '',
vendors: [
{
name: 'Go',
img: goIcon,
url: 'https://go.dev/'
},
{
name: 'Next.js',
img: nextjsIcon,
url: 'https://nextjs.org/'
},
{
name: 'Tailwind',
img: tailwindIcon,
url: 'https://tailwindcss.com/'
},
{
name: 'Vercel',
img: vercelIcon,
url: 'https://vercel.com/'
},
{
name: 'AWS',
img: awsIcon,
url: 'https://aws.amazon.com/'
}
]
},
{
category: 'svelte',
title: 'Portfolio',
url: 'https://rannes.dev',
description:
'This project was initially to get familiar with Svelte and showcase my future projects. I find myself that I keep coming back to expand on it whenever I need a break from React.',
repo: 'https://gitea.rannes.dev/rannes.dev/my-portfolio',
rss: 'https://gitea.rannes.dev/rannes.dev/my-portfolio.rss',
image: '',
vendors: [
{
name: 'Svelte',
img: svelteIcon,
url: 'https://svelte.dev/'
},
{
name: 'Tailwind',
img: tailwindIcon,
url: 'https://tailwindcss.com/'
},
{
name: 'Flowbite',
img: flowbiteSvelteIcon,
url: 'https://flowbite-svelte.com//'
},
{
name: 'Vercel',
img: vercelIcon,
url: 'https://vercel.com/'
}
]
},
{
category: 'nextjs',
title: 'Online Wine Shop.',
url: 'https://wine-shop-eta.vercel.app/',
description:
"To get practical experience with forms, databases, queries and states I want to build a online wine shop for my friend Ketil (that he didn't ask for). Besides the current technologies, I plan to implement Clerk or Auth.js for auth, and Zustand for state management if neccesary (Something tells me it's needed at least for cart) I am doing my best to implement progressive enhancement in forms with cool hooks like <code class='dark:bg-slate-800 bg-stone-300 rounded p-1'>useActionState</code> and explore caching and the prevention of caching in nextjs and vercel. 🤷",
repo: 'https://gitea.rannes.dev/rannes.dev/wine-shop',
rss: 'https://gitea.rannes.dev/rannes.dev/wine-shop.rss',
image: '',
vendors: [
{
name: 'React',
img: reactIcon,
url: 'https://react.dev/'
},
{
name: 'Next.js',
img: nextjsIcon,
url: 'https://nextjs.org/'
},
{
name: 'Tailwind',
img: tailwindIcon,
url: 'https://tailwindcss.com/'
},
{
name: 'Drizzle',
img: drizzleIcon,
url: 'https://orm.drizzle.team/'
},
{
name: 'Zustand',
img: zustandIcon,
url: 'https://zustand-demo.pmnd.rs/'
},
{
name: 'Shadcn',
img: shadcnIcon,
url: 'https://ui.shadcn.com/'
},
{
name: 'Vercel',
img: vercelIcon,
url: 'https://vercel.com/'
}
]
},
{
category: 'nextjs',
title: 'Local weather',
url: 'https://weather.rannes.dev',
description: 'A simple application to fetch a weekly weather forecast.',
repo: 'https://gitea.rannes.dev/rannes.dev/local-weather',
rss: 'https://gitea.rannes.dev/rannes.dev/local-weather.rss',
image: '',
vendors: [
{
name: 'React',
img: reactIcon,
url: 'https://react.dev/'
},
{
name: 'Next.js',
img: nextjsIcon,
url: 'https://nextjs.org/'
},
{
name: 'Tailwind',
img: tailwindIcon,
url: 'https://tailwindcss.com/'
},
{
name: 'Vercel',
img: vercelIcon,
url: 'https://vercel.com/'
}
]
}
];

25
src/lib/queries.js Normal file
View File

@ -0,0 +1,25 @@
/**
* Example of how you could re-use GROQ queries across different contexts with Javascript.
* As your schema evolves, this pattern will be useful to keep your data in sync across all surfaces.
*/
export async function getPostsQuery() {
const data = await client.fetch(`*[_type == "post"] {
title,
slug,
coverImage {
...,
asset->
},
body,
}`);
if (data) {
return {
posts: data
};
}
return {
status: 500,
body: new Error("Internal Server Error")
};
}

9
src/lib/sanity/client.js Normal file
View File

@ -0,0 +1,9 @@
import { createClient } from "@sanity/client"
export const client = createClient({
projectId: "f4465sc9",
dataset: "production",
apiVersion: "2024-03-11",
// Set to `true` for production environments
useCdn: false,
})

View File

@ -1,25 +1,68 @@
<script> <script>
import { blur, fade } from "svelte/transition";
import "../app.css";
import ThemeSwitch from '$lib/ThemeSwitch.svelte';
import '../app.css'; import '../app.css';
import CloudflareAnalytics from '$lib/CloudflareAnalytics.svelte';
import BottomNavigation from '../lib/BottomNavigation.svelte';
import TopNav from '../lib/TopNav.svelte'; /* Navigation links are generated based on this object.
import { inject } from '@vercel/analytics'; Nav items are added by adding and object to the nav array.
let activeBtn = 'home'; Underscore _ should be added instead of whitespace, and it is then removed when the nav item is instantiated.
function handleNavItemClick(btnName) { */ const nav = [
activeBtn = btnName; {
name: "index",
subPages: [],
},
{
name: "whoami",
subPages: ["about", "resume", "homelab"],
},
{
name: "portfolio",
subPages: ["learnings", "portfolio_project", "next.js_weather"],
},
{
name: "contact",
subPages: ["get_in_touch", "socials"],
},
];
let selected = nav[0]; // keep track of the selected 'page' object.
let intSelected = 0; // selected page index
// change the selected component (the event.originalTarget.id is not accessible in Chrome so switched to event.srcElement.id)
function changeComponent(event) {
selected = nav[event.srcElement.id];
intSelected = event.srcElement.id;
} }
$: activeBtn = activeBtn === 'projects';
inject();
</script> </script>
<CloudflareAnalytics /> <nav class="nav-container h-32 w-full mt-12">
<TopNav /> <ul class="text-center">
<div class="px-2 sm:px-0 mx-auto max-w-xs sm:max-w-md md:max-w-3xl mb-20 md:mb-0"> {#each nav as main,i}
{#if i != 0}
{#if !nav[i].subPages[0]}
<li class="nav-item font-jose inline-block"><a href="/{main.name}" class={selected==nav[i] ? "nav-link text-2xl p-3" : "nav link text-2xl p-3"} on:click={changeComponent} id={i} >{main.name}</a></li>
{:else}
<li class="nav-item font-jose inline-block"><button class={selected==nav[i] ? "nav-link text-2xl p-3" : "nav link text-2xl p-3"} on:click={changeComponent} id={i} >{main.name}</button></li>
{/if}
{/if}
{/each}
</ul>
<hr class="nav-divider max-w-xl h-0.5 border-0 mx-auto bg-black rounded dark:bg-stone-100"/>
{#key selected}
<ul in:blur={{ delay: 250 }} out:blur={{ duration: 250 }} class="text-center h-4 my-1">
{#each selected.subPages as subPage}
<li class="sub-nav-item inline-block font-jose"><a class="sub-nav-link text-xl p-2"href="/{(subPage)}">{subPage.replace(/_/g, ' ')}</a></li>
{/each}
</ul>
{/key}
<li><ThemeSwitch/></li>
</nav>
<div class="container text-center w-3/4 mx-auto font-jose">
<slot /> <slot />
</div> </div>
<BottomNavigation /> <footer class="mt-12">
<footer class=""> <p class="text-sm text-gray-400">built and hosted by christian rannes 2024</p>
<div class="hidden md:block text-sm text-stone-400 mt-12 text-center">
<p>built by christian rannes 2024</p>
</div>
</footer> </footer>

View File

@ -1,29 +1,6 @@
<script> <div class="main-container text-center">
import VendorMarquee from '$lib/Landing/VendorMarquee.svelte'; <h1 class="text-xl mb-2">Welcome to my corner of the internet</h1>
import VendorCarousel from '../lib/Landing/VendorCarousel.svelte'; <p class="text-left">You most likely ended up here after listening to me rambling about the wonders of self hosted services, and how life would be much easier if we could just containerize everything.
import { Heading, Mark } from 'flowbite-svelte';
import portfolio from '$lib/images/portfolio.png';
import hero from '$lib/images/hero.webp';
</script>
<div class="text-xl">
<div class="flex my-4 gap-4">
<Heading tag="h1" class="md:text-right leading-tight">father by day <Mark>developer</Mark> by night</Heading>
<img
src={hero}
alt=""
class="hidden md:block rounded-xl max-h-36 w-auto shadow-inner border border-slate-700"
/>
</div>
<h2 class="py-2">
welcome to my space. For now it is used to document my learnings and share my projects. It might
expand over time.
</h2>
<p class="py-2">
I like to explore many different technologies and frameworks mostly surrounding web development, infrastructure and DevOps.
</p> </p>
<h2 class="py-2"> <p class="italic text-sm mt-8">This page is my initial svelte project to try out the framework, and at the time of writing (24th April 2024) many pages are still lacking content.</p>
This page is my initial portfolio project built in Svelte.
</h2>
<p>You can read all about it <a class="underline" href="/projects/svelte">here</a> and explore the repo on <a class="underline" href="https://gitea.rannes.dev/rannes.dev/my-portfolio">my gitea.</a></p>
</div> </div>

View File

@ -0,0 +1,17 @@
<script>
import migImg from "$lib/images/mig.jpg"
import osImg from "$lib/images/os.webp"
import { fade } from "svelte/transition";
</script>
<div class="page-container" in:fade>
<h1 class="text-xl mb-4">Life is good in Copenhagen</h1>
<div class="article-container md:flex mb-4 items-center text-left">
<p class="">I live in Copenhagen with my partner and children near the water. We love going on expeditions around the city in our cargo bike, or on my electrical skateboard.
When we're not outside I spend a lot of time fiddling around with my homelab, and development projects. You can read more about my projects and homelab under the homelab and portfolio nav.
</p>
<img class="rounded-2xl xl:ml-4 md:w-auto md:h-52 md:ml-4 md:mt-4 sm:ml-0 sm:mt-4 sm:w-full" src={migImg} alt="crazy man"/>
</div>
<p class="mb-4 ">I work in recruitment, and I specialise in building product teams for start ups and scale ups for a small recruitment agency called <a class="underline font-semibold" href="https://www.adveniopeople.com">Advenio People</a></p>
<img src={osImg} alt="A happy man and a beautiful woman both wearing facemasks." class="rounded-full w-1/2 h-auto m-auto">
</div>

View File

@ -0,0 +1 @@
<h1>Under development</h1>

View File

@ -3,22 +3,20 @@
import asrockImg from '$lib/images/asrock.webp'; import asrockImg from '$lib/images/asrock.webp';
import rackImg from '$lib/images/rack.webp'; import rackImg from '$lib/images/rack.webp';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import PageHeader from '$lib/PageHeader.svelte';
const title = 'Homelab';
</script> </script>
<div in:fade> <div in:fade >
<PageHeader {title} /> <h1 class="text-2xl mb-4 font-normal">Homelab</h1>
<div class="content"> <div class="content text-left">
<article> <article>
<h2 class="text-xl ">What is a homelab?</h2> <h2 class="text-xl text-center">What is a homelab?</h2>
<img class="rounded mt-4" src={quoteImg} alt="" /> <img class="rounded mt-4" src={quoteImg} alt="" />
<p class="text-sm italic"> <p class="text-sm italic">
This question was answered very well by the reddit users webtroter and TreAwayDeuce 6 years This question was answered very well by the reddit users webtroter and TreAwayDeuce 6 years
ago. ago.
</p> </p>
<h2 class="text-xl mt-4">Origin and Hardware</h2> <h2 class="text-xl text-center mt-4">Origin and Hardware</h2>
<p> <p>
My interest in “Homelabbing” arose long before I was familiar with the term Homelab. I have My interest in “Homelabbing” arose long before I was familiar with the term Homelab. I have
always been curious, and drawn towards things that are unfamiliar to me. I am also a builder always been curious, and drawn towards things that are unfamiliar to me. I am also a builder
@ -26,9 +24,9 @@
maker-culture. maker-culture.
</p> </p>
<p> <p>
My lab started in 2020, when I wanted to set up my own DNS server at home, to add network My lab started in 2020, when I wanted to set up my own DNS server at home, to add
wide ad-block (Pihole). As I learned more about Linux and containerization I quickly got network wide ad-block (Pihole). As I learned more about Linux and containerization I quickly
drawn into the hobby of self-hosting web-services. got drawn into the hobby of self-hosting web-services.
</p> </p>
<p> <p>
Raspberry Pi's are great, but but the computing resources are limited compared to a x86, so Raspberry Pi's are great, but but the computing resources are limited compared to a x86, so
@ -82,13 +80,11 @@
<p> <p>
The homelab is also connected to two 3D printers, that are running open source custom The homelab is also connected to two 3D printers, that are running open source custom
firmware (klipper) and controlled through a web interface (Mainsail) from any device in the firmware (klipper) and controlled through a web interface (Mainsail) from any device in the
local network. I started with a Ender3, and during my parental leave last year I built <a local network. I started with a Ender3, and during my parental leave last year I built <a class="underline" href="https://vorondesign.com/voron0.2">Voron 0.2</a>. The parts are all sourced, and the
class="underline" rest of the parts are 3D printed in ABS+. It took me roughly 40 hours to build it and
href="https://vorondesign.com/voron0.2">Voron 0.2</a calibrate it.
>. The parts are all sourced, and the rest of the parts are 3D printed in ABS+. It took me
roughly 40 hours to build it and calibrate it.
</p> </p>
<h2 class="text-xl mt-4">OS</h2> <h2 class="text-xl text-center mt-4">OS</h2>
<p> <p>
The server is running ProxmoxVE which is great for experimenting, as I can provision The server is running ProxmoxVE which is great for experimenting, as I can provision
development and test environments easily from templates and spin up machines to experiment development and test environments easily from templates and spin up machines to experiment
@ -96,8 +92,8 @@
Proxmox even though virtualization is not necessarily something I will do a deep dive on. It Proxmox even though virtualization is not necessarily something I will do a deep dive on. It
also makes it easy to separate services in LXC containers and virtual machines. also makes it easy to separate services in LXC containers and virtual machines.
</p> </p>
<h2 class="text-xl mt-4">VMs and LXC</h2> <h2 class="text-xl text-center mt-4">VMs and LXC</h2>
<h3 class="text-lg ">Docker Host</h3> <h3 class="text-lg text-center">Docker Host</h3>
<p> <p>
This VM is my production environment where I run my docker services that have been tested an This VM is my production environment where I run my docker services that have been tested an
properly implemented with network volumes and backup. properly implemented with network volumes and backup.
@ -120,7 +116,8 @@
<li>Portfolio web page</li> <li>Portfolio web page</li>
<p class="italic pl-4"> <p class="italic pl-4">
This is my portfolio page, which will soon be available at rannes.dev. I'm using This is my portfolio page, which will soon be available at rannes.dev. I'm using
svelte/sveltekit. It is currently not exposed to the internet as I am still building it. svelte/sveltekit. It is
currently not exposed to the internet as I am still building it.
</p> </p>
<li>Crowdsec Security Engine</li> <li>Crowdsec Security Engine</li>
<li>Prometheus</li> <li>Prometheus</li>
@ -137,7 +134,7 @@
<li>Kuma Uptime</li> <li>Kuma Uptime</li>
<li>Portainer</li> <li>Portainer</li>
</ul> </ul>
<h3 class="text-lg mt-4">Pi-Hole</h3> <h3 class="text-lg text-center mt-4">Pi-Hole</h3>
<p> <p>
LXC container running Pi-hole dns blocker. This is separate so the network is not affected LXC container running Pi-hole dns blocker. This is separate so the network is not affected
when servicing other VMs. First this was included in the docker-stack but it created too when servicing other VMs. First this was included in the docker-stack but it created too
@ -146,7 +143,7 @@
<p> <p>
For this reason, I am also planning on moving Crowdsec and Traefik to a separate containers. For this reason, I am also planning on moving Crowdsec and Traefik to a separate containers.
</p> </p>
<h3 class="text-lg mt-4">Unraid</h3> <h3 class="text-lg text-center mt-4">Unraid</h3>
<p> <p>
This VM is running Unraid, which is managing my BTRFS array in Raid1. Upon boot it is loaded This VM is running Unraid, which is managing my BTRFS array in Raid1. Upon boot it is loaded
from a USB-stick, and runs from memory. I moved to unraid as it allows me to add more drives from a USB-stick, and runs from memory. I moved to unraid as it allows me to add more drives
@ -154,17 +151,10 @@
have the knowledge (or the will) of storage systems to manage it if I can avoid it. have the knowledge (or the will) of storage systems to manage it if I can avoid it.
</p> </p>
<p>This VM has the SATA controller passed through, for full control of the HDD's.</p> <p>This VM has the SATA controller passed through, for full control of the HDD's.</p>
<h3 class="text-lg mt-4">Development server</h3> <h3 class="text-lg text-center mt-4">Development server</h3>
<p> <p>This vm is my development server. It's running a act_runner paired up with Gitea to build my portfolio project, dockerize it and push it to my container registry. The application then deployed in the staging environment for a last check.</p>
This vm is my development server. It's running a act_runner paired up with Gitea to build my <h2 class="text-xl text-center mt-4">CI/CD</h2>
portfolio project, dockerize it and push it to my container registry. The application then <p>I use Gitea Actions which is similar to Github Actions. I will post a guide soon how to set up CI for your svelte-docker project with Gitea Actions.</p>
deployed in the staging environment for a last check.
</p>
<h2 class="text-xl mt-4">CI/CD</h2>
<p>
I use Gitea Actions which is similar to Github Actions. I will post a guide soon how to set
up CI for your svelte-docker project with Gitea Actions.
</p>
</article> </article>
</div> </div>
</div> </div>

View File

@ -0,0 +1,24 @@
import { client } from '$lib/sanity/client.js'
export async function load({ params }) {
const data = await client.fetch(`*[_type == "post"] {
title,
slug,
_createdAt,
mainImage {
...,
asset->
},
body,
}`);
if (data) {
return {
posts: data
};
}
return {
status: 500,
body: new Error("Internal Server Error")
};
}

View File

@ -0,0 +1,20 @@
<script>
import {PortableText} from '@portabletext/svelte'
export let data;
</script>
{#each data.posts as post}
<div class="border-2 border-slate-500 rounded my-2 text-l p-4">
<img class="max-h-32 mx-auto" src={post.mainImage.asset.url} alt={post.title}>
<h2 class="text-xl">{post.title}</h2>
{#each post.body as block}
<PortableText
value={[
block
]}
/>
{/each}
<p>{post._createdAt}</p>
</div>
{/each}

View File

@ -0,0 +1,2 @@
<h1>hello</h1>
<p>why is this being weird</p>

View File

@ -0,0 +1,2 @@
<h1>This is the login page</h1>
<p>Access denied</p>

View File

@ -0,0 +1,4 @@
<h1 class="text-2xl font-normal">Weather application</h1>
<p>this is a simple application to fetch a weekly weather forecast.</p>
<p>It's built in <span class="font-normal">react/nextjs</span> using <span class="font-normal">typescript</span>, and queries <span class="font-normal">Google Places API</span> for geo location and then queries <span class="font-normal">open-meteo API</span> for the weather forecast.</p>
<p>You can try it out at <a class="underline" href="https://weather.rannes.dev">weather.rannes.dev</a></p>

View File

@ -0,0 +1 @@
<h1>this is the page describing my portfolio project in juuuuuust a second.</h1>

View File

@ -1,12 +0,0 @@
<script>
import { fade } from 'svelte/transition';
import Projects from '$lib/Projects.svelte';
import PageHeader from '$lib/PageHeader.svelte';
const category = 'nextjs';
const title = 'Next.js Projects';
</script>
<div in:fade>
<PageHeader {title} />
<Projects {category} />
</div>

View File

@ -1,13 +0,0 @@
<script>
import { fade } from 'svelte/transition';
import Projects from '$lib/Projects.svelte';
import PageHeader from '$lib/PageHeader.svelte';
const projectRssUrl = 'https://gitea.rannes.dev/rannes.dev/my-portfolio.rss';
const category = 'svelte';
const title = 'Svelte Projects';
</script>
<div in:fade>
<PageHeader {title} />
<Projects {category} />
</div>

View File

@ -0,0 +1,9 @@
<script>
import { fade } from "svelte/transition";
</script>
<div in:fade>
<h1 class="text-xl">Under development</h1>
<p>In the meantime have a look at my <a class="underline" href="https://www.linkedin.com/in/christian-rannes/">linkedin</a></p>
</div>

View File

@ -1,3 +1 @@
<div> <h1>Under development</h1>
<img src="$lib/images/portfolio-card.webp" alt="Socials Card" />
</div>

View File

@ -1,4 +1,4 @@
import adapter from '@sveltejs/adapter-vercel'; import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */ /** @type {import('@sveltejs/kit').Config} */

View File

@ -1,31 +1,14 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
export default { export default {
content: [ content: ['./src/**/*.{html,js,svelte,ts}'],
'./src/**/*.{html,js,svelte,ts}',
'./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}'
],
plugins: [require('flowbite/plugin')],
darkMode: 'class',
theme: { theme: {
extend: { extend: {
colors: { fontFamily: {
// slate "jose": ["Josefin Sans", "sans-serif"]
primary: {
50: '#f8fafc',
100: '#f1f5f9',
200: '#e2e8f0',
300: '#cbd5e1',
400: '#94a3b8',
500: '#64748b',
600: '#475569',
700: '#334155',
800: '#1e293b',
900: '#0f172a'
} }
}, },
fontFamily: { },
jose: ['Josefin Sans', 'sans-serif'] plugins: [],
} darkMode: 'class',
} }
}
};