This commit is contained in:
vcoppe
2024-04-08 17:12:39 +02:00
parent 411ae8e6a6
commit 4e0bb275fb
38 changed files with 1467 additions and 166 deletions

14
website/components.json Normal file
View File

@@ -0,0 +1,14 @@
{
"$schema": "https://shadcn-svelte.com/schema.json",
"style": "default",
"tailwind": {
"config": "tailwind.config.js",
"css": "src/app.css",
"baseColor": "slate"
},
"aliases": {
"components": "$lib/components",
"utils": "$lib/utils"
},
"typescript": true
}

File diff suppressed because it is too large Load Diff

View File

@@ -38,7 +38,12 @@
"type": "module",
"dependencies": {
"@maplibre/maplibre-gl-geocoder": "^1.5.0",
"bits-ui": "^0.21.2",
"clsx": "^2.1.0",
"gpx": "file:../gpx",
"maplibre-gl": "^4.1.2"
"lucide-svelte": "^0.365.0",
"maplibre-gl": "^4.1.2",
"tailwind-merge": "^2.2.2",
"tailwind-variants": "^0.2.1"
}
}

View File

@@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

78
website/src/app.pcss Normal file
View File

@@ -0,0 +1,78 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 72.2% 50.6%;
--destructive-foreground: 210 40% 98%;
--ring: 222.2 84% 4.9%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--ring: hsl(212.7,26.8%,83.9);
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}

View File

@@ -0,0 +1,5 @@
<script lang="ts">
import { base } from '$app/paths';
</script>
<img src="{base}/logo.svg" alt="Logo of gpx.studio." {...$$restProps} />

View File

@@ -72,8 +72,6 @@
collapsed: true
})
);
console.log(map);
});
onDestroy(() => {

View File

@@ -0,0 +1,95 @@
<script lang="ts">
import * as Menubar from '$lib/components/ui/menubar/index.js';
import { Button } from '$lib/components/ui/button';
import Logo from './Logo.svelte';
let distanceUnits = 'metric';
let velocityUnits = 'speed';
let showDistanceMarkers = false;
let showDirectionMarkers = false;
</script>
<div class="h-fit flex flex-row items-center mx-1">
<Logo class="h-5 mt-1 mx-2" />
<Menubar.Root class="border-none">
<Menubar.Menu>
<Menubar.Trigger>File</Menubar.Trigger>
<Menubar.Content>
<Menubar.Item>
New GPX file <Menubar.Shortcut>⌘N</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item>
Load GPX file(s)... <Menubar.Shortcut>⌘O</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Separator />
<Menubar.Item>
Export... <Menubar.Shortcut>⌘S</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item>
Export all... <Menubar.Shortcut>⇧⌘S</Menubar.Shortcut>
</Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>Edit</Menubar.Trigger>
<Menubar.Content>
<Menubar.Item>
Undo <Menubar.Shortcut>⌘Z</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item>
Redo <Menubar.Shortcut>⇧⌘Z</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Separator />
<Menubar.Item>Delete <Menubar.Shortcut>⌘D</Menubar.Shortcut></Menubar.Item>
<Menubar.Item>Delete all<Menubar.Shortcut>⇧⌘D</Menubar.Shortcut></Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>Help</Menubar.Trigger>
<Menubar.Content>
<Menubar.Item>
Quick help <Menubar.Shortcut>⌘H</Menubar.Shortcut>
</Menubar.Item>
<Menubar.Item>User guide</Menubar.Item>
</Menubar.Content>
</Menubar.Menu>
<Menubar.Menu>
<Menubar.Trigger>Settings</Menubar.Trigger>
<Menubar.Content
><Menubar.Sub>
<Menubar.SubTrigger inset>Distance units</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.RadioGroup bind:value={distanceUnits}>
<Menubar.RadioItem value="metric">Metric</Menubar.RadioItem>
<Menubar.RadioItem value="imperial">Imperial</Menubar.RadioItem>
</Menubar.RadioGroup>
</Menubar.SubContent>
</Menubar.Sub>
<Menubar.Sub>
<Menubar.SubTrigger inset>Velocity units</Menubar.SubTrigger>
<Menubar.SubContent>
<Menubar.RadioGroup bind:value={velocityUnits}>
<Menubar.RadioItem value="speed">Speed</Menubar.RadioItem>
<Menubar.RadioItem value="pace">Pace</Menubar.RadioItem>
</Menubar.RadioGroup>
</Menubar.SubContent>
</Menubar.Sub>
<Menubar.Separator />
<Menubar.CheckboxItem bind:checked={showDistanceMarkers}>
Show distance markers
</Menubar.CheckboxItem>
<Menubar.CheckboxItem bind:checked={showDirectionMarkers}>
Show direction markers
</Menubar.CheckboxItem>
</Menubar.Content>
</Menubar.Menu>
</Menubar.Root>
<div class="py-1 h-10">
<Button
variant="ghost"
href="/about"
target="_blank"
class="cursor-default py-1.5 px-3 h-fit rounded-sm">About</Button
>
</div>
</div>

View File

@@ -0,0 +1,25 @@
<script lang="ts">
import { Button as ButtonPrimitive } from "bits-ui";
import { type Events, type Props, buttonVariants } from "./index.js";
import { cn } from "$lib/utils.js";
type $$Props = Props;
type $$Events = Events;
let className: $$Props["class"] = undefined;
export let variant: $$Props["variant"] = "default";
export let size: $$Props["size"] = "default";
export let builders: $$Props["builders"] = [];
export { className as class };
</script>
<ButtonPrimitive.Root
{builders}
class={cn(buttonVariants({ variant, size, className }))}
type="button"
{...$$restProps}
on:click
on:keydown
>
<slot />
</ButtonPrimitive.Root>

View File

@@ -0,0 +1,49 @@
import { type VariantProps, tv } from "tailwind-variants";
import type { Button as ButtonPrimitive } from "bits-ui";
import Root from "./button.svelte";
const buttonVariants = tv({
base: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
});
type Variant = VariantProps<typeof buttonVariants>["variant"];
type Size = VariantProps<typeof buttonVariants>["size"];
type Props = ButtonPrimitive.Props & {
variant?: Variant;
size?: Size;
};
type Events = ButtonPrimitive.Events;
export {
Root,
type Props,
type Events,
//
Root as Button,
type Props as ButtonProps,
type Events as ButtonEvents,
buttonVariants,
};

View File

@@ -0,0 +1,35 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import Check from "lucide-svelte/icons/check";
import { cn } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.CheckboxItemProps;
type $$Events = DropdownMenuPrimitive.CheckboxItemEvents;
let className: $$Props["class"] = undefined;
export let checked: $$Props["checked"] = undefined;
export { className as class };
</script>
<DropdownMenuPrimitive.CheckboxItem
bind:checked
class={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
className
)}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.CheckboxIndicator>
<Check class="h-4 w-4" />
</DropdownMenuPrimitive.CheckboxIndicator>
</span>
<slot />
</DropdownMenuPrimitive.CheckboxItem>

View File

@@ -0,0 +1,27 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.ContentProps;
type $$Events = DropdownMenuPrimitive.ContentEvents;
let className: $$Props["class"] = undefined;
export let sideOffset: $$Props["sideOffset"] = 4;
export let transition: $$Props["transition"] = flyAndScale;
export let transitionConfig: $$Props["transitionConfig"] = undefined;
export { className as class };
</script>
<DropdownMenuPrimitive.Content
{transition}
{transitionConfig}
{sideOffset}
class={cn(
"z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none",
className
)}
{...$$restProps}
on:keydown
>
<slot />
</DropdownMenuPrimitive.Content>

View File

@@ -0,0 +1,31 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.ItemProps & {
inset?: boolean;
};
type $$Events = DropdownMenuPrimitive.ItemEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script>
<DropdownMenuPrimitive.Item
class={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
inset && "pl-8",
className
)}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
>
<slot />
</DropdownMenuPrimitive.Item>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.LabelProps & {
inset?: boolean;
};
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script>
<DropdownMenuPrimitive.Label
class={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...$$restProps}
>
<slot />
</DropdownMenuPrimitive.Label>

View File

@@ -0,0 +1,11 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
type $$Props = DropdownMenuPrimitive.RadioGroupProps;
export let value: $$Props["value"] = undefined;
</script>
<DropdownMenuPrimitive.RadioGroup {...$$restProps} bind:value>
<slot />
</DropdownMenuPrimitive.RadioGroup>

View File

@@ -0,0 +1,35 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import Circle from "lucide-svelte/icons/circle";
import { cn } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.RadioItemProps;
type $$Events = DropdownMenuPrimitive.RadioItemEvents;
let className: $$Props["class"] = undefined;
export let value: $$Props["value"];
export { className as class };
</script>
<DropdownMenuPrimitive.RadioItem
class={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
className
)}
{value}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerdown
on:pointerleave
on:pointermove
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<DropdownMenuPrimitive.RadioIndicator>
<Circle class="h-2 w-2 fill-current" />
</DropdownMenuPrimitive.RadioIndicator>
</span>
<slot />
</DropdownMenuPrimitive.RadioItem>

View File

@@ -0,0 +1,14 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.SeparatorProps;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<DropdownMenuPrimitive.Separator
class={cn("-mx-1 my-1 h-px bg-muted", className)}
{...$$restProps}
/>

View File

@@ -0,0 +1,13 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLSpanElement>;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<span class={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...$$restProps}>
<slot />
</span>

View File

@@ -0,0 +1,30 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.SubContentProps;
type $$Events = DropdownMenuPrimitive.SubContentEvents;
let className: $$Props["class"] = undefined;
export let transition: $$Props["transition"] = flyAndScale;
export let transitionConfig: $$Props["transitionConfig"] = {
x: -10,
y: 0,
};
export { className as class };
</script>
<DropdownMenuPrimitive.SubContent
{transition}
{transitionConfig}
class={cn(
"z-50 min-w-[8rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-lg focus:outline-none",
className
)}
{...$$restProps}
on:keydown
on:focusout
on:pointermove
>
<slot />
</DropdownMenuPrimitive.SubContent>

View File

@@ -0,0 +1,32 @@
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import ChevronRight from "lucide-svelte/icons/chevron-right";
import { cn } from "$lib/utils.js";
type $$Props = DropdownMenuPrimitive.SubTriggerProps & {
inset?: boolean;
};
type $$Events = DropdownMenuPrimitive.SubTriggerEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script>
<DropdownMenuPrimitive.SubTrigger
class={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground",
inset && "pl-8",
className
)}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
>
<slot />
<ChevronRight class="ml-auto h-4 w-4" />
</DropdownMenuPrimitive.SubTrigger>

View File

@@ -0,0 +1,48 @@
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
import Item from "./dropdown-menu-item.svelte";
import Label from "./dropdown-menu-label.svelte";
import Content from "./dropdown-menu-content.svelte";
import Shortcut from "./dropdown-menu-shortcut.svelte";
import RadioItem from "./dropdown-menu-radio-item.svelte";
import Separator from "./dropdown-menu-separator.svelte";
import RadioGroup from "./dropdown-menu-radio-group.svelte";
import SubContent from "./dropdown-menu-sub-content.svelte";
import SubTrigger from "./dropdown-menu-sub-trigger.svelte";
import CheckboxItem from "./dropdown-menu-checkbox-item.svelte";
const Sub = DropdownMenuPrimitive.Sub;
const Root = DropdownMenuPrimitive.Root;
const Trigger = DropdownMenuPrimitive.Trigger;
const Group = DropdownMenuPrimitive.Group;
export {
Sub,
Root,
Item,
Label,
Group,
Trigger,
Content,
Shortcut,
Separator,
RadioItem,
SubContent,
SubTrigger,
RadioGroup,
CheckboxItem,
//
Root as DropdownMenu,
Sub as DropdownMenuSub,
Item as DropdownMenuItem,
Label as DropdownMenuLabel,
Group as DropdownMenuGroup,
Content as DropdownMenuContent,
Trigger as DropdownMenuTrigger,
Shortcut as DropdownMenuShortcut,
RadioItem as DropdownMenuRadioItem,
Separator as DropdownMenuSeparator,
RadioGroup as DropdownMenuRadioGroup,
SubContent as DropdownMenuSubContent,
SubTrigger as DropdownMenuSubTrigger,
CheckboxItem as DropdownMenuCheckboxItem,
};

View File

@@ -0,0 +1,52 @@
import { Menubar as MenubarPrimitive } from "bits-ui";
import Root from "./menubar.svelte";
import CheckboxItem from "./menubar-checkbox-item.svelte";
import Content from "./menubar-content.svelte";
import Item from "./menubar-item.svelte";
import Label from "./menubar-label.svelte";
import RadioItem from "./menubar-radio-item.svelte";
import Separator from "./menubar-separator.svelte";
import Shortcut from "./menubar-shortcut.svelte";
import SubContent from "./menubar-sub-content.svelte";
import SubTrigger from "./menubar-sub-trigger.svelte";
import Trigger from "./menubar-trigger.svelte";
const Menu = MenubarPrimitive.Menu;
const Group = MenubarPrimitive.Group;
const Sub = MenubarPrimitive.Sub;
const RadioGroup = MenubarPrimitive.RadioGroup;
export {
Root,
CheckboxItem,
Content,
Item,
Label,
RadioItem,
Separator,
Shortcut,
SubContent,
SubTrigger,
Trigger,
Menu,
Group,
Sub,
RadioGroup,
//
Root as Menubar,
CheckboxItem as MenubarCheckboxItem,
Content as MenubarContent,
Item as MenubarItem,
Label as MenubarLabel,
RadioItem as MenubarRadioItem,
Separator as MenubarSeparator,
Shortcut as MenubarShortcut,
SubContent as MenubarSubContent,
SubTrigger as MenubarSubTrigger,
Trigger as MenubarTrigger,
Menu as MenubarMenu,
Group as MenubarGroup,
Sub as MenubarSub,
RadioGroup as MenubarRadioGroup,
};

View File

@@ -0,0 +1,35 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import Check from "lucide-svelte/icons/check";
import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.CheckboxItemProps;
type $$Events = MenubarPrimitive.CheckboxItemEvents;
let className: $$Props["class"] = undefined;
export let checked: $$Props["checked"] = false;
export { className as class };
</script>
<MenubarPrimitive.CheckboxItem
bind:checked
class={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
className
)}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
on:pointerdown
{...$$restProps}
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<MenubarPrimitive.CheckboxIndicator>
<Check class="h-4 w-4" />
</MenubarPrimitive.CheckboxIndicator>
</span>
<slot />
</MenubarPrimitive.CheckboxItem>

View File

@@ -0,0 +1,33 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js";
type $$Props = MenubarPrimitive.ContentProps;
type $$Events = MenubarPrimitive.ContentEvents;
let className: $$Props["class"] = undefined;
export let sideOffset: $$Props["sideOffset"] = 8;
export let alignOffset: $$Props["alignOffset"] = -4;
export let align: $$Props["align"] = "start";
export let side: $$Props["side"] = "bottom";
export let transition: $$Props["transition"] = flyAndScale;
export let transitionConfig: $$Props["transitionConfig"] = undefined;
export { className as class };
</script>
<MenubarPrimitive.Content
{transition}
{transitionConfig}
{sideOffset}
{align}
{alignOffset}
{side}
class={cn(
"z-50 min-w-[12rem] rounded-md border bg-popover p-1 text-popover-foreground shadow-md focus:outline-none",
className
)}
{...$$restProps}
on:keydown
>
<slot />
</MenubarPrimitive.Content>

View File

@@ -0,0 +1,31 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.ItemProps & {
inset?: boolean;
};
type $$Events = MenubarPrimitive.ItemEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script>
<MenubarPrimitive.Item
class={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
inset && "pl-8",
className
)}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
on:pointerdown
>
<slot />
</MenubarPrimitive.Item>

View File

@@ -0,0 +1,19 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.LabelProps & {
inset?: boolean;
};
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script>
<MenubarPrimitive.Label
class={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)}
{...$$restProps}
>
<slot />
</MenubarPrimitive.Label>

View File

@@ -0,0 +1,35 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import Circle from "lucide-svelte/icons/circle";
import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.RadioItemProps;
type $$Events = MenubarPrimitive.RadioItemEvents;
let className: $$Props["class"] = undefined;
export let value: $$Props["value"];
export { className as class };
</script>
<MenubarPrimitive.RadioItem
{value}
class={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
className
)}
{...$$restProps}
on:click
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
on:pointerdown
>
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<MenubarPrimitive.RadioIndicator>
<Circle class="h-2 w-2 fill-current" />
</MenubarPrimitive.RadioIndicator>
</span>
<slot />
</MenubarPrimitive.RadioItem>

View File

@@ -0,0 +1,11 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.SeparatorProps;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<MenubarPrimitive.Separator class={cn("-mx-1 my-1 h-px bg-muted", className)} {...$$restProps} />

View File

@@ -0,0 +1,16 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLSpanElement>;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<span
class={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)}
{...$$restProps}
>
<slot />
</span>

View File

@@ -0,0 +1,27 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn, flyAndScale } from "$lib/utils.js";
type $$Props = MenubarPrimitive.SubContentProps;
type $$Events = MenubarPrimitive.SubContentEvents;
let className: $$Props["class"] = undefined;
export let transition: $$Props["transition"] = flyAndScale;
export let transitionConfig: $$Props["transitionConfig"] = { x: -10, y: 0 };
export { className as class };
</script>
<MenubarPrimitive.SubContent
{transition}
{transitionConfig}
class={cn(
"z-50 min-w-max rounded-md border bg-popover p-1 text-popover-foreground focus:outline-none",
className
)}
{...$$restProps}
on:focusout
on:pointermove
on:keydown
>
<slot />
</MenubarPrimitive.SubContent>

View File

@@ -0,0 +1,32 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import ChevronRight from "lucide-svelte/icons/chevron-right";
import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.SubTriggerProps & {
inset?: boolean;
};
type $$Events = MenubarPrimitive.SubTriggerEvents;
let className: $$Props["class"] = undefined;
export let inset: $$Props["inset"] = undefined;
export { className as class };
</script>
<MenubarPrimitive.SubTrigger
class={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground data-[disabled]:opacity-50",
inset && "pl-8",
className
)}
on:click
{...$$restProps}
on:keydown
on:focusin
on:focusout
on:pointerleave
on:pointermove
>
<slot />
<ChevronRight class="ml-auto h-4 w-4" />
</MenubarPrimitive.SubTrigger>

View File

@@ -0,0 +1,23 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.TriggerProps;
type $$Events = MenubarPrimitive.TriggerEvents;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<MenubarPrimitive.Trigger
class={cn(
"flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none data-[highlighted]:bg-accent data-[state=open]:bg-accent data-[highlighted]:text-accent-foreground data-[state=open]:text-accent-foreground",
className
)}
on:click
on:keydown
on:pointerenter
{...$$restProps}
>
<slot />
</MenubarPrimitive.Trigger>

View File

@@ -0,0 +1,16 @@
<script lang="ts">
import { Menubar as MenubarPrimitive } from "bits-ui";
import { cn } from "$lib/utils.js";
type $$Props = MenubarPrimitive.Props;
let className: $$Props["class"] = undefined;
export { className as class };
</script>
<MenubarPrimitive.Root
class={cn("flex h-10 items-center space-x-1 rounded-md border bg-background p-1", className)}
{...$$restProps}
>
<slot />
</MenubarPrimitive.Root>

62
website/src/lib/utils.ts Normal file
View File

@@ -0,0 +1,62 @@
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
import { cubicOut } from "svelte/easing";
import type { TransitionConfig } from "svelte/transition";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
type FlyAndScaleParams = {
y?: number;
x?: number;
start?: number;
duration?: number;
};
export const flyAndScale = (
node: Element,
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
): TransitionConfig => {
const style = getComputedStyle(node);
const transform = style.transform === "none" ? "" : style.transform;
const scaleConversion = (
valueA: number,
scaleA: [number, number],
scaleB: [number, number]
) => {
const [minA, maxA] = scaleA;
const [minB, maxB] = scaleB;
const percentage = (valueA - minA) / (maxA - minA);
const valueB = percentage * (maxB - minB) + minB;
return valueB;
};
const styleToString = (
style: Record<string, number | string | undefined>
): string => {
return Object.keys(style).reduce((str, key) => {
if (style[key] === undefined) return str;
return str + `${key}:${style[key]};`;
}, "");
};
return {
duration: params.duration ?? 200,
delay: 0,
css: (t) => {
const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]);
const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]);
const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]);
return styleToString({
transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`,
opacity: t
});
},
easing: cubicOut
};
};

View File

@@ -1,5 +1,5 @@
<script>
import '../app.css';
import '../app.pcss';
</script>
<slot />

View File

@@ -1,8 +1,10 @@
<script lang="ts">
import Map from '$lib/components/Map.svelte';
import Menu from '$lib/components/Menu.svelte';
</script>
<div class="flex flex-col w-screen h-screen">
<Menu />
<Map class="grow" />
<div class="h-1/3">Test</div>
</div>

239
website/static/logo.svg Normal file
View File

@@ -0,0 +1,239 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg2"
width="1181.2769"
height="247.79251"
viewBox="0 0 1181.2769 247.79251"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs6">
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath16">
<path
d="M 0,630 H 1200 V 0 H 0 Z"
id="path14" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath96">
<path
d="M 410.129,207.977 H 624.177 V 422.024 H 410.129 Z"
id="path94" />
</clipPath>
</defs>
<g
id="g8"
transform="matrix(1.3333333,0,0,-1.3333333,-209.36172,543.79306)">
<g
id="g10">
<g
id="g12"
clip-path="url(#clipPath16)">
<g
id="g18"
transform="translate(224.4053,313.6836)">
<path
d="m 0,0 c 0,22.193 -11.968,30.28 -23.375,30.28 -14.959,0 -23.749,-11.871 -23.749,-29.075 0,-19.269 11.594,-27.699 23.001,-27.699 C -12.155,-26.494 0,-17.893 0,0 m 15.006,43.871 c 1.833,0 3.32,-1.486 3.32,-3.32 v -76.508 c 0,-28.387 -20.196,-38.602 -44.319,-38.602 -10.021,0 -21.107,1.47 -30.145,5.366 -0.433,0.186 -0.709,0.618 -0.709,1.089 l 2,14.243 c 0,0.884 0.936,1.458 1.718,1.043 7.85,-4.171 16.044,-6.257 25.266,-6.257 17.391,0 27.863,5.398 27.863,23.291 0,2.866 -3.378,4.372 -5.524,2.471 -5.548,-4.914 -12.87,-7.633 -21.965,-7.633 -19.822,0 -38.895,13.763 -38.895,41.806 0,25.29 15.147,44.215 38.895,44.215 9.531,0 16.72,-2.931 21.964,-7.818 C -3.429,35.304 0,36.87 0,39.734 v 0.817 c 0,1.834 1.486,3.32 3.319,3.32 z"
style="display:inline;fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path20" />
</g>
<g
id="g22"
transform="translate(224.4053,313.6836)">
<path
d="m 0,0 c 0,22.193 -11.968,30.28 -23.375,30.28 -14.959,0 -23.749,-11.871 -23.749,-29.075 0,-19.269 11.594,-27.699 23.001,-27.699 C -12.155,-26.494 0,-17.893 0,0 Z m 15.006,43.871 c 1.833,0 3.32,-1.486 3.32,-3.32 v -76.508 c 0,-28.387 -20.196,-38.602 -44.319,-38.602 -10.021,0 -21.107,1.47 -30.145,5.366 -0.433,0.186 -0.709,0.618 -0.709,1.089 l 2,14.243 c 0,0.884 0.936,1.458 1.718,1.043 7.85,-4.171 16.044,-6.257 25.266,-6.257 17.391,0 27.863,5.398 27.863,23.291 0,2.866 -3.378,4.372 -5.524,2.471 -5.548,-4.914 -12.87,-7.633 -21.965,-7.633 -19.822,0 -38.895,13.763 -38.895,41.806 0,25.29 15.147,44.215 38.895,44.215 9.531,0 16.72,-2.931 21.964,-7.818 C -3.429,35.304 0,36.87 0,39.734 v 0.817 c 0,1.834 1.486,3.32 3.319,3.32 z"
style="fill:none;stroke:#3b3735;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path24" />
</g>
<g
id="g26"
transform="translate(325.7568,314.3716)">
<path
d="m 0,0 c 0,18.581 -10.659,29.592 -24.497,29.592 -12.341,0 -26.179,-7.399 -26.179,-29.764 0,-22.021 14.025,-30.279 25.432,-30.279 C -11.033,-30.451 0,-19.957 0,0 m -50.676,38.597 c 0,-2.85 3.367,-4.388 5.499,-2.495 5.86,5.202 13.751,8.285 23.673,8.285 25.431,0 40.391,-19.097 40.391,-44.215 0,-25.978 -15.708,-45.419 -40.765,-45.419 -9.372,0 -17.28,2.888 -23.33,8.232 -2.121,1.873 -5.468,0.301 -5.468,-2.528 v -34.556 c 0,-1.833 -1.486,-3.319 -3.32,-3.319 h -11.686 c -1.834,0 -3.319,1.486 -3.319,3.319 V 39.863 c 0,1.834 1.485,3.32 3.319,3.32 h 11.686 c 1.834,0 3.32,-1.486 3.32,-3.32 z"
style="fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path28" />
</g>
<g
id="g30"
transform="translate(325.7568,314.3716)">
<path
d="m 0,0 c 0,18.581 -10.659,29.592 -24.497,29.592 -12.341,0 -26.179,-7.399 -26.179,-29.764 0,-22.021 14.025,-30.279 25.432,-30.279 C -11.033,-30.451 0,-19.957 0,0 Z m -50.676,38.597 c 0,-2.85 3.367,-4.388 5.499,-2.495 5.86,5.202 13.751,8.285 23.673,8.285 25.431,0 40.391,-19.097 40.391,-44.215 0,-25.978 -15.708,-45.419 -40.765,-45.419 -9.372,0 -17.28,2.888 -23.33,8.232 -2.121,1.873 -5.468,0.301 -5.468,-2.528 v -34.556 c 0,-1.833 -1.486,-3.319 -3.32,-3.319 h -11.686 c -1.834,0 -3.319,1.486 -3.319,3.319 V 39.863 c 0,1.834 1.485,3.32 3.319,3.32 h 11.686 c 1.834,0 3.32,-1.486 3.32,-3.32 z"
style="fill:none;stroke:#3b3735;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path32" />
</g>
<g
id="g34"
transform="translate(422.8999,270.3291)">
<path
d="m 0,0 h -12.5 c -1.125,0 -2.173,0.569 -2.785,1.513 l -17.064,26.305 c -1.289,1.989 -4.187,2.024 -5.525,0.068 L -55.951,1.445 C -56.569,0.541 -57.595,0 -58.691,0 h -11.917 c -2.715,0 -4.282,3.08 -2.683,5.274 l 27.106,37.191 c 0.837,1.148 0.85,2.703 0.031,3.866 l -25.24,35.836 c -1.549,2.199 0.024,5.23 2.714,5.23 h 12.548 c 1.128,0 2.18,-0.573 2.791,-1.522 l 16.089,-24.997 c 1.297,-2.015 4.236,-2.033 5.559,-0.035 l 16.591,25.067 c 0.615,0.929 1.655,1.487 2.769,1.487 H -0.09 c 2.717,0 4.283,-3.086 2.678,-5.279 l -26.32,-35.966 c -0.846,-1.156 -0.855,-2.725 -0.022,-3.89 L 2.7,5.249 C 4.271,3.053 2.7,0 0,0"
style="fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path36" />
</g>
<g
id="g38"
transform="translate(422.8999,270.3291)">
<path
d="m 0,0 h -12.5 c -1.125,0 -2.173,0.569 -2.785,1.513 l -17.064,26.305 c -1.289,1.989 -4.187,2.024 -5.525,0.068 L -55.951,1.445 C -56.569,0.541 -57.595,0 -58.691,0 h -11.917 c -2.715,0 -4.282,3.08 -2.683,5.274 l 27.106,37.191 c 0.837,1.148 0.85,2.703 0.031,3.866 l -25.24,35.836 c -1.549,2.199 0.024,5.23 2.714,5.23 h 12.548 c 1.128,0 2.18,-0.573 2.791,-1.522 l 16.089,-24.997 c 1.297,-2.015 4.236,-2.033 5.559,-0.035 l 16.591,25.067 c 0.615,0.929 1.655,1.487 2.769,1.487 H -0.09 c 2.717,0 4.283,-3.086 2.678,-5.279 l -26.32,-35.966 c -0.846,-1.156 -0.855,-2.725 -0.022,-3.89 L 2.7,5.249 C 4.271,3.053 2.7,0 0,0 Z"
style="fill:none;stroke:#3b3735;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path40" />
</g>
<g
id="g42"
transform="translate(653.999,347.6792)">
<path
d="m 0,0 c 0,-1.817 -1.458,-3.296 -3.274,-3.318 -4.091,-0.051 -11.165,-0.129 -16.198,-0.129 -7.328,0 -11.601,-4.129 -11.601,-9.979 0,-7.742 7.785,-10.839 15.877,-14.968 9.923,-4.989 19.235,-11.354 19.235,-24.945 0,-15.828 -10.686,-24.947 -27.174,-24.947 -8.079,0 -15.698,0.308 -20.764,2.186 -1.293,0.479 -2.136,1.728 -2.136,3.107 v 8.33 c 0,2.353 2.387,3.979 4.558,3.075 5.266,-2.194 11.511,-2.934 17.579,-2.934 8.243,0 12.518,4.129 12.518,9.979 0,7.914 -7.176,11.182 -16.946,15.828 -8.855,4.129 -18.167,10.665 -18.167,24.773 0,15.828 12.06,24.602 26.716,24.602 7.286,0 10.416,-0.255 16.672,-0.663 C -1.36,9.883 0,8.434 0,6.685 Z"
style="fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path44" />
</g>
<g
id="g46"
transform="translate(653.999,347.6792)">
<path
d="m 0,0 c 0,-1.817 -1.458,-3.296 -3.274,-3.318 -4.091,-0.051 -11.165,-0.129 -16.198,-0.129 -7.328,0 -11.601,-4.129 -11.601,-9.979 0,-7.742 7.785,-10.839 15.877,-14.968 9.923,-4.989 19.235,-11.354 19.235,-24.945 0,-15.828 -10.686,-24.947 -27.174,-24.947 -8.079,0 -15.698,0.308 -20.764,2.186 -1.293,0.479 -2.136,1.728 -2.136,3.107 v 8.33 c 0,2.353 2.387,3.979 4.558,3.075 5.266,-2.194 11.511,-2.934 17.579,-2.934 8.243,0 12.518,4.129 12.518,9.979 0,7.914 -7.176,11.182 -16.946,15.828 -8.855,4.129 -18.167,10.665 -18.167,24.773 0,15.828 12.06,24.602 26.716,24.602 7.286,0 10.416,-0.255 16.672,-0.663 C -1.36,9.883 0,8.434 0,6.685 Z"
style="fill:none;stroke:#3b3735;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path48" />
</g>
<g
id="g50"
transform="translate(695.2998,296.4043)">
<path
d="m 0,0 c 0,-8.258 4.488,-12.559 13.09,-12.559 2.787,0 5.79,0.531 8.472,1.51 2.156,0.786 4.43,-0.83 4.43,-3.124 v -7.54 c 0,-1.396 -0.868,-2.652 -2.183,-3.123 -4.047,-1.45 -9.36,-2.175 -12.963,-2.175 -20.383,0 -29.359,9.979 -29.359,27.355 V 44.68 c 0,1.834 -1.486,3.32 -3.319,3.32 h -5.134 c -1.833,0 -3.319,1.486 -3.319,3.319 v 6.436 c 0,1.834 1.486,3.32 3.319,3.32 h 5.134 c 1.833,0 3.319,1.486 3.319,3.319 v 14.694 c 0,1.834 1.487,3.32 3.32,3.32 H -3.319 C -1.486,82.408 0,80.922 0,79.088 V 64.394 c 0,-1.833 1.486,-3.319 3.319,-3.319 h 18.232 c 1.833,0 3.319,-1.486 3.319,-3.32 V 51.319 C 24.87,49.486 23.384,48 21.551,48 H 3.319 C 1.486,48 0,46.514 0,44.68 Z"
style="fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path52" />
</g>
<g
id="g54"
transform="translate(695.2998,296.4043)">
<path
d="m 0,0 c 0,-8.258 4.488,-12.559 13.09,-12.559 2.787,0 5.79,0.531 8.472,1.51 2.156,0.786 4.43,-0.83 4.43,-3.124 v -7.54 c 0,-1.396 -0.868,-2.652 -2.183,-3.123 -4.047,-1.45 -9.36,-2.175 -12.963,-2.175 -20.383,0 -29.359,9.979 -29.359,27.355 V 44.68 c 0,1.834 -1.486,3.32 -3.319,3.32 h -5.134 c -1.833,0 -3.319,1.486 -3.319,3.319 v 6.436 c 0,1.834 1.486,3.32 3.319,3.32 h 5.134 c 1.833,0 3.319,1.486 3.319,3.319 v 14.694 c 0,1.834 1.487,3.32 3.32,3.32 H -3.319 C -1.486,82.408 0,80.922 0,79.088 V 64.394 c 0,-1.833 1.486,-3.319 3.319,-3.319 h 18.232 c 1.833,0 3.319,-1.486 3.319,-3.32 V 51.319 C 24.87,49.486 23.384,48 21.551,48 H 3.319 C 1.486,48 0,46.514 0,44.68 Z"
style="fill:none;stroke:#3b3735;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path56" />
</g>
<g
id="g58"
transform="translate(809.0576,354.1597)">
<path
d="m 0,0 v -80.586 c 0,-1.833 -1.486,-3.32 -3.319,-3.32 h -11.687 c -1.833,0 -3.319,1.487 -3.319,3.32 v 1.383 c 0,2.956 -3.523,4.385 -5.664,2.348 -5.663,-5.389 -13.782,-8.083 -23.882,-8.083 -18.699,0 -30.48,10.667 -30.48,28.731 V 0 c 0,1.833 1.487,3.319 3.32,3.319 h 11.873 c 1.833,0 3.319,-1.486 3.319,-3.319 v -52.078 c 0,-12.214 7.107,-18.409 17.952,-18.409 14.025,0 23.562,9.291 23.562,26.323 V 0 c 0,1.833 1.486,3.319 3.319,3.319 H -3.319 C -1.486,3.319 0,1.833 0,0"
style="fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path60" />
</g>
<g
id="g62"
transform="translate(809.0576,354.1597)">
<path
d="m 0,0 v -80.586 c 0,-1.833 -1.486,-3.32 -3.319,-3.32 h -11.687 c -1.833,0 -3.319,1.487 -3.319,3.32 v 1.383 c 0,2.956 -3.523,4.385 -5.664,2.348 -5.663,-5.389 -13.782,-8.083 -23.882,-8.083 -18.699,0 -30.48,10.667 -30.48,28.731 V 0 c 0,1.833 1.487,3.319 3.32,3.319 h 11.873 c 1.833,0 3.319,-1.486 3.319,-3.319 v -52.078 c 0,-12.214 7.107,-18.409 17.952,-18.409 14.025,0 23.562,9.291 23.562,26.323 V 0 c 0,1.833 1.486,3.319 3.319,3.319 H -3.319 C -1.486,3.319 0,1.833 0,0 Z"
style="fill:none;stroke:#3b3735;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path64" />
</g>
<g
id="g66"
transform="translate(888.3457,314.4683)">
<path
d="m 0,0 c 0,22.021 -14.586,29.42 -25.245,29.42 -13.838,0 -25.244,-10.151 -25.244,-30.795 0,-17.549 10.658,-29.248 24.683,-29.248 C -12.716,-30.623 0,-22.193 0,0 M 18.513,74.101 V -40.895 c 0,-1.833 -1.487,-3.319 -3.32,-3.319 H 3.319 C 1.486,-44.214 0,-42.728 0,-40.895 v 1.189 c 0,2.843 -3.357,4.391 -5.486,2.509 -5.883,-5.202 -13.665,-8.221 -23.499,-8.221 -26.179,0 -40.391,21.161 -40.391,44.386 0,27.699 17.203,45.247 40.765,45.247 9.109,0 17.063,-2.995 23.154,-8.335 C -3.335,34.02 0,35.597 0,38.419 v 35.682 c 0,1.833 1.486,3.319 3.319,3.319 h 11.874 c 1.833,0 3.32,-1.486 3.32,-3.319"
style="fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path68" />
</g>
<g
id="g70"
transform="translate(888.3457,314.4683)">
<path
d="m 0,0 c 0,22.021 -14.586,29.42 -25.245,29.42 -13.838,0 -25.244,-10.151 -25.244,-30.795 0,-17.549 10.658,-29.248 24.683,-29.248 C -12.716,-30.623 0,-22.193 0,0 Z M 18.513,74.101 V -40.895 c 0,-1.833 -1.487,-3.319 -3.32,-3.319 H 3.319 C 1.486,-44.214 0,-42.728 0,-40.895 v 1.189 c 0,2.843 -3.357,4.391 -5.486,2.509 -5.883,-5.202 -13.665,-8.221 -23.499,-8.221 -26.179,0 -40.391,21.161 -40.391,44.386 0,27.699 17.203,45.247 40.765,45.247 9.109,0 17.063,-2.995 23.154,-8.335 C -3.335,34.02 0,35.597 0,38.419 v 35.682 c 0,1.833 1.486,3.319 3.319,3.319 h 11.874 c 1.833,0 3.32,-1.486 3.32,-3.319 z"
style="fill:none;stroke:#3b3735;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path72" />
</g>
<g
id="g74"
transform="translate(941.9541,376.2642)">
<path
d="m 0,0 c 0,-5.522 -4.478,-10 -10,-10 -5.523,0 -10,4.478 -10,10 0,5.523 4.477,10 10,10 C -4.478,10 0,5.523 0,0 m -15.883,-18.785 h 11.874 c 1.833,0 3.32,-1.486 3.32,-3.319 v -80.587 c 0,-1.833 -1.487,-3.319 -3.32,-3.319 h -11.874 c -1.833,0 -3.319,1.486 -3.319,3.319 v 80.587 c 0,1.833 1.486,3.319 3.319,3.319"
style="fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path76" />
</g>
<g
id="g78"
transform="translate(941.9541,376.2642)">
<path
d="m 0,0 c 0,-5.522 -4.478,-10 -10,-10 -5.523,0 -10,4.478 -10,10 0,5.523 4.477,10 10,10 C -4.478,10 0,5.523 0,0 Z m -15.883,-18.785 h 11.874 c 1.833,0 3.32,-1.486 3.32,-3.319 v -80.587 c 0,-1.833 -1.487,-3.319 -3.32,-3.319 h -11.874 c -1.833,0 -3.319,1.486 -3.319,3.319 v 80.587 c 0,1.833 1.486,3.319 3.319,3.319 z"
style="fill:none;stroke:#3b3735;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path80" />
</g>
<g
id="g82"
transform="translate(971.041,313.6084)">
<path
d="m 0,0 c 0,-16.516 9.334,-30.623 25.762,-30.623 17.734,0 25.948,13.936 25.948,30.451 0,16.516 -7.094,30.967 -26.135,30.967 C 8.588,30.795 0,16.344 0,0 m -19.041,-0.516 c 0,25.634 17.361,45.591 44.803,45.591 29.869,0 45.176,-19.957 45.176,-44.903 0,-25.118 -16.054,-45.075 -45.176,-45.075 -28.935,0 -44.803,19.785 -44.803,44.387"
style="fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path84" />
</g>
<g
id="g86"
transform="translate(971.041,313.6084)">
<path
d="m 0,0 c 0,-16.516 9.334,-30.623 25.762,-30.623 17.734,0 25.948,13.936 25.948,30.451 0,16.516 -7.094,30.967 -26.135,30.967 C 8.588,30.795 0,16.344 0,0 Z m -19.041,-0.516 c 0,25.634 17.361,45.591 44.803,45.591 29.869,0 45.176,-19.957 45.176,-44.903 0,-25.118 -16.054,-45.075 -45.176,-45.075 -28.935,0 -44.803,19.785 -44.803,44.387 z"
style="fill:none;stroke:#3b3735;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path88" />
</g>
</g>
</g>
<g
id="g90">
<g
id="g92"
clip-path="url(#clipPath96)">
<g
id="g98"
transform="translate(517.0752,358.501)">
<path
d="m 0,0 c -24.068,0 -43.579,-19.511 -43.579,-43.579 0,-24.067 19.511,-43.578 43.579,-43.578 24.068,0 43.579,19.511 43.579,43.578 C 43.579,-19.511 24.068,0 0,0 m 58.863,-49.872 c -0.325,-3.089 1.209,-6.078 3.896,-7.631 l 6.286,-3.633 c 3.769,-2.177 5.06,-6.997 2.886,-10.767 L 60.44,-91.823 c -2.177,-3.776 -7.004,-5.069 -10.777,-2.888 l -6.265,3.62 c -2.69,1.555 -6.05,1.399 -8.559,-0.432 -3.365,-2.457 -7.001,-4.568 -10.852,-6.28 -2.833,-1.259 -4.645,-4.086 -4.645,-7.188 v -7.252 c 0,-4.356 -3.531,-7.887 -7.886,-7.887 h -22.971 c -4.355,0 -7.885,3.531 -7.885,7.886 v 7.253 c 0,3.102 -1.813,5.929 -4.645,7.188 -3.851,1.712 -7.487,3.823 -10.853,6.28 -2.509,1.831 -5.869,1.987 -8.559,0.432 l -6.277,-3.628 c -3.767,-2.177 -8.584,-0.885 -10.759,2.886 l -11.495,19.928 c -2.175,3.77 -0.885,8.592 2.883,10.768 l 6.287,3.634 c 2.688,1.553 4.222,4.542 3.896,7.631 -0.217,2.059 -0.329,4.148 -0.329,6.264 0,2.116 0.112,4.206 0.329,6.264 0.326,3.089 -1.208,6.078 -3.896,7.631 l -6.285,3.632 c -3.77,2.178 -5.061,6.998 -2.886,10.769 l 11.496,19.929 c 2.175,3.77 6.992,5.062 10.759,2.885 l 6.286,-3.632 c 2.691,-1.555 6.048,-1.389 8.558,0.443 3.364,2.455 6.996,4.563 10.845,6.273 2.832,1.26 4.645,4.086 4.645,7.189 v 7.252 c 0,4.356 3.53,7.887 7.886,7.887 h 22.97 c 4.355,0 7.886,-3.531 7.886,-7.886 v -7.253 c 0,-3.103 1.812,-5.929 4.645,-7.189 3.848,-1.71 7.481,-3.818 10.845,-6.273 2.51,-1.832 5.867,-1.998 8.557,-0.443 l 6.287,3.632 C 53.443,9.679 58.26,8.387 60.435,4.617 L 71.93,-15.312 c 2.175,-3.771 0.884,-8.591 -2.885,-10.769 l -6.286,-3.632 c -2.687,-1.553 -4.221,-4.542 -3.896,-7.631 0.218,-2.058 0.33,-4.148 0.33,-6.264 0,-2.116 -0.112,-4.205 -0.33,-6.264"
style="fill:#d5d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path100" />
</g>
<g
id="g102"
transform="translate(564.8286,389.3633)">
<path
d="m 0,0 -21.424,9.99 -37.041,-79.436 21.423,-9.991 z"
style="fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path104" />
</g>
<g
id="g106"
transform="translate(543.2061,399.4458)">
<path
d="m 0,0 17.2,8.399 4.621,-18.574 z"
style="fill:#3b3735;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path108" />
</g>
<g
id="g110"
transform="translate(469.3218,240.4814)">
<path
d="M 0,0 21.423,-9.99 58.465,69.445 37.042,79.436 Z"
style="fill:#e62d2d;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path112" />
</g>
<g
id="g114"
transform="translate(490.9443,230.3984)">
<path
d="m 0,0 -17.2,-8.398 -4.622,18.574 z"
style="fill:#e62d2d;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path116" />
</g>
<g
id="g118"
transform="translate(533.7656,314.9224)">
<path
d="m 0,0 c 0,-9.218 -7.473,-16.691 -16.69,-16.691 -9.218,0 -16.691,7.473 -16.691,16.691 0,9.218 7.473,16.69 16.691,16.69 C -7.473,16.69 0,9.218 0,0"
style="fill:#d5d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path120" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -1,9 +1,64 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {},
},
plugins: [],
}
import { fontFamily } from "tailwindcss/defaultTheme";
/** @type {import('tailwindcss').Config} */
const config = {
darkMode: ["class"],
content: ["./src/**/*.{html,js,svelte,ts}"],
safelist: ["dark"],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px"
}
},
extend: {
colors: {
border: "hsl(var(--border) / <alpha-value>)",
input: "hsl(var(--input) / <alpha-value>)",
ring: "hsl(var(--ring) / <alpha-value>)",
background: "hsl(var(--background) / <alpha-value>)",
foreground: "hsl(var(--foreground) / <alpha-value>)",
primary: {
DEFAULT: "hsl(var(--primary) / <alpha-value>)",
foreground: "hsl(var(--primary-foreground) / <alpha-value>)"
},
secondary: {
DEFAULT: "hsl(var(--secondary) / <alpha-value>)",
foreground: "hsl(var(--secondary-foreground) / <alpha-value>)"
},
destructive: {
DEFAULT: "hsl(var(--destructive) / <alpha-value>)",
foreground: "hsl(var(--destructive-foreground) / <alpha-value>)"
},
muted: {
DEFAULT: "hsl(var(--muted) / <alpha-value>)",
foreground: "hsl(var(--muted-foreground) / <alpha-value>)"
},
accent: {
DEFAULT: "hsl(var(--accent) / <alpha-value>)",
foreground: "hsl(var(--accent-foreground) / <alpha-value>)"
},
popover: {
DEFAULT: "hsl(var(--popover) / <alpha-value>)",
foreground: "hsl(var(--popover-foreground) / <alpha-value>)"
},
card: {
DEFAULT: "hsl(var(--card) / <alpha-value>)",
foreground: "hsl(var(--card-foreground) / <alpha-value>)"
}
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)"
},
fontFamily: {
sans: [...fontFamily.sans]
}
}
},
};
export default config;