delete old state
2
.gitattributes
vendored
@ -1,2 +0,0 @@
|
||||
*.afphoto filter=lfs diff=lfs merge=lfs -text
|
||||
*.afdesign filter=lfs diff=lfs merge=lfs -text
|
8
.gitignore
vendored
@ -1,8 +0,0 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/.svelte-kit
|
||||
/package
|
||||
/build
|
||||
.vercel_build_output
|
||||
.vercel
|
||||
*.wpress
|
@ -1 +0,0 @@
|
||||
schema: "https://api.nicco.io/graphql"
|
38
README.md
@ -1,38 +0,0 @@
|
||||
# create-svelte
|
||||
|
||||
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte);
|
||||
|
||||
## Creating a project
|
||||
|
||||
If you're seeing this, you've probably already done this step. Congrats!
|
||||
|
||||
```bash
|
||||
# create a new project in the current directory
|
||||
npm init svelte@next
|
||||
|
||||
# create a new project in my-app
|
||||
npm init svelte@next my-app
|
||||
```
|
||||
|
||||
> Note: the `@next` is temporary
|
||||
|
||||
## 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
|
||||
|
||||
Before creating a production version of your app, install an [adapter](https://kit.svelte.dev/docs#adapters) for your target environment. Then:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
> You can preview the built app with `npm run preview`, regardless of whether you installed an adapter. This should _not_ be used to serve your app in production.
|
14
codegen.yaml
@ -1,14 +0,0 @@
|
||||
schema: https://api.nicco.io/graphql
|
||||
documents: "src/**/*.graphql"
|
||||
generates:
|
||||
./src/lib/gql/gen.ts:
|
||||
plugins:
|
||||
- "@graphql-codegen/typescript"
|
||||
- "@graphql-codegen/typescript-operations"
|
||||
- "@graphql-codegen/typescript-graphql-request"
|
||||
config:
|
||||
maybeValue: "T"
|
||||
typesPrefix: GQL
|
||||
immutableTypes: true
|
||||
useTypeImports: true
|
||||
avoidOptionals: true
|
37
package.json
@ -1,37 +0,0 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "svelte-kit dev",
|
||||
"build": "svelte-kit build",
|
||||
"preview": "svelte-kit preview",
|
||||
"check": "svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"generate": "graphql-codegen",
|
||||
"ci": "pnpm run generate && pnpm run check && pnpm run build"
|
||||
},
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@graphql-codegen/cli": "^2.6.2",
|
||||
"@graphql-codegen/typescript": "^2.4.7",
|
||||
"@graphql-codegen/typescript-graphql-request": "^4.4.2",
|
||||
"@graphql-codegen/typescript-operations": "^2.3.4",
|
||||
"@sveltejs/adapter-static": "^1.0.0-next.29",
|
||||
"@sveltejs/kit": "^1.0.0-next.295",
|
||||
"@types/lunr": "^2.3.4",
|
||||
"graphql": "^15.8.0",
|
||||
"graphql-request": "^3.7.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"svelte": "^3.46.4",
|
||||
"svelte-check": "^2.4.5",
|
||||
"svelte-preprocess": "^4.10.4",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"dayjs": "^1.10.8",
|
||||
"highlight.js": "^11.5.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lunr": "^2.3.9",
|
||||
"svelte-cloudinary": "^0.2.5"
|
||||
}
|
||||
}
|
4470
pnpm-lock.yaml
generated
114
src/app.css
@ -1,114 +0,0 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Jost:wght@300;400&family=Playfair+Display&display=swap');
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
:root {
|
||||
--ff: 'Jost', Roboto, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans,
|
||||
Helvetica Neue, sans-serif;
|
||||
--ff-alt: 'Playfair Display', serif;
|
||||
--clr-light: #ffffff;
|
||||
--clr-dark: #010101;
|
||||
--clr-primary: hsl(219, 90%, 80%);
|
||||
--clr-secondary: hsl(64, 93%, 51%);
|
||||
--clr-error: hsl(0, 73.9%, 65.5%);
|
||||
--clr-transparent-0: hsla(0, 0%, 0%, 0.1);
|
||||
--animation: all 250ms ease;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--clr-light: #010101;
|
||||
--clr-dark: #ffffff;
|
||||
--clr-primary: hsl(219, 90%, 30%);
|
||||
--clr-transparent-0: hsla(0, 0%, 100%, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
|
||||
background-color: var(--clr-light);
|
||||
|
||||
font-family: var(--ff);
|
||||
font-size: 16px;
|
||||
font-weight: lighter;
|
||||
color: var(--clr-dark);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
text-shadow: rgba(0, 0, 0, 0.01) 0 0 1px;
|
||||
}
|
||||
|
||||
@media (min-width: 30em) {
|
||||
body {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: var(--ff-alt);
|
||||
font-weight: normal;
|
||||
margin: 1em 0 0.5em 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: justify;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0.1px solid var(--clr-primary);
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-left: 0px;
|
||||
padding-left: 1em;
|
||||
list-style: square;
|
||||
}
|
||||
|
||||
.progress {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background: var(--clr-light);
|
||||
margin: 0.5em 0;
|
||||
padding: 0.1em 0.5em;
|
||||
border: 1px solid var(--clr-dark);
|
||||
}
|
||||
|
||||
.progress > span {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.progress > div {
|
||||
height: 100%;
|
||||
background: var(--clr-primary);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
height: auto;
|
||||
}
|
23
src/app.html
@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="description" content="Designer & Developer" />
|
||||
<meta name="keywords" content="Web Agency Blog Articles" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,viewport-fit=cover" />
|
||||
|
||||
<link rel="icon" type="image/png" href="/images/monogramm.png" />
|
||||
|
||||
%svelte.head%
|
||||
</head>
|
||||
<body>
|
||||
<div id="svelte">%svelte.body%</div>
|
||||
|
||||
<script
|
||||
async
|
||||
defer
|
||||
data-website-id="2c23f7af-230c-4ea3-a40a-87aa2939fef3"
|
||||
src="https://spectare.nicco.io/unicorn.js"
|
||||
></script>
|
||||
</body>
|
||||
</html>
|
1
src/global.d.ts
vendored
@ -1 +0,0 @@
|
||||
/// <reference types="@sveltejs/kit" />
|
@ -1,8 +0,0 @@
|
||||
import { initialize, image } from 'svelte-cloudinary'
|
||||
|
||||
initialize({ cloud_name: 'cupcakearmy', secure: true })
|
||||
|
||||
export function cdn(el: HTMLImageElement, src: string) {
|
||||
const cleaned = src.replace('https://api.nicco.io', '/nicco')
|
||||
return image(el, { src: cleaned, bind: { width: true }, lazy: true })
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
export type ArticleHeading = {
|
||||
text: string
|
||||
hash: string
|
||||
href: string
|
||||
level: number
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let headings: ArticleHeading[]
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<b>Outline</b>
|
||||
{#each headings as { text, level, href }}
|
||||
<div style="margin-left: {level - 2}rem;">
|
||||
<span>▶</span>
|
||||
<a {href}>
|
||||
{text}
|
||||
</a>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
@media (min-width: 75rem) {
|
||||
.wrapper {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 40rem;
|
||||
width: calc(100vw - 51rem);
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 0.5em;
|
||||
transform: translateY(-0.8em);
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
a {
|
||||
height: 1.4em;
|
||||
display: inline-block;
|
||||
max-width: calc(100% - 1.5rem);
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
@ -1,29 +0,0 @@
|
||||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<section>
|
||||
<script
|
||||
src="https://giscus.app/client.js"
|
||||
data-repo="cupcakearmy/nicco.io"
|
||||
data-repo-id="MDEwOlJlcG9zaXRvcnkyODIwMjY5ODQ="
|
||||
data-category="Discussion"
|
||||
data-category-id="DIC_kwDOEM9j6M4CSa6S"
|
||||
data-mapping="pathname"
|
||||
data-strict="0"
|
||||
data-reactions-enabled="1"
|
||||
data-emit-metadata="0"
|
||||
data-input-position="top"
|
||||
data-theme="preferred_color_scheme"
|
||||
data-lang="en"
|
||||
data-loading="lazy"
|
||||
crossorigin="anonymous"
|
||||
async
|
||||
>
|
||||
</script>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
section {
|
||||
max-width: 30em;
|
||||
}
|
||||
</style>
|
@ -1,67 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import IconAnalytics from '$lib/icons/IconAnalytics.svelte'
|
||||
import IconCafe from '$lib/icons/IconCafe.svelte'
|
||||
import IconCaretUpCircle from '$lib/icons/IconCaretUpCircle.svelte'
|
||||
import IconChatbubblesOutline from '$lib/icons/IconChatbubblesOutline.svelte'
|
||||
import IconFingerPrintOutline from '$lib/icons/IconFingerPrintOutline.svelte'
|
||||
import IconHeartSharp from '$lib/icons/IconHeartSharp.svelte'
|
||||
import IconLinkOutline from '$lib/icons/IconLinkOutline.svelte'
|
||||
import IconLogoGithub from '$lib/icons/IconLogoGithub.svelte'
|
||||
import IconMailOutline from '$lib/icons/IconMailOutline.svelte'
|
||||
import IconPaypal from '$lib/icons/IconPaypal.svelte'
|
||||
import IconSearchOutline from '$lib/icons/IconSearchOutline.svelte'
|
||||
|
||||
export type IconType =
|
||||
| 'search-outline'
|
||||
| 'link-outline'
|
||||
| 'cafe'
|
||||
| 'logo-github'
|
||||
| 'mail-outline'
|
||||
| 'chatbubbles-outline'
|
||||
| 'logo-github'
|
||||
| 'analytics'
|
||||
| 'finger-print-outline'
|
||||
| 'heart-sharp'
|
||||
| 'caret-up-circle'
|
||||
| 'paypal'
|
||||
|
||||
const mapping: Record<IconType, any> = {
|
||||
'search-outline': IconSearchOutline,
|
||||
'link-outline': IconLinkOutline,
|
||||
cafe: IconCafe,
|
||||
'logo-github': IconLogoGithub,
|
||||
'mail-outline': IconMailOutline,
|
||||
'chatbubbles-outline': IconChatbubblesOutline,
|
||||
analytics: IconAnalytics,
|
||||
'finger-print-outline': IconFingerPrintOutline,
|
||||
'heart-sharp': IconHeartSharp,
|
||||
'caret-up-circle': IconCaretUpCircle,
|
||||
paypal: IconPaypal,
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let icon: IconType
|
||||
|
||||
$: component = mapping[icon]
|
||||
</script>
|
||||
|
||||
{#if component}
|
||||
<span {...$$restProps}>
|
||||
<svelte:component this={component} />
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
contain: strict;
|
||||
box-sizing: content-box;
|
||||
transform: translateY(0.2em);
|
||||
}
|
||||
span > :global(svg) {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
@ -1,61 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { IconType } from './Icon.svelte'
|
||||
export type Link = {
|
||||
href: string
|
||||
name: string
|
||||
icon: IconType
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import Icon from './Icon.svelte'
|
||||
|
||||
export let links: Link[] = []
|
||||
|
||||
function isExternal(link: string) {
|
||||
return /^https?\:\/\//.test(link)
|
||||
}
|
||||
|
||||
$: list = links.map((link) => ({
|
||||
...link,
|
||||
external: isExternal(link.href),
|
||||
}))
|
||||
</script>
|
||||
|
||||
<ul>
|
||||
{#each list as { href, name, icon, external }}
|
||||
<a rel={external ? 'noopener noreferrer' : ''} {href} target={external ? '_blank' : ''}>
|
||||
<li>
|
||||
<Icon class="icon" {icon} />
|
||||
{name}
|
||||
</li>
|
||||
</a>
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
<style>
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
transition: transform 200ms ease;
|
||||
padding: 0.75em 0.5em;
|
||||
cursor: pointer;
|
||||
border-radius: 0.5em;
|
||||
display: block;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
box-shadow: 0px 6px 6px -3px #00000012;
|
||||
transform: translateY(0.25em) translateX(0.15em) scale(1.05);
|
||||
}
|
||||
|
||||
a :global(.icon) {
|
||||
transform: translateY(0.3em);
|
||||
font-size: 1.5em;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
</style>
|
@ -1,25 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cdn } from '$lib/actions/cloudinary'
|
||||
|
||||
export let src: string
|
||||
export let alt: string
|
||||
</script>
|
||||
|
||||
<img use:cdn={src} {alt} />
|
||||
|
||||
<style>
|
||||
img {
|
||||
width: calc(100% - 0.25em);
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
border: 0.125em solid var(--clr-primary);
|
||||
transition: var(--animation);
|
||||
transform: scale(1);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
transform: scale(1.1);
|
||||
margin: 1em 0;
|
||||
}
|
||||
</style>
|
@ -1,120 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores'
|
||||
|
||||
import Icon from './Icon.svelte'
|
||||
|
||||
const routes = [
|
||||
{ name: 'About', href: '/about' },
|
||||
// { name: 'Works', href: '/works' },
|
||||
{ name: 'Projects', href: '/projects' },
|
||||
{ name: 'Blog', href: '/blog' },
|
||||
{ name: 'Contact', href: '/contact' },
|
||||
]
|
||||
</script>
|
||||
|
||||
<nav>
|
||||
<a href="/">
|
||||
<h1 class:active={$page.url.pathname === '/'}>NB</h1>
|
||||
</a>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/search">
|
||||
<Icon icon="search-outline" />
|
||||
</a>
|
||||
</li>
|
||||
{#each routes as { name, href }}
|
||||
<li>
|
||||
<a {href}>
|
||||
<span>{name}</span>
|
||||
<div class:active={$page.url.pathname.startsWith(href)} />
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<style>
|
||||
nav :global(*) {
|
||||
box-sizing: initial;
|
||||
}
|
||||
|
||||
nav {
|
||||
padding-top: env(safe-area-inset-top);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
width: 3em;
|
||||
height: 100%;
|
||||
background-color: var(--clr-primary);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-right: 0.1em solid var(--clr-secondary);
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
max-height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
a {
|
||||
writing-mode: vertical-rl;
|
||||
padding: 1em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
li a {
|
||||
line-height: 1em;
|
||||
width: 1em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
li a span {
|
||||
z-index: 5;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
li a div {
|
||||
z-index: 4;
|
||||
width: 0.125em;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 1.12em;
|
||||
position: absolute;
|
||||
transition: all 500ms ease;
|
||||
}
|
||||
li a div.active {
|
||||
background-color: var(--clr-secondary);
|
||||
}
|
||||
li:hover a div:not(.active) {
|
||||
background-color: var(--clr-light);
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
writing-mode: horizontal-tb;
|
||||
letter-spacing: -0.15em;
|
||||
width: 1.15em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h1.active {
|
||||
box-shadow: 0 0.1em var(--clr-secondary);
|
||||
}
|
||||
|
||||
@media (max-width: 30em) {
|
||||
nav {
|
||||
width: 2.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
li a div {
|
||||
transform: translateX(-0.5em);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,19 +0,0 @@
|
||||
<script lang="ts">
|
||||
import SpacedLetters from './SpacedLetters.svelte'
|
||||
|
||||
export let title = ''
|
||||
export let readable = false
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<h1>
|
||||
<SpacedLetters letters={title} {readable} />
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
margin-top: calc(28vh - 3em);
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
</style>
|
@ -1,34 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { GQLBasePostFragment } from '$lib/gql/gen'
|
||||
import { readingTimeInMinutes } from '$lib/utils'
|
||||
import dj from 'dayjs'
|
||||
|
||||
export let post: GQLBasePostFragment
|
||||
export let full = false
|
||||
|
||||
function format(date: string) {
|
||||
return dj(date).format('MMM D, YYYY')
|
||||
}
|
||||
|
||||
$: created = format(post.date)
|
||||
$: modified = format(post.modified)
|
||||
</script>
|
||||
|
||||
<div class="attributes">
|
||||
<div>
|
||||
{created}
|
||||
{#if full && created !== modified}<br /> <small>Last update: {modified}</small>{/if}
|
||||
</div>
|
||||
{#if post.content}
|
||||
<div>~ {readingTimeInMinutes(post.content)} min</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.attributes {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-weight: 400;
|
||||
margin-top: -0.125em;
|
||||
}
|
||||
</style>
|
@ -1,61 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { GQLBasePostFragment } from '$lib/gql/gen'
|
||||
|
||||
import ImageFrame from '../components/ImageFrame.svelte'
|
||||
import PostAttributes from '../components/PostAttributes.svelte'
|
||||
import Tags from './Tags.svelte'
|
||||
|
||||
export let post: GQLBasePostFragment
|
||||
</script>
|
||||
|
||||
<a href={`/blog/${post.slug}`} class:without={!post.post.featured}>
|
||||
{#if post.post.featured}
|
||||
<ImageFrame src={post.post.featured.sourceUrl} alt={post.post.featured.altText} />
|
||||
{/if}
|
||||
<PostAttributes {post} />
|
||||
<h2>
|
||||
{@html post.title}
|
||||
</h2>
|
||||
<Tags tags={post.tags.nodes} />
|
||||
</a>
|
||||
|
||||
<style>
|
||||
a {
|
||||
display: block;
|
||||
margin-bottom: 5em;
|
||||
}
|
||||
a > :global(img) {
|
||||
height: 12em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 0.25em;
|
||||
position: relative;
|
||||
top: 0;
|
||||
transition: var(--animation);
|
||||
background-color: var(--clr-light);
|
||||
}
|
||||
a :global(img) {
|
||||
transition: var(--animation);
|
||||
position: relative;
|
||||
top: 0;
|
||||
}
|
||||
a:hover :global(img) {
|
||||
top: 2.5rem;
|
||||
}
|
||||
|
||||
a > :global(div) {
|
||||
opacity: 1;
|
||||
transition: var(--animation);
|
||||
}
|
||||
a:hover > :global(div) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
a.without {
|
||||
border: 2px solid var(--clr-primary);
|
||||
padding: 5%;
|
||||
width: calc(100% + 10%);
|
||||
transform: translateX(-5%);
|
||||
}
|
||||
</style>
|
@ -1,62 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { spring } from 'svelte/motion'
|
||||
import { scroll } from '$lib/stores'
|
||||
|
||||
let el: SVGElement
|
||||
|
||||
const springed = spring(
|
||||
{ scroll: 0 },
|
||||
{
|
||||
stiffness: 0.05,
|
||||
damping: 0.7,
|
||||
}
|
||||
)
|
||||
|
||||
function updateState(value: number) {
|
||||
const max = 359.99999
|
||||
const R = 50
|
||||
let alpha = (360 / 1) * value
|
||||
alpha = Math.min(alpha, max)
|
||||
const a = ((90 - alpha) * Math.PI) / 180
|
||||
const x = R + R * Math.cos(a) * 2
|
||||
const y = R - R * Math.sin(a) * 2
|
||||
const center = alpha > 180 ? 1 : 0
|
||||
const path = `M${R},${-50} A${R * 2},${R * 2},0,${center},1,${x},${y} L${R},${R} L${R},${-R}`
|
||||
if (el) el.setAttribute('d', path)
|
||||
}
|
||||
|
||||
$: springed.set({ scroll: $scroll })
|
||||
|
||||
$: updateState($springed.scroll)
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" version="1.1">
|
||||
<path bind:this={el} fill="var(--clr-secondary)" d="" />
|
||||
</svg>
|
||||
<span>{$scroll.toFixed(2)}</span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
position: absolute;
|
||||
bottom: 1em;
|
||||
right: 1em;
|
||||
pointer-events: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
font-size: 0.5em;
|
||||
background-color: var(--clr-primary);
|
||||
height: 1.5em;
|
||||
}
|
||||
svg {
|
||||
border: 0.125em solid var(--clr-primary);
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
position: relative;
|
||||
top: 0.45em;
|
||||
}
|
||||
</style>
|
@ -1,69 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { GQLBaseProjectFragment } from '$lib/gql/gen'
|
||||
import dayjs from 'dayjs'
|
||||
import Icon from './Icon.svelte'
|
||||
|
||||
export let project: GQLBaseProjectFragment
|
||||
</script>
|
||||
|
||||
<section>
|
||||
<a href={project.project.link} target="_blank" rel="noopener">
|
||||
<h2>{project.title}</h2>
|
||||
</a>
|
||||
<div class="subtitle">
|
||||
<b>{project.project.description}</b>
|
||||
<b class="date">{dayjs(project.project.date, 'X').format('MMM YY')}</b>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
{@html project.content}
|
||||
</p>
|
||||
|
||||
<div class="link">
|
||||
<Icon icon="link-outline" />
|
||||
<a rel="noopener noreferrer" target="_blank" href={project.project.link}
|
||||
>{project.project.link.replace(/https?:\/\//, '')}</a
|
||||
>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
h2 {
|
||||
font-size: 2em;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
div.subtitle {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.date {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.link {
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.link a {
|
||||
margin-left: 0.5rem;
|
||||
display: block;
|
||||
}
|
||||
|
||||
section {
|
||||
margin-bottom: 6em;
|
||||
}
|
||||
|
||||
a {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
@media (max-width: 30em) {
|
||||
div.subtitle {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,59 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
export type SearchResultItem = {
|
||||
ref: string
|
||||
score: number
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let result: SearchResultItem
|
||||
|
||||
const [type, slug] = result.ref.split('/')
|
||||
let href = '/'
|
||||
|
||||
$: {
|
||||
switch (type) {
|
||||
case 'works':
|
||||
href = `${type}/${slug}`
|
||||
break
|
||||
case 'projects':
|
||||
href = `${type}`
|
||||
break
|
||||
case 'posts':
|
||||
href = `/blog/${slug}`
|
||||
break
|
||||
case 'pages':
|
||||
href = `/${slug}`
|
||||
break
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<li>
|
||||
<a {href}>
|
||||
<h3>{slug.replace(/-/g, ' ')}</h3>
|
||||
<span>{type}</span>
|
||||
<code>Score: {result.score.toFixed(1)}</code>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<style>
|
||||
h3 {
|
||||
margin: 0;
|
||||
margin-top: 2.5em;
|
||||
margin-bottom: 0.2em;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
padding: 0.1em 0.15em;
|
||||
background-color: var(--clr-primary);
|
||||
margin: 0;
|
||||
line-height: 90%;
|
||||
height: 1.25em;
|
||||
}
|
||||
|
||||
code {
|
||||
margin-left: 1em;
|
||||
}
|
||||
</style>
|
@ -1,24 +0,0 @@
|
||||
<script lang="ts">
|
||||
import PageTitle from './PageTitle.svelte'
|
||||
|
||||
export let title = ''
|
||||
export let expanded = true
|
||||
export let readable = false
|
||||
</script>
|
||||
|
||||
<PageTitle {title} {readable} />
|
||||
|
||||
<section class:expanded>
|
||||
<slot />
|
||||
</section>
|
||||
|
||||
<style>
|
||||
section {
|
||||
max-width: 30em;
|
||||
margin-bottom: 4em;
|
||||
}
|
||||
|
||||
section.expanded {
|
||||
margin-top: 5em;
|
||||
}
|
||||
</style>
|
@ -1,36 +0,0 @@
|
||||
<script lang="ts">
|
||||
export let letters: string = ''
|
||||
export let even = false
|
||||
export let readable = false
|
||||
</script>
|
||||
|
||||
<div class:even class:readable>
|
||||
{#if even}
|
||||
{#each letters as letter}<span>{letter}</span>{/each}
|
||||
{:else}{letters}{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
span {
|
||||
width: 1em;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
div {
|
||||
font-size: min(8vw, 2.5em);
|
||||
text-transform: uppercase;
|
||||
user-select: none;
|
||||
letter-spacing: 0.35em;
|
||||
}
|
||||
|
||||
div.even {
|
||||
font-size: 8vw;
|
||||
}
|
||||
|
||||
div.readable {
|
||||
letter-spacing: initial;
|
||||
text-transform: initial;
|
||||
font-size: 2.25rem;
|
||||
}
|
||||
</style>
|
@ -1,28 +0,0 @@
|
||||
<script lang="ts">
|
||||
export let name: string = ''
|
||||
export let href: string = ''
|
||||
export let count: number = 0
|
||||
</script>
|
||||
|
||||
<a {href}>
|
||||
<div>
|
||||
{name} <i>{count}</i>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
div {
|
||||
display: inline-block;
|
||||
margin: 0.25rem;
|
||||
padding: 0 0.5rem;
|
||||
background-color: var(--clr-primary);
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
i {
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: 0.85em;
|
||||
font-weight: bold;
|
||||
color: var(--clr-secondary);
|
||||
}
|
||||
</style>
|
@ -1,34 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { GQLBaseTagFragment } from '$lib/gql/gen'
|
||||
import Tag from './Tag.svelte'
|
||||
|
||||
export let tags: readonly GQLBaseTagFragment[]
|
||||
export let rows: number = 1
|
||||
|
||||
$: height = rows * 2
|
||||
</script>
|
||||
|
||||
<div style="height: {height}em;">
|
||||
{#each tags as { slug, name, count }}
|
||||
<Tag {name} {count} href="/blog/tags/{slug}" />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: auto;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin: 0 -0.25rem;
|
||||
}
|
||||
|
||||
div::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
div {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
</style>
|
@ -1,160 +0,0 @@
|
||||
<script lang="ts">
|
||||
import hljs from 'highlight.js/lib/core'
|
||||
import bash from 'highlight.js/lib/languages/bash'
|
||||
import css from 'highlight.js/lib/languages/css'
|
||||
import docker from 'highlight.js/lib/languages/dockerfile'
|
||||
import javascript from 'highlight.js/lib/languages/javascript'
|
||||
import json from 'highlight.js/lib/languages/json'
|
||||
import python from 'highlight.js/lib/languages/python'
|
||||
import rust from 'highlight.js/lib/languages/rust'
|
||||
import typescript from 'highlight.js/lib/languages/typescript'
|
||||
import yaml from 'highlight.js/lib/languages/yaml'
|
||||
import { onMount } from 'svelte'
|
||||
import ArticleOverview, { ArticleHeading } from './ArticleOverview.svelte'
|
||||
|
||||
hljs.registerLanguage('javascript', javascript)
|
||||
hljs.registerLanguage('python', python)
|
||||
hljs.registerLanguage('yaml', yaml)
|
||||
hljs.registerLanguage('json', json)
|
||||
hljs.registerLanguage('bash', bash)
|
||||
hljs.registerLanguage('docker', docker)
|
||||
hljs.registerLanguage('rust', rust)
|
||||
hljs.registerLanguage('css', css)
|
||||
hljs.registerLanguage('typescript', typescript)
|
||||
|
||||
export let legend = false
|
||||
export let content: string
|
||||
let headings: ArticleHeading[] | null = null
|
||||
|
||||
function encodeTextToUrl(text: string): string {
|
||||
return text
|
||||
.toLowerCase()
|
||||
.replace(/[^A-Za-z ]/g, '')
|
||||
.replace(/ +/g, '-')
|
||||
}
|
||||
|
||||
async function update(isDark: boolean) {
|
||||
isDark ? await import('highlight.js/styles/github-dark.css') : await import('highlight.js/styles/github.css')
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
hljs.highlightAll()
|
||||
|
||||
// Add anchor links to headers
|
||||
const selector = [1, 2, 3, 4, 5, 6].map((i) => `div.adapter h${i}`).join(', ')
|
||||
const elements = window.document.querySelectorAll(selector)
|
||||
headings = Array.from(elements).map((element) => {
|
||||
const text = element.textContent || ''
|
||||
const hash = encodeTextToUrl(text)
|
||||
const href = `${window.location.pathname}#${hash}`
|
||||
const level = parseInt(element.tagName.slice(1))
|
||||
|
||||
element.innerHTML = `<a class="target-link" id="${hash}" href="${href}">${text}</a>`
|
||||
return { text, hash, level, href }
|
||||
})
|
||||
|
||||
const match = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
match.addEventListener('change', (e) => update(e.matches))
|
||||
update(match.matches)
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="adapter">
|
||||
{#if legend && headings}
|
||||
<ArticleOverview {headings} />
|
||||
{/if}
|
||||
{@html content}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.adapter {
|
||||
position: relative;
|
||||
}
|
||||
div :global(.alignfull) {
|
||||
width: calc(100vw - 6em);
|
||||
margin-left: -2em;
|
||||
}
|
||||
div :global(.alignwide) {
|
||||
width: calc(100% + 4em);
|
||||
margin-left: -2em;
|
||||
}
|
||||
@media (max-width: 30em) {
|
||||
div :global(.alignfull) {
|
||||
width: calc(100vw - 4em);
|
||||
margin-left: -1em;
|
||||
}
|
||||
div :global(.alignwide) {
|
||||
width: calc(100% + 2em);
|
||||
margin-left: -1em;
|
||||
}
|
||||
}
|
||||
|
||||
div :global(figure video),
|
||||
div :global(figure img) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div :global(figure) {
|
||||
margin: 2em 0;
|
||||
}
|
||||
div :global(figure figcaption) {
|
||||
opacity: 0.75;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div :global(a) {
|
||||
border-bottom: 0.125em solid var(--clr-primary);
|
||||
}
|
||||
|
||||
div :global(pre) {
|
||||
padding: 1em;
|
||||
background: var(--clr-transparent-0);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div :global(code) {
|
||||
background: var(--clr-transparent-0);
|
||||
padding: 0.25em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
div :global(pre code) {
|
||||
background: initial;
|
||||
padding: initial;
|
||||
-moz-tab-size: 2;
|
||||
tab-size: 2;
|
||||
}
|
||||
|
||||
div :global(h1),
|
||||
div :global(h2),
|
||||
div :global(h3),
|
||||
div :global(h4),
|
||||
div :global(h5),
|
||||
div :global(h6) {
|
||||
margin: 0;
|
||||
margin-top: 3em;
|
||||
border-left: 0.2rem solid var(--clr-primary);
|
||||
padding-left: 0.5rem;
|
||||
margin-left: -0.7rem;
|
||||
}
|
||||
|
||||
div :global(.target-link) {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
div :global(p.has-background) {
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
div :global(table) {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
border: 0.1rem solid var(--clr-primary);
|
||||
}
|
||||
|
||||
div :global(table th),
|
||||
div :global(table td) {
|
||||
padding: 0.25rem;
|
||||
border: 0.1rem solid var(--clr-primary);
|
||||
}
|
||||
</style>
|
@ -1,65 +0,0 @@
|
||||
<script lang="ts">
|
||||
import Icon from '$lib/components/Icon.svelte'
|
||||
import ImageFrame from '$lib/components/ImageFrame.svelte'
|
||||
import type { GQLBaseWorkFragment } from '$lib/gql/gen'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
export let work: GQLBaseWorkFragment
|
||||
</script>
|
||||
|
||||
<section>
|
||||
<a href="/works/{work.slug}">
|
||||
<div class="horizontal">
|
||||
<div class="title regular">{work.title}</div>
|
||||
<div>
|
||||
<a href={work.work.link} target="_blank" rel="noopener">
|
||||
<Icon icon="link-outline" />
|
||||
<span>{work.work.link.replace(/https?:\/\//, '')}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ImageFrame src={work.work.image.sourceUrl} alt={work.work.image.altText} />
|
||||
</a>
|
||||
<div class="horizontal regular">
|
||||
<div>{work.work.role}</div>
|
||||
<div>{dayjs(work.work.date, 'X').format('MMM YY')}</div>
|
||||
</div>
|
||||
{#if work.content}
|
||||
<p>
|
||||
{@html work.content}
|
||||
</p>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.title {
|
||||
font-size: 2em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.horizontal {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.regular {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
section {
|
||||
margin-bottom: 6em;
|
||||
}
|
||||
|
||||
a {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
@media (max-width: 30em) {
|
||||
.horizontal {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
</style>
|
9512
src/lib/gql/gen.ts
@ -1,5 +0,0 @@
|
||||
import { GraphQLClient } from 'graphql-request'
|
||||
import { getSdk } from './gen'
|
||||
|
||||
const client = new GraphQLClient('https://api.nicco.io/graphql')
|
||||
export const SDK = getSdk(client)
|
@ -1,173 +0,0 @@
|
||||
fragment BaseMediaItem on MediaItem {
|
||||
srcSet
|
||||
altText
|
||||
sourceUrl
|
||||
}
|
||||
|
||||
query MediaItemsMany {
|
||||
mediaItems(first: 100, where: { status: PUBLISH }) {
|
||||
nodes {
|
||||
...BaseMediaItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query MediaItemsOne($slug: ID!) {
|
||||
mediaItem(id: $slug, idType: URI) {
|
||||
...BaseMediaItem
|
||||
}
|
||||
}
|
||||
|
||||
fragment BasePage on Page {
|
||||
id
|
||||
slug
|
||||
title
|
||||
content
|
||||
status
|
||||
}
|
||||
|
||||
query PagesMany {
|
||||
pages(first: 100, where: { status: PUBLISH }) {
|
||||
nodes {
|
||||
...BasePage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query PagesOne($slug: ID!) {
|
||||
page(id: $slug, idType: URI) {
|
||||
...BasePage
|
||||
}
|
||||
}
|
||||
|
||||
fragment BaseWork on Work {
|
||||
id
|
||||
slug
|
||||
title
|
||||
content
|
||||
status
|
||||
work {
|
||||
date
|
||||
image {
|
||||
...BaseMediaItem
|
||||
}
|
||||
link
|
||||
role
|
||||
}
|
||||
}
|
||||
|
||||
query WorksMany {
|
||||
works(first: 100, where: { status: PUBLISH }) {
|
||||
nodes {
|
||||
...BaseWork
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query WorksOne($slug: ID!) {
|
||||
work(id: $slug, idType: URI) {
|
||||
...BaseWork
|
||||
}
|
||||
}
|
||||
|
||||
fragment BaseProject on Project {
|
||||
id
|
||||
slug
|
||||
title
|
||||
content
|
||||
status
|
||||
project {
|
||||
date
|
||||
link
|
||||
description
|
||||
}
|
||||
}
|
||||
|
||||
query ProjectsMany {
|
||||
projects(first: 100, where: { status: PUBLISH }) {
|
||||
nodes {
|
||||
...BaseProject
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query ProjectsOne($slug: ID!) {
|
||||
project(id: $slug, idType: URI) {
|
||||
...BaseProject
|
||||
}
|
||||
}
|
||||
|
||||
fragment BasePost on Post {
|
||||
id
|
||||
slug
|
||||
title
|
||||
content
|
||||
status
|
||||
date
|
||||
modified
|
||||
tags {
|
||||
nodes {
|
||||
...BaseTag
|
||||
}
|
||||
}
|
||||
post {
|
||||
featured {
|
||||
...BaseMediaItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query PostsMany {
|
||||
posts(first: 100, where: { status: PUBLISH }) {
|
||||
nodes {
|
||||
...BasePost
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query PostsOne($slug: ID!) {
|
||||
post(id: $slug, idType: URI) {
|
||||
...BasePost
|
||||
}
|
||||
}
|
||||
|
||||
query PostsManyByTag($tag: String!) {
|
||||
posts(first: 100, where: { status: PUBLISH, tag: $tag }) {
|
||||
nodes {
|
||||
...BasePost
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query Search {
|
||||
posts(first: 100) {
|
||||
nodes {
|
||||
...BasePost
|
||||
}
|
||||
}
|
||||
projects(first: 100) {
|
||||
nodes {
|
||||
...BaseProject
|
||||
}
|
||||
}
|
||||
works(first: 100) {
|
||||
nodes {
|
||||
...BaseWork
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment BaseTag on Tag {
|
||||
id
|
||||
slug
|
||||
name
|
||||
count
|
||||
}
|
||||
|
||||
query TagsMany {
|
||||
tags(first: 100) {
|
||||
nodes {
|
||||
...BaseTag
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"
|
||||
><title>Analytics</title><path
|
||||
d="M456 128a40 40 0 00-37.23 54.6l-84.17 84.17a39.86 39.86 0 00-29.2 0l-60.17-60.17a40 40 0 10-74.46 0L70.6 306.77a40 40 0 1022.63 22.63L193.4 229.23a39.86 39.86 0 0029.2 0l60.17 60.17a40 40 0 1074.46 0l84.17-84.17A40 40 0 10456 128z"
|
||||
/></svg
|
||||
>
|
Before Width: | Height: | Size: 362 B |
@ -1,5 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"
|
||||
><title>Cafe</title><path
|
||||
d="M432 64H96a16 16 0 00-16 16v192a96.11 96.11 0 0096 96h112a96.11 96.11 0 0096-96v-80h18a62.07 62.07 0 0062-62V96a32 32 0 00-32-32zm0 66a30 30 0 01-30 30h-18V96h48zM400 400H64a16 16 0 000 32h336a16 16 0 000-32z"
|
||||
/></svg
|
||||
>
|
Before Width: | Height: | Size: 335 B |
@ -1,5 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"
|
||||
><title>Caret Up Circle</title><path
|
||||
d="M256 48C141.13 48 48 141.13 48 256s93.13 208 208 208 208-93.13 208-208S370.87 48 256 48zm74.14 252H181.86a16 16 0 01-12.29-26.23l74.13-89.09a16 16 0 0124.6 0l74.13 89.09A16 16 0 01330.14 300z"
|
||||
/></svg
|
||||
>
|
Before Width: | Height: | Size: 329 B |
@ -1,19 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
|
||||
<title>Chatbubbles</title>
|
||||
<path
|
||||
d="M431 320.6c-1-3.6 1.2-8.6 3.3-12.2a33.68 33.68 0 012.1-3.1A162 162 0 00464 215c.3-92.2-77.5-167-173.7-167-83.9 0-153.9 57.1-170.3 132.9a160.7 160.7 0 00-3.7 34.2c0 92.3 74.8 169.1 171 169.1 15.3 0 35.9-4.6 47.2-7.7s22.5-7.2 25.4-8.3a26.44 26.44 0 019.3-1.7 26 26 0 0110.1 2l56.7 20.1a13.52 13.52 0 003.9 1 8 8 0 008-8 12.85 12.85 0 00-.5-2.7z"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
stroke-width="32"
|
||||
/>
|
||||
<path
|
||||
d="M66.46 232a146.23 146.23 0 006.39 152.67c2.31 3.49 3.61 6.19 3.21 8s-11.93 61.87-11.93 61.87a8 8 0 002.71 7.68A8.17 8.17 0 0072 464a7.26 7.26 0 002.91-.6l56.21-22a15.7 15.7 0 0112 .2c18.94 7.38 39.88 12 60.83 12A159.21 159.21 0 00284 432.11"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
stroke-width="32"
|
||||
/>
|
||||
</svg>
|
Before Width: | Height: | Size: 977 B |
@ -1,7 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
|
||||
<title>Finger Print</title>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M390.42 75.28a10.45 10.45 0 01-5.32-1.44C340.72 50.08 302.35 40 256.35 40c-45.77 0-89.23 11.28-128.76 33.84C122 77 115.11 74.8 111.87 69a12.4 12.4 0 014.63-16.32A281.81 281.81 0 01256.35 16c49.23 0 92.23 11.28 139.39 36.48a12 12 0 014.85 16.08 11.3 11.3 0 01-10.17 6.72zm-330.79 126a11.73 11.73 0 01-6.7-2.16 12.26 12.26 0 01-2.78-16.8c22.89-33.6 52-60 86.69-78.48 72.58-38.84 165.51-39.12 238.32-.24 34.68 18.48 63.8 44.64 86.69 78a12.29 12.29 0 01-2.78 16.8 11.26 11.26 0 01-16.18-2.88c-20.8-30.24-47.15-54-78.36-70.56-66.34-35.28-151.18-35.28-217.29.24-31.44 16.8-57.79 40.8-78.59 71a10 10 0 01-9.02 5.08zM204.1 491a10.66 10.66 0 01-8.09-3.6C175.9 466.48 165 453 149.55 424c-16-29.52-24.27-65.52-24.27-104.16 0-71.28 58.71-129.36 130.84-129.36S387 248.56 387 319.84a11.56 11.56 0 11-23.11 0c0-58.08-48.32-105.36-107.72-105.36S148.4 261.76 148.4 319.84c0 34.56 7.39 66.48 21.49 92.4 14.8 27.6 25 39.36 42.77 58.08a12.67 12.67 0 010 17 12.44 12.44 0 01-8.56 3.68zm165.75-44.4c-27.51 0-51.78-7.2-71.66-21.36a129.1 129.1 0 01-55-105.36 11.57 11.57 0 1123.12 0 104.28 104.28 0 0044.84 85.44c16.41 11.52 35.6 17 58.72 17a147.41 147.41 0 0024-2.4c6.24-1.2 12.25 3.12 13.4 9.84a11.92 11.92 0 01-9.47 13.92 152.28 152.28 0 01-27.95 2.88zM323.38 496a13 13 0 01-3-.48c-36.76-10.56-60.8-24.72-86-50.4-32.37-33.36-50.16-77.76-50.16-125.28 0-38.88 31.9-70.56 71.19-70.56s71.2 31.68 71.2 70.56c0 25.68 21.5 46.56 48.08 46.56s48.08-20.88 48.08-46.56c0-90.48-75.13-163.92-167.59-163.92-65.65 0-125.75 37.92-152.79 96.72-9 19.44-13.64 42.24-13.64 67.2 0 18.72 1.61 48.24 15.48 86.64 2.32 6.24-.69 13.2-6.7 15.36a11.34 11.34 0 01-14.79-7 276.39 276.39 0 01-16.88-95c0-28.8 5.32-55 15.72-77.76 30.75-67 98.94-110.4 173.6-110.4 105.18 0 190.71 84.24 190.71 187.92 0 38.88-31.9 70.56-71.2 70.56s-71.2-31.68-71.2-70.56c.01-25.68-21.49-46.6-48.07-46.6s-48.08 20.88-48.08 46.56c0 41 15.26 79.44 43.23 108.24 22 22.56 43 35 75.59 44.4 6.24 1.68 9.71 8.4 8.09 14.64a11.39 11.39 0 01-10.87 9.16z"
|
||||
/>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.1 KiB |
@ -1,7 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
|
||||
<title>Heart</title>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M256 448l-9-6c-42.78-28.57-96.91-60.86-137-108.32-42.25-50-62.52-101.35-62-157C48.63 114.54 98.46 64 159.08 64c48.11 0 80.1 28 96.92 48.21C272.82 92 304.81 64 352.92 64c60.62 0 110.45 50.54 111.08 112.65.56 55.68-19.71 107-62 157-40.09 47.49-94.22 79.78-137 108.35z"
|
||||
/>
|
||||
</svg>
|
Before Width: | Height: | Size: 420 B |
@ -1,11 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
|
||||
<title>Link</title>
|
||||
<path
|
||||
d="M208 352h-64a96 96 0 010-192h64M304 160h64a96 96 0 010 192h-64M163.29 256h187.42"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="36"
|
||||
/>
|
||||
</svg>
|
Before Width: | Height: | Size: 329 B |
@ -1,7 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
|
||||
<title>Logo Github</title>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M256 32C132.3 32 32 134.9 32 261.7c0 101.5 64.2 187.5 153.2 217.9a17.56 17.56 0 003.8.4c8.3 0 11.5-6.1 11.5-11.4 0-5.5-.2-19.9-.3-39.1a102.4 102.4 0 01-22.6 2.7c-43.1 0-52.9-33.5-52.9-33.5-10.2-26.5-24.9-33.6-24.9-33.6-19.5-13.7-.1-14.1 1.4-14.1h.1c22.5 2 34.3 23.8 34.3 23.8 11.2 19.6 26.2 25.1 39.6 25.1a63 63 0 0025.6-6c2-14.8 7.8-24.9 14.2-30.7-49.7-5.8-102-25.5-102-113.5 0-25.1 8.7-45.6 23-61.6-2.3-5.8-10-29.2 2.2-60.8a18.64 18.64 0 015-.5c8.1 0 26.4 3.1 56.6 24.1a208.21 208.21 0 01112.2 0c30.2-21 48.5-24.1 56.6-24.1a18.64 18.64 0 015 .5c12.2 31.6 4.5 55 2.2 60.8 14.3 16.1 23 36.6 23 61.6 0 88.2-52.4 107.6-102.3 113.3 8 7.1 15.2 21.1 15.2 42.5 0 30.7-.3 55.5-.3 63 0 5.4 3.1 11.5 11.4 11.5a19.35 19.35 0 004-.4C415.9 449.2 480 363.1 480 261.7 480 134.9 379.7 32 256 32z"
|
||||
/>
|
||||
</svg>
|
Before Width: | Height: | Size: 941 B |
@ -1,24 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
|
||||
<title>Mail</title>
|
||||
<rect
|
||||
x="48"
|
||||
y="96"
|
||||
width="416"
|
||||
height="320"
|
||||
rx="40"
|
||||
ry="40"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="32"
|
||||
/>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="32"
|
||||
d="M112 160l144 112 144-112"
|
||||
/>
|
||||
</svg>
|
Before Width: | Height: | Size: 484 B |
@ -1,7 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"
|
||||
><title>Logo Paypal</title><path
|
||||
d="M424.81 148.79c-.43 2.76-.93 5.58-1.49 8.48-19.17 98-84.76 131.8-168.54 131.8h-42.65a20.67 20.67 0 00-20.47 17.46l-21.84 137.84-6.18 39.07a10.86 10.86 0 009.07 12.42 10.72 10.72 0 001.7.13h75.65a18.18 18.18 0 0018-15.27l.74-3.83 14.24-90 .91-4.94a18.16 18.16 0 0118-15.3h11.31c73.3 0 130.67-29.62 147.44-115.32 7-35.8 3.38-65.69-15.16-86.72a72.27 72.27 0 00-20.73-15.82z"
|
||||
/><path
|
||||
d="M385.52 51.09C363.84 26.52 324.71 16 274.63 16H129.25a20.75 20.75 0 00-20.54 17.48l-60.55 382a12.43 12.43 0 0010.39 14.22 12.58 12.58 0 001.94.15h89.76l22.54-142.29-.7 4.46a20.67 20.67 0 0120.47-17.46h42.65c83.77 0 149.36-33.86 168.54-131.8.57-2.9 1.05-5.72 1.49-8.48 5.7-36.22-.05-60.87-19.72-83.19z"
|
||||
/></svg
|
||||
>
|
Before Width: | Height: | Size: 823 B |
@ -1,18 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512">
|
||||
<title>Search</title>
|
||||
<path
|
||||
d="M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-miterlimit="10"
|
||||
stroke-width="32"
|
||||
/>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-miterlimit="10"
|
||||
stroke-width="32"
|
||||
d="M338.29 338.29L448 448"
|
||||
/>
|
||||
</svg>
|
Before Width: | Height: | Size: 454 B |
@ -1,3 +0,0 @@
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
export const scroll = writable(0)
|
@ -1,24 +0,0 @@
|
||||
<svg
|
||||
{...$$restProps}
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 1500 650"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:space="preserve"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
id="Niccolo-Outline"
|
||||
d="M20.271,459.439c-1.17,-3.419 3.175,-9.667 10.262,-9.656c47.47,-41.735 98.965,-93.306 153.09,-151.305l141.37,-151.839l46.857,-57.73c4.246,-5.313 12.634,-0.233 7.597,7.121c-24.452,33.091 -49.57,66.559 -72.909,99.021c-4.255,7.012 -28.702,40.073 -54.403,74.754c-31.401,44.917 -56.137,87.345 -72.031,126.472c-5.226,12.173 -10.453,24.346 -15.679,36.52c-18.953,41.143 -39.007,81.367 -59.994,120.815c42.202,-42.593 70.867,-72.932 102.804,-107.146c28.316,-30.334 61.042,-62.614 73.907,-73.637c10.762,-9.09 17.153,-13.711 20.76,-16.467c5.612,-4.288 13.108,-2.443 10.155,8.052c-3.103,9.01 -7.394,18.956 -13.682,30.475c-4.402,8.289 -8.249,16.961 -11.459,24.83c-4.646,11.389 -7.855,20.391 -7.923,25.916c14.003,-8.284 31.688,-21.532 51.119,-36.542c13.038,-8.455 26.163,-16.951 39.441,-25.517c12.498,-8.738 23.006,-15.921 36.217,-21.442c7.292,-2.43 13.246,1.576 10.104,8.202l-8.089,13.678c-6.343,7.45 -13.359,34.46 -11.387,34.695c3.534,0.777 7.149,0.17 10.794,-0.933c23.784,-10.493 45.573,-21.385 69.025,-34.661c6.369,-3.605 11.37,1.451 6.254,5.825c-16.222,12.959 -28.925,27.403 -34.865,44.701c8.792,0.261 20.532,-8.963 33.808,-16.713c8.014,-4.576 16.028,-9.154 20.885,-8.785c11.911,-10.996 25.507,-24.107 43.452,-42.675c13.197,-30.813 29.84,-58.163 48.859,-83.127c17.47,-25.723 37.654,-48.609 58.99,-70.29c22.847,-26.175 44.455,-44.727 71.493,-52.443c7.445,-2.124 16.358,3.673 17.086,14.754c0.351,4.574 0.445,8.416 0.463,12.046c-4.465,23.076 -37.053,52.117 -68.637,80.944c-40.543,34.913 -80.295,70.231 -118.776,106.201c-8.172,17.541 -14.392,35.163 -18.91,52.857c-0.517,3.438 -0.96,6.889 -0.507,10.481c1.697,1.017 5.468,0.45 9.67,-0.445c11.461,-4.152 26.727,-13.293 43.617,-24.563c4.248,-15.98 9.857,-31.063 16.469,-45.483c16.602,-29.693 44.252,-62.684 61.948,-68.886c11.646,-4.081 20.539,3.744 18.176,16.41c-5.323,22.443 -36.961,61.86 -79.496,102.518c3.018,1.49 5.795,0.679 9.36,-1.235c2.52,-0.936 3.644,0.943 2.567,2.551c-1.569,2.342 -2.793,4.242 -3.853,6.808c-4.713,11.41 -19.341,14.129 -25.345,4.372c-15.438,10.943 -30.287,20.032 -42.639,21.265c-13.619,2.275 -19.672,-1.519 -22.759,-7.695c-4.459,-8.734 -0.458,-24.537 8.084,-44.134c-10.253,10.639 -21.336,20.469 -33.584,29.164c-4.302,3.574 -8.532,3.089 -11.05,-1.904c-16.541,11.137 -30.907,20.415 -39.674,19.79c-14.821,-1.058 -15.256,-12.14 0.849,-34.251c-20.141,11.132 -35.112,21.67 -50.324,21.67c-12.367,-0 -16.07,-5.667 -16.095,-15.883c-0.026,-11.108 12.042,-28.307 25.69,-46.49c-6.766,1.251 -29.36,16.484 -36.856,22.894c-31.276,26.743 -56.376,48.181 -80.374,61.851c-28.635,14.765 -30.493,-3.213 -23.688,-22c5.204,-14.365 5.708,-14.079 16.705,-34.027c3.395,-6.157 12.513,-19.838 18.955,-32.346c-21.194,16.195 -63.494,61.438 -108.128,109.894c-54.127,64.575 -96.284,112.081 -119.345,130.945c-8.391,6.863 -21.32,0.204 -14.954,-12.912c30.64,-55.549 61.083,-111.714 91.044,-169.382c10.592,-24.866 23.464,-49.607 38.413,-74.233c15.015,-28.578 59.12,-90.218 110.565,-160.202l-112.922,123.021c-36.339,42.043 -74.641,81.815 -114.295,120.022l-34.998,26.716c-7.575,5.788 -15.046,5.237 -17.274,-1.272Zm584.135,-59.379c2.547,-13.05 7.342,-25.449 13.647,-37.411c13.317,-22.914 32.664,-47.218 46.624,-56.324c10.853,-5.711 15.959,-1.884 14.306,5.387c-14.859,30.917 -42.775,59.263 -74.577,88.348Zm-36.287,-54.812c18.429,-40.636 47.954,-79.719 82.452,-118.106c21.615,-24.592 43.824,-45.573 67.534,-57.425c8.454,-3.531 14.15,-3.27 15.663,2.74c1.208,5.511 1.087,12.919 -0.025,15.884c-10.895,29.06 -98.099,97.654 -165.624,156.907Z"
|
||||
/>
|
||||
<path
|
||||
d="M790.827,340.284c14.131,-11.65 22.862,-18.483 26.192,-20.401c16.902,-8.922 34.857,-17.829 54.346,-26.712c41.304,-55.97 93.802,-108.542 154.102,-158.745c64.172,-53.215 105.987,-85.713 113.832,-89.283c6.351,-4.057 10.29,-3.836 9.835,2.373c0.537,5.883 -5.707,13.962 -14.222,22.776c-13.989,18.609 -69.137,70.564 -143.638,138.199c-16.254,14.232 -30.536,27.337 -42.56,39.151c-8.867,10.618 -18.587,21.162 -29.312,31.616c29.784,1.071 28.6,23.154 -0.625,46.65c-25.027,24.157 -54.137,45.113 -90.469,60.405c-28.265,41.837 -49.15,77.302 -60.555,104.586c-1.328,3.177 -7.815,18.804 -9.47,27.943c-4.9,27.063 10.015,23.06 21.109,17.971c16.709,-7.664 47.351,-35.697 78.978,-69.143c16.312,-20.342 32.626,-40.673 49.286,-59.531l35.791,-41.013c10.68,-10.696 15.887,-9.64 14.867,4.787l0.595,44.037c0.101,2.758 1.698,4.03 5.102,3.509c14.976,-4.162 29.386,-10.875 43.334,-19.664c3.561,-13.613 14.633,-25.34 29.175,-36.196l22.441,-14.931c18.8,-13.476 37.413,-21.894 55.74,-22.538c6.642,0.777 8.001,4.197 2.512,11.04c-8.132,9.079 -20.747,18.875 -34.694,28.883c-12.008,9.381 -32.042,22.63 -60.721,40.05c-4.734,3.027 -4.639,5.159 -0.543,6.55c30.233,-0.882 54.09,-16.005 77.861,-31.32l78.336,-53.796c6.813,-4.532 7.774,-2.56 4.78,4.683l-13.326,10.376c-11.237,9.236 -21.582,23.435 -30.556,45.247c19.972,-22.566 41.888,-43.948 65.1,-64.539c36.527,-31.836 66.455,-57.911 85.428,-72.972l49.659,-114.434c30.151,-70.206 63.115,-118.463 101.962,-120.814c10.2,-0.617 22.043,5.413 22.793,18.674c0.675,11.94 -9.22,36.621 -20.016,54.793c-17.775,39.721 -72.206,101.77 -143.423,162.579c-18.125,44.481 -37.315,87.848 -57.208,130.48c15.957,-15.122 32.068,-29.228 48.482,-41.326c16.178,-12.339 25.42,-11.829 23.443,9.463c-1.374,12.137 -3.975,23.706 -8.242,34.505c17.261,-20.861 34.969,-39.56 53.598,-53.805c22.833,-19.216 39.045,-22.42 43.464,2.893l0.687,19.386c0.61,3.885 2.56,3.346 4.64,0.295c3.65,-2.837 4.84,-1.296 3.571,3.234l-4.48,4.436c-8.095,6.965 -12.46,3.205 -13.005,-11.534l-2.491,-21.154c-1.277,-5.355 -4.898,-5.045 -9.637,-2.035c-10.262,6.903 -19.7,14.708 -28.47,23.249c-20.622,21.031 -39.722,43.404 -57.37,67.058c-6.958,7.296 -17.433,2.826 -13.117,-9.237c8.703,-18.489 16.414,-38.868 23.309,-60.801c0.513,-1.942 0.625,-3.57 0.555,-5.055c-0.084,-2.158 -1.304,-2.818 -3.997,-1.536c-10.007,4.648 -38.464,30.349 -69.307,58.775c-18.018,39.51 -42.493,81.084 -61.361,112.817c-15.895,26.735 -32.517,51.063 -51.844,77.582c-11.06,15.967 -24.357,29.563 -39.492,41.212c-14.64,9.765 -23.656,4.567 -23.983,-11.631c-0.227,-11.224 12.271,-31.246 29.841,-55.471l16.19,-27.055c37.737,-54.692 75.307,-98.044 112.733,-131.562l64.645,-136.834c-44.996,39.012 -86.331,78.465 -123.784,118.386c-10.374,15.05 -19.756,21.651 -27.489,14.2c-8.665,-7.056 3.682,-22.95 15.182,-38.487c-27.042,20.746 -52.866,39.881 -70.454,48.128c-18.019,9.664 -35.365,16.293 -51.281,16.483c-8.823,0.488 -14.584,-2.983 -17.154,-10.58c-16.049,9.662 -31.681,18.226 -44.512,19.401c-10.209,-0.192 -15.881,-3.907 -15.058,-12.664c1.616,-12.544 4.133,-25.363 7.168,-38.34c0.426,-5.95 0.285,-11.97 -0.325,-18.048c-4.409,1.154 -32.557,35.243 -62.642,72.018c-16.158,24.562 -42.094,53.85 -77.866,87.891c-29.099,26.823 -50.488,34.159 -63.639,23.277c-9.388,-7.768 -9.983,-23.902 -4.601,-44.68c14.14,-41.508 34.508,-77.887 57.319,-112.253l-15.554,0.957c-13.166,2.136 -21.228,-7.217 -20.125,-19.359c0.471,-5.185 5.926,-4.163 6.19,0.805l0.056,4.409c0.144,1.466 0.961,2.324 3.322,1.79c15.214,-2.886 27.175,-5.595 39.417,-8.32l11.731,-16.82c-12.537,7.756 -26.583,12.915 -43.06,13.89c-14.901,-0.493 -9.189,-15.08 6.979,-29.279Zm414.48,86.48c-22.256,40.512 -48.181,82.189 -76.975,126.343c-27.236,35.969 -44.649,56.694 -53.771,62.226c-0.12,-7.817 9.581,-24.513 23.178,-44.73c8.821,-14.641 16.901,-28.071 23.705,-39.421c40.639,-59.455 66.613,-90.413 83.863,-104.418Zm-178.28,-38.987c14.175,-9.07 28.957,-18.853 44.552,-29.591c19.866,-10.959 36.232,-20.597 40.815,-25.795c-27.737,2.819 -70.826,31.038 -85.367,55.386Zm-178.283,-30.729c31.942,-20.031 53.3,-35.788 65.798,-47.965c5.138,-4.37 9.49,-9.322 13.125,-14.804c-6.643,-1.412 -14.627,-1.157 -23.54,0.252c-9.2,9.223 -20.581,19.463 -33.337,30.345c-3.543,4.971 -11.183,15.301 -22.046,32.172Zm-58.64,-1.128c14.859,-1.459 34.671,-14.198 55.997,-28.34c3.655,-4.48 7.289,-8.929 9.624,-13.347c-9.978,3.571 -21.859,9.534 -34.242,16.306c-21.104,15.919 -32.258,23.973 -31.379,25.381Zm115.973,-78.403l33.33,-34.097c20.314,-19.226 41.291,-37.458 63.022,-54.56c31.836,-27.817 62.044,-54.745 89.268,-80.044c24.823,-25.326 53.39,-53.527 53.343,-59.749c-7.426,4.73 -16.767,13.03 -25.831,20.812c-21.766,19.158 -44.251,38.317 -66.962,57.475c-22.656,20.764 -45.415,42.327 -68.292,64.824c-33.48,32.148 -58.19,59.778 -77.878,85.339Zm401.363,-43.122c16.971,-45.011 35.077,-89.057 54.716,-131.801c17.33,-34.503 37.252,-62.015 61.735,-77.223c10.166,-5.541 19.875,-7.148 28.715,-1.277c6.635,6.635 4.298,14.28 2.519,21.567c-8.122,26.528 -25.987,56.266 -44.164,81.113c-25.536,34.905 -65.89,75.934 -103.521,107.621Z"
|
||||
/>
|
||||
<path
|
||||
d="M1446.02,213.684c-2.16,-9.662 1.698,-13.133 10.952,-10.452c3.849,3.585 8.747,6.193 13.678,6.007c9.177,2.961 12.191,9.881 6.072,15.938c0.637,5.115 -5.038,5.379 -6.199,1.113c-13.591,0.532 -21.806,-3.846 -24.503,-12.606Z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 8.8 KiB |
@ -1,5 +0,0 @@
|
||||
export function readingTimeInMinutes(text: string, options: { wpm?: number } = {}): number {
|
||||
const cleaned = text.replace(/(<.*?>)|(\\n)|(&#\d*?;)/g, '')
|
||||
const words = cleaned.split(' ').length
|
||||
return Math.round(words / (options.wpm ?? 200))
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte'
|
||||
import { page } from '$app/stores'
|
||||
|
||||
import '../app.css'
|
||||
import '$lib/actions/cloudinary'
|
||||
|
||||
import dayjs from 'dayjs'
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat.js'
|
||||
dayjs.extend(customParseFormat)
|
||||
|
||||
import { scroll } from '$lib/stores'
|
||||
import Nav from '$lib/components/Nav.svelte'
|
||||
import Progress from '$lib/components/Progress.svelte'
|
||||
|
||||
let wrapper: HTMLDivElement
|
||||
let main: HTMLElement
|
||||
|
||||
function resize() {
|
||||
wrapper.style.height = `${window.innerHeight}px`
|
||||
}
|
||||
|
||||
let last = ''
|
||||
$: {
|
||||
const { host, pathname } = $page.url
|
||||
const full = host + pathname
|
||||
if (last !== full) {
|
||||
last = full
|
||||
if (main) setTimeout(() => (main.scrollTop = 0), 150)
|
||||
}
|
||||
}
|
||||
|
||||
function updateScroll(e: any) {
|
||||
const el = e.target
|
||||
const percentage = el.scrollTop / (el.scrollHeight - el.offsetHeight)
|
||||
scroll.set(isNaN(percentage) ? 0 : percentage)
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
window.addEventListener('resize', resize, false)
|
||||
main.addEventListener('scroll', updateScroll, false)
|
||||
resize()
|
||||
return () => {
|
||||
window.removeEventListener('resize', resize)
|
||||
main.removeEventListener('scroll', updateScroll)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div bind:this={wrapper}>
|
||||
<Nav />
|
||||
<main bind:this={main}>
|
||||
<slot />
|
||||
</main>
|
||||
{#if $page.url.pathname !== '/'}
|
||||
<Progress />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
main {
|
||||
position: relative;
|
||||
padding: 3em;
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
flex: 1 0 auto;
|
||||
overflow: auto;
|
||||
max-width: calc(100% - 4em);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 30em) {
|
||||
main {
|
||||
padding: 1em;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,57 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const load: Load = async ({ fetch }) => {
|
||||
return {
|
||||
props: {
|
||||
data: await fetch('/api/pages/about.json').then((r) => r.json()),
|
||||
image: await fetch('/api/media/about-2.json').then((r) => r.json()),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import WPAdapter from '$lib/components/WPAdapter.svelte'
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
import type { GQLBaseMediaItemFragment, GQLBasePageFragment } from '$lib/gql/gen'
|
||||
import { cdn } from '$lib/actions/cloudinary'
|
||||
|
||||
export let data: GQLBasePageFragment
|
||||
export let image: GQLBaseMediaItemFragment
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{data.title}</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title={data.title} expanded={false}>
|
||||
{#if data.content}
|
||||
<WPAdapter content={data.content} />
|
||||
<img use:cdn={image.sourceUrl} alt="decoration" />
|
||||
{/if}
|
||||
</SimplePage>
|
||||
|
||||
<style>
|
||||
img {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
object-fit: contain;
|
||||
width: 24vw;
|
||||
height: 30vw;
|
||||
left: 35em;
|
||||
top: 12em;
|
||||
max-width: 25em;
|
||||
}
|
||||
|
||||
@media (max-width: 55em) {
|
||||
img {
|
||||
position: initial;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-position: right;
|
||||
max-height: 20em;
|
||||
margin-top: 4em;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,73 +0,0 @@
|
||||
import { SDK } from '$lib/gql'
|
||||
import type { RequestHandler } from '@sveltejs/kit'
|
||||
|
||||
export const get: RequestHandler<{ type: string; slug: string }, any> = async (args) => {
|
||||
const { type, slug } = args.params
|
||||
const all = slug === '*'
|
||||
|
||||
switch (type) {
|
||||
case 'pages': {
|
||||
if (all) {
|
||||
const data = await SDK.PagesMany()
|
||||
return { body: data.pages?.nodes }
|
||||
} else {
|
||||
const data = await SDK.PagesOne({ slug })
|
||||
return { body: data.page }
|
||||
}
|
||||
}
|
||||
case 'works': {
|
||||
if (all) {
|
||||
const data = await SDK.WorksMany()
|
||||
return { body: data.works?.nodes }
|
||||
} else {
|
||||
const data = await SDK.WorksOne({ slug })
|
||||
return { body: data.work }
|
||||
}
|
||||
}
|
||||
case 'projects': {
|
||||
if (all) {
|
||||
const data = await SDK.ProjectsMany()
|
||||
return { body: data.projects?.nodes }
|
||||
} else {
|
||||
const data = await SDK.ProjectsOne({ slug })
|
||||
return { body: data.project }
|
||||
}
|
||||
}
|
||||
|
||||
case 'media': {
|
||||
if (all) {
|
||||
const data = await SDK.MediaItemsMany()
|
||||
return { body: data.mediaItems?.nodes }
|
||||
} else {
|
||||
const data = await SDK.MediaItemsOne({ slug })
|
||||
return { body: data.mediaItem }
|
||||
}
|
||||
}
|
||||
|
||||
case 'posts': {
|
||||
if (all) {
|
||||
const data = await SDK.PostsMany()
|
||||
return { body: data.posts?.nodes }
|
||||
} else {
|
||||
const data = await SDK.PostsOne({ slug })
|
||||
return { body: data.post }
|
||||
}
|
||||
}
|
||||
|
||||
case 'tags': {
|
||||
if (all) {
|
||||
const data = await SDK.TagsMany()
|
||||
const sorted = [...data.tags.nodes].filter((t) => t.count).sort((a, b) => b.count - a.count)
|
||||
return { body: sorted }
|
||||
}
|
||||
}
|
||||
|
||||
case 'postsByTags': {
|
||||
const data = await SDK.PostsManyByTag({ tag: slug })
|
||||
return { body: data.posts.nodes }
|
||||
}
|
||||
|
||||
default:
|
||||
return { status: 404 }
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
import { SDK } from '$lib/gql'
|
||||
import type { GQLBasePageFragment } from '$lib/gql/gen'
|
||||
import lunr from 'lunr'
|
||||
|
||||
function removeHTML(s: string) {
|
||||
return s.replace(/<.*?>|\s+|&#\d+;/g, ' ').trim()
|
||||
}
|
||||
|
||||
function convertForIdx(type: string, items: GQLBasePageFragment[]) {
|
||||
const keys: (keyof GQLBasePageFragment)[] = ['title', 'content', 'slug']
|
||||
return items.map((item) => ({
|
||||
url: `${type}/${item.slug}`,
|
||||
data: keys.map((field) => removeHTML(item[field] ?? '')).join(' '),
|
||||
}))
|
||||
}
|
||||
|
||||
export const get = async () => {
|
||||
const { __typename, ...all } = await SDK.Search()
|
||||
const converted = Object.entries(all)
|
||||
.map(([type, data]) => convertForIdx(type, data.nodes))
|
||||
.flat()
|
||||
|
||||
const idx = lunr(function () {
|
||||
this.ref('url')
|
||||
this.field('data')
|
||||
converted.forEach((doc) => this.add(doc))
|
||||
})
|
||||
|
||||
return { body: idx }
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const load: Load = async ({ fetch, params }) => {
|
||||
return {
|
||||
props: {
|
||||
data: await fetch(`/api/posts/${params.slug}.json`).then((r) => r.json()),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import PostAttributes from '$lib/components/PostAttributes.svelte'
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
import Tags from '$lib/components/Tags.svelte'
|
||||
import WpAdapter from '$lib/components/WPAdapter.svelte'
|
||||
import Discussion from '$lib/components/Discussion.svelte'
|
||||
import type { GQLBasePostFragment } from '$lib/gql/gen'
|
||||
|
||||
export let data: GQLBasePostFragment
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Blog - {data.title}</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title={data.title} readable>
|
||||
<PostAttributes post={data} full />
|
||||
{#if data.content}
|
||||
<WpAdapter content={data.content} legend />
|
||||
{/if}
|
||||
<Tags tags={data.tags.nodes} />
|
||||
</SimplePage>
|
||||
|
||||
<Discussion />
|
@ -1,42 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const load: Load = async ({ fetch }) => {
|
||||
return {
|
||||
props: {
|
||||
data: await fetch('/api/posts/*.json').then((r) => r.json()),
|
||||
tags: await fetch('/api/tags/*.json').then((r) => r.json()),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
import PostPreview from '$lib/components/PostPreview.svelte'
|
||||
import type { GQLBasePostFragment, GQLBaseTagFragment } from '$lib/gql/gen'
|
||||
import Tags from '$lib/components/Tags.svelte'
|
||||
|
||||
export let data: GQLBasePostFragment[]
|
||||
export let tags: GQLBaseTagFragment[]
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Blog</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title="Blog">
|
||||
<b>Explore Tags</b>
|
||||
<Tags {tags} />
|
||||
<div />
|
||||
|
||||
{#each data as post}
|
||||
<PostPreview {post} />
|
||||
{/each}
|
||||
</SimplePage>
|
||||
|
||||
<style>
|
||||
div {
|
||||
margin-bottom: 3em;
|
||||
}
|
||||
</style>
|
@ -1,31 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const load: Load = async ({ fetch, params }) => {
|
||||
return {
|
||||
props: {
|
||||
slug: params.slug,
|
||||
data: await fetch(`/api/postsByTags/${params.slug}.json`).then((r) => r.json()),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
import type { GQLPostsManyByTagQuery } from '$lib/gql/gen'
|
||||
import PostPreview from '$lib/components/PostPreview.svelte'
|
||||
|
||||
export let slug: string
|
||||
export let data: GQLPostsManyByTagQuery['posts']['nodes']
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Blog - {slug}</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title={slug}>
|
||||
{#each data as post}
|
||||
<PostPreview {post} />
|
||||
{/each}
|
||||
</SimplePage>
|
@ -1,35 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { Link } from '$lib/components/IconList.svelte'
|
||||
import IconList from '$lib/components/IconList.svelte'
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
|
||||
const links: Link[] = [
|
||||
{
|
||||
href: 'mailto:hi@nicco.io',
|
||||
name: 'Say hi@nicco.io',
|
||||
icon: 'mail-outline',
|
||||
},
|
||||
{
|
||||
href: 'https://discord.gg/wS7RpYTYd2',
|
||||
name: 'Chat on Discord',
|
||||
icon: 'chatbubbles-outline',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/cupcakearmy',
|
||||
name: 'Github',
|
||||
icon: 'logo-github',
|
||||
},
|
||||
{ href: 'https://spectare.nicco.io/share/q80YU8C2/nicco.io', name: 'Website Statistics', icon: 'analytics' },
|
||||
{ href: '/privacy', name: 'Privacy Policy', icon: 'finger-print-outline' },
|
||||
{ href: '/support', name: 'Support', icon: 'heart-sharp' },
|
||||
{ href: 'https://status.nicco.io', name: 'Status Monitor', icon: 'caret-up-circle' },
|
||||
]
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Contact</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title="Contact">
|
||||
<IconList {links} />
|
||||
</SimplePage>
|
@ -1,100 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { GQLBaseMediaItemFragment } from '$lib/gql/gen'
|
||||
|
||||
type Data = Record<'home', GQLBaseMediaItemFragment>
|
||||
export const load: Load = async ({ fetch }) => {
|
||||
const home: GQLBaseMediaItemFragment = await fetch('/api/media/home.json').then((r) => r.json())
|
||||
return { props: { data: { home } } }
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
import SpacedLetters from '$lib/components/SpacedLetters.svelte'
|
||||
import Signature from '$lib/svgs/Signature.svelte'
|
||||
|
||||
export let data: Data
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Niccolò Borgioli</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="left" style="z-index: 3;">
|
||||
<h1>
|
||||
<SpacedLetters letters="Niccolò" even />
|
||||
<SpacedLetters letters="Borgioli" even />
|
||||
</h1>
|
||||
|
||||
<p>Design & Development</p>
|
||||
</div>
|
||||
|
||||
<div class="right" style="z-index: 2;">
|
||||
<img srcset={data.home.srcSet} alt="decoration" class="home" />
|
||||
<Signature class="signature" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.left {
|
||||
flex: 1 0 auto;
|
||||
max-width: 64vw;
|
||||
}
|
||||
|
||||
.right {
|
||||
position: relative;
|
||||
top: 5vh;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 4vw;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
img.home {
|
||||
width: min(100%, 33vw);
|
||||
object-fit: contain;
|
||||
object-position: left;
|
||||
max-height: 65vh;
|
||||
}
|
||||
.right :global(.signature) {
|
||||
position: absolute;
|
||||
width: 50%;
|
||||
top: 0%;
|
||||
left: -8.5%;
|
||||
transform: rotate(-25deg);
|
||||
}
|
||||
|
||||
@media (max-width: 50em) {
|
||||
.wrapper {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.left {
|
||||
flex: initial;
|
||||
}
|
||||
|
||||
.right {
|
||||
left: 1rem;
|
||||
}
|
||||
|
||||
img.home {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
max-height: calc(90vh - 35vw - 5vh);
|
||||
max-width: 90%;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,29 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const load: Load = async ({ fetch }) => {
|
||||
return {
|
||||
props: {
|
||||
data: await fetch('/api/pages/privacy.json').then((r) => r.json()),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import WPAdapter from '$lib/components/WPAdapter.svelte'
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
import type { GQLBasePageFragment } from '$lib/gql/gen'
|
||||
|
||||
export let data: GQLBasePageFragment
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{data.title}</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title={data.title} expanded={false}>
|
||||
{#if data.content}
|
||||
<WPAdapter content={data.content} legend />
|
||||
{/if}
|
||||
</SimplePage>
|
@ -1,29 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const load: Load = async ({ fetch }) => {
|
||||
return {
|
||||
props: {
|
||||
data: await fetch('/api/projects/*.json').then((r) => r.json()),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
import Project from '$lib/components/Project.svelte'
|
||||
import type { GQLBaseProjectFragment } from '$lib/gql/gen'
|
||||
|
||||
export let data: GQLBaseProjectFragment[]
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Projects</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title="Projects">
|
||||
{#each data as project}
|
||||
<Project {project} />
|
||||
{/each}
|
||||
</SimplePage>
|
@ -1,86 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const load: Load = async ({ fetch }) => {
|
||||
return {
|
||||
props: {
|
||||
prebuilt: await fetch('/api/search.json').then((r) => r.json()),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import lunr from 'lunr'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
import type { SearchResultItem } from '$lib/components/SearchResult.svelte'
|
||||
import SearchResult from '$lib/components/SearchResult.svelte'
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
|
||||
export let prebuilt: any
|
||||
let needle: string | null = null
|
||||
let results: SearchResultItem[] = []
|
||||
let input: HTMLInputElement
|
||||
|
||||
const idx = lunr.Index.load(prebuilt)
|
||||
|
||||
async function search(needle: string) {
|
||||
if (!needle || !idx) {
|
||||
results = []
|
||||
} else {
|
||||
let found = idx.search(needle + '~1')
|
||||
if (!found.length) found = idx.search(needle + '*')
|
||||
results = found.slice(0, 20)
|
||||
}
|
||||
}
|
||||
|
||||
$: if (needle !== null) {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.history.replaceState(null, '', `/search?q=${needle ?? ''}`)
|
||||
}
|
||||
search(needle)
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
needle = new URLSearchParams(window.location.search).get('q')
|
||||
input.focus()
|
||||
})
|
||||
</script>
|
||||
|
||||
<SimplePage title="Search" expanded={false}>
|
||||
<input bind:this={input} bind:value={needle} placeholder="needle" />
|
||||
{#if needle && needle.indexOf('haystack') !== -1}
|
||||
<p>⛳️✨ Here is a flag for you. ✨⛳</p>
|
||||
{/if}
|
||||
{#if needle}
|
||||
<ul>
|
||||
{#each results as result (result.ref)}
|
||||
<SearchResult {result} />
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</SimplePage>
|
||||
|
||||
<style>
|
||||
input {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
padding: 0.75rem;
|
||||
font-size: inherit;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
border: 0.15rem solid var(--clr-primary);
|
||||
border-bottom-width: 0.5rem;
|
||||
border-radius: 0;
|
||||
background: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-top: 2em;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
@ -1,27 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { Link } from '$lib/components/IconList.svelte'
|
||||
import IconList from '$lib/components/IconList.svelte'
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
|
||||
const links: Link[] = [
|
||||
{
|
||||
href: 'https://www.buymeacoffee.com/cupcakearmy',
|
||||
name: 'Buy Me A Coffee',
|
||||
icon: 'cafe',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/sponsors/cupcakearmy',
|
||||
name: 'Github Sponsor',
|
||||
icon: 'logo-github',
|
||||
},
|
||||
{ href: 'https://www.paypal.com/paypalme/cupcakearmy', name: 'Paypal', icon: 'paypal' },
|
||||
]
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Support</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title="Support">
|
||||
<IconList {links} />
|
||||
</SimplePage>
|
@ -1,27 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const load: Load = async ({ fetch, params }) => {
|
||||
return {
|
||||
props: {
|
||||
data: await fetch(`/api/works/${params.slug}.json`).then((r) => r.json()),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
import Work from '$lib/components/Work.svelte'
|
||||
import type { GQLBaseWorkFragment } from '$lib/gql/gen'
|
||||
|
||||
export let data: GQLBaseWorkFragment
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Works</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title="Works">
|
||||
<Work work={data} />
|
||||
</SimplePage>
|
@ -1,29 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const load: Load = async ({ fetch }) => {
|
||||
return {
|
||||
props: {
|
||||
data: await fetch('/api/works/*.json').then((r) => r.json()),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { GQLBaseWorkFragment } from '$lib/gql/gen'
|
||||
import SimplePage from '$lib/components/SimplePage.svelte'
|
||||
import Work from '$lib/components/Work.svelte'
|
||||
|
||||
export let data: GQLBaseWorkFragment[]
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Works</title>
|
||||
</svelte:head>
|
||||
|
||||
<SimplePage title="Works">
|
||||
{#each data as work}
|
||||
<Work {work} />
|
||||
{/each}
|
||||
</SimplePage>
|
Before Width: | Height: | Size: 8.1 KiB |
@ -1,13 +0,0 @@
|
||||
import preprocess from 'svelte-preprocess'
|
||||
import adapter from '@sveltejs/adapter-static'
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
preprocess: preprocess(),
|
||||
kit: {
|
||||
prerender: { default: true },
|
||||
adapter: adapter(),
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
@ -1,34 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"module": "es2020",
|
||||
"lib": ["es2020"],
|
||||
"target": "es2019",
|
||||
|
||||
"noImplicitAny": true,
|
||||
"alwaysStrict": true,
|
||||
"strictNullChecks": true,
|
||||
/**
|
||||
svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
|
||||
to enforce using \`import type\` instead of \`import\` for Types.
|
||||
*/
|
||||
"importsNotUsedAsValues": "error",
|
||||
"isolatedModules": true,
|
||||
"resolveJsonModule": true,
|
||||
/**
|
||||
To have warnings/errors of the Svelte compiler at the correct position,
|
||||
enable source maps by default.
|
||||
*/
|
||||
"sourceMap": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"baseUrl": ".",
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"paths": {
|
||||
"$lib/*": ["src/lib/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts", "src/**/*.svelte"]
|
||||
}
|