Add /legal-notice and /terms
This commit is contained in:
parent
18d65f5fe4
commit
2c3dcc9c1a
13 changed files with 327 additions and 63 deletions
|
@ -4,7 +4,5 @@
|
|||
|
||||
TODO:
|
||||
- Blog
|
||||
- Projects
|
||||
- Libraries
|
||||
- Legal Notice
|
||||
- Terms
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<div class="text-lg font-bold">
|
||||
{{ link.label }}
|
||||
</div>
|
||||
<div class="opacity-60 -sm:text-sm">
|
||||
<div class="text-gray-400 -sm:text-sm">
|
||||
{{ link.description }}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -34,7 +34,7 @@
|
|||
<script lang="ts">
|
||||
import { Component, ComponentCustomOptions, PropType } from "vue"
|
||||
|
||||
type Link = {
|
||||
export type Link = {
|
||||
label: string
|
||||
description: string
|
||||
iconClasses?: string
|
||||
|
|
53
components/Prose.vue
Normal file
53
components/Prose.vue
Normal file
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<div class="prose">
|
||||
<slot/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.prose {
|
||||
@apply text-light-900 text-lg;
|
||||
|
||||
.intro {
|
||||
@apply text-xl pb-2;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@apply font-bold text-2xl pt-8 pb-4 text-gray-100;
|
||||
}
|
||||
|
||||
a {
|
||||
@apply text-blue-400;
|
||||
}
|
||||
|
||||
ol {
|
||||
@apply list-decimal list-inside space-y-2;
|
||||
|
||||
::marker {
|
||||
@apply text-gray-400;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
@apply list-disc list-inside space-y-1;
|
||||
}
|
||||
|
||||
address, p, ol, ul {
|
||||
@apply max-w-180;
|
||||
}
|
||||
|
||||
address {
|
||||
@apply not-italic;
|
||||
}
|
||||
|
||||
:where(address, p, ol, ul) ~ :where(address, p, ol, ul) {
|
||||
@apply pt-4;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Prose"
|
||||
}
|
||||
</script>
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="w-full max-w-1000px mx-auto">
|
||||
<div class="bg-background bg-opacity-70 backdrop-filter backdrop-blur-sm backdrop-saturate-200 shadow-2xl px-6 py-8 text-light-900 sticky top-0 z-10 flex items-center justify-between">
|
||||
<div class="bg-background bg-opacity-70 backdrop-filter backdrop-blur-sm backdrop-saturate-200 px-6 py-8 text-light-900 sticky top-0 z-10 flex items-center justify-between">
|
||||
<div class="w-0">
|
||||
<router-link :to="backTarget" class="w-8 flex items-center group relative">
|
||||
<ArrowLeftIcon class="text-2xl"/>
|
||||
|
@ -14,7 +14,7 @@
|
|||
</div>
|
||||
<div/>
|
||||
</div>
|
||||
<div class="pt-8 pb-10 px-5">
|
||||
<div class="pt-8 pb-10 px-5" v-bind="$attrs">
|
||||
<slot/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -24,8 +24,9 @@
|
|||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import ArrowLeftIcon from "~icons/ph/arrow-left"
|
||||
import { useMeta } from "#meta"
|
||||
|
||||
export default {
|
||||
name: "TopBarLayout",
|
||||
|
@ -39,6 +40,11 @@
|
|||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
useMeta({
|
||||
title: `${props.title} — Moritz Ruth`
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "nuxi dev",
|
||||
"build": "nuxi build",
|
||||
"build": "NITRO_PRESET=server nuxi build",
|
||||
"start": "node .output/server/index.mjs",
|
||||
"fi": "pnpm i --shamefully-hoist"
|
||||
},
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
},
|
||||
{
|
||||
icon: TwitterIcon,
|
||||
href: "https://twitter.com/moritzruth",
|
||||
href: "https://moritzruth.de/twitter",
|
||||
label: "Twitter",
|
||||
description: "moritzruth"
|
||||
}
|
||||
|
|
115
pages/index.vue
115
pages/index.vue
|
@ -1,56 +1,66 @@
|
|||
<template>
|
||||
<div class="h-100vh w-full max-w-1200px mx-auto flex justify-between -lg:flex-col p-5 sm:p-10">
|
||||
<section class="relative pt-20">
|
||||
<div class="absolute top-60 -left-20 lg:-left-10">
|
||||
<BlurredBlobCanvas
|
||||
:blur="30"
|
||||
:size="300"
|
||||
:randomness="80"
|
||||
:minimum-duration="600"
|
||||
:duration-variation="400"
|
||||
:minimum-opacity="0.2"
|
||||
:opacity-variation="0.5"
|
||||
:colors="['#eb34cf', '#6577fc']"
|
||||
/>
|
||||
</div>
|
||||
<main class="relative max-w-130 p-2 lg:pl-10">
|
||||
<div class="font-extrabold text-3xl sm:text-4xl">
|
||||
Moritz Ruth
|
||||
<div class="h-100vh w-full flex flex-col items-center justify-between">
|
||||
<div class="w-full max-w-1200px flex justify-between -lg:flex-col p-5 sm:p-10">
|
||||
<div class="relative pt-20">
|
||||
<div class="absolute top-60 -left-20 lg:-left-10">
|
||||
<BlurredBlobCanvas
|
||||
:blur="30"
|
||||
:size="300"
|
||||
:randomness="80"
|
||||
:minimum-duration="600"
|
||||
:duration-variation="400"
|
||||
:minimum-opacity="0.2"
|
||||
:opacity-variation="0.5"
|
||||
:colors="['#eb34cf', '#6577fc']"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-lg sm:text-xl font-medium leading-8 pt-5">
|
||||
<p>
|
||||
I’m a freelance
|
||||
<router-link to="/projects" :class="$style.link">software developer</router-link>,
|
||||
graphic design enthusiast and
|
||||
<router-link to="/photography" :class="$style.link">hobby photographer</router-link>
|
||||
from Europe.
|
||||
</p>
|
||||
<XSpacer v="5"/>
|
||||
<p>
|
||||
I primarily focus on
|
||||
Web and Android development,
|
||||
but I also do Backend sometimes.
|
||||
</p>
|
||||
</div>
|
||||
<XSpacer v="10"/>
|
||||
<router-link to="/contact" :class="$style.reachOut">Reach out</router-link>
|
||||
</main>
|
||||
</section>
|
||||
<section class="relative lg:pr-20 pt-20 pb-10 mt-0">
|
||||
<div class="absolute w-full pt-20 flex justify-center">
|
||||
<BlurredBlobCanvas
|
||||
:blur="30"
|
||||
:size="300"
|
||||
:randomness="100"
|
||||
:minimum-duration="3000"
|
||||
:duration-variation="1000"
|
||||
:minimum-opacity="0.4"
|
||||
:opacity-variation="0"
|
||||
:colors="['#eb34cf', '#6577fc']"
|
||||
/>
|
||||
<main class="relative max-w-130 p-2 lg:pl-10">
|
||||
<div class="font-extrabold text-3xl sm:text-4xl">
|
||||
Moritz Ruth
|
||||
</div>
|
||||
<div class="text-lg sm:text-xl font-medium leading-8 pt-5">
|
||||
<p>
|
||||
I’m a freelance
|
||||
<router-link to="/projects" :class="$style.link">software developer</router-link>,
|
||||
graphic design enthusiast and
|
||||
<router-link to="/photography" :class="$style.link">hobby photographer</router-link>
|
||||
from Europe.
|
||||
</p>
|
||||
<XSpacer v="5"/>
|
||||
<p>
|
||||
I primarily focus on
|
||||
Web and Android development,
|
||||
but I also do Backend sometimes.
|
||||
</p>
|
||||
</div>
|
||||
<XSpacer v="10"/>
|
||||
<router-link to="/contact" :class="$style.reachOut">Reach out</router-link>
|
||||
</main>
|
||||
</div>
|
||||
<LinkCardList :links="navigationLinks"/>
|
||||
</section>
|
||||
<div class="relative lg:pr-20 pt-20 pb-8 mt-0">
|
||||
<nav class="absolute w-full pt-20 flex justify-center">
|
||||
<BlurredBlobCanvas
|
||||
:blur="30"
|
||||
:size="300"
|
||||
:randomness="100"
|
||||
:minimum-duration="3000"
|
||||
:duration-variation="1000"
|
||||
:minimum-opacity="0.4"
|
||||
:opacity-variation="0"
|
||||
:colors="['#eb34cf', '#6577fc']"
|
||||
/>
|
||||
</nav>
|
||||
<LinkCardList :links="navigationLinks"/>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="flex justify-center opacity-30 hover:opacity-60 transition duration-400 space-x-4 pb-6">
|
||||
<router-link to="/terms">
|
||||
Terms
|
||||
</router-link>
|
||||
<router-link to="/legal-notice">
|
||||
Legal notice
|
||||
</router-link>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -86,6 +96,7 @@
|
|||
import BlurredBlobCanvas from "../components/BlurredBlobCanvas.vue"
|
||||
import XSpacer from "../components/XSpacer.vue"
|
||||
import LinkCardList from "../components/LinkCardList.vue"
|
||||
import { useMeta } from "#meta"
|
||||
|
||||
const NAVIGATION_LINKS = [
|
||||
{
|
||||
|
@ -123,6 +134,10 @@
|
|||
BlurredBlobCanvas
|
||||
},
|
||||
setup() {
|
||||
useMeta({
|
||||
title: "Moritz Ruth — freelance software developer"
|
||||
})
|
||||
|
||||
return {
|
||||
navigationLinks: NAVIGATION_LINKS
|
||||
}
|
||||
|
|
44
pages/legal-notice.vue
Normal file
44
pages/legal-notice.vue
Normal file
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<TopBarLayout title="Legal notice" back-target="/">
|
||||
<Prose>
|
||||
<section class="intro">
|
||||
<p>
|
||||
This legal notice (Impressum) is a requirement of the German Act for Telemedia Services (Telemediengesetz).
|
||||
</p>
|
||||
<p>
|
||||
The declarations on this page only apply to this website (moritzruth.de) and all websites which reside under subdomains of moritzruth.de.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>
|
||||
Information pursuant to § 5 TMG
|
||||
</h2>
|
||||
<address>
|
||||
Moritz Ruth<br>
|
||||
Zum Galgenberg 19<br>
|
||||
66539 Neunkirchen
|
||||
</address>
|
||||
<p>
|
||||
Email address: <a href="mailto:legal@moritzruth.de">legal@moritzruth.de</a>
|
||||
</p>
|
||||
<p>
|
||||
Matrix: <a href="https://moritzruth.de/matrix">@moritz:moritzruth.de</a>
|
||||
</p>
|
||||
</section>
|
||||
</Prose>
|
||||
</TopBarLayout>
|
||||
</template>
|
||||
|
||||
<style module>
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import TopBarLayout from "../components/TopBarLayout.vue"
|
||||
import Prose from "../components/Prose.vue"
|
||||
|
||||
export default {
|
||||
name: "TermsPage",
|
||||
components: { Prose, TopBarLayout }
|
||||
}
|
||||
</script>
|
|
@ -7,18 +7,18 @@
|
|||
class="flex -lg:space-y-10 lg:space-x-10 -lg:flex-col -lg:items-center"
|
||||
>
|
||||
<img
|
||||
:src="photo.file"
|
||||
:src="`/photography/${photo.file}`"
|
||||
:alt="photo.title"
|
||||
class="w-full lg:max-w-150 max-h-80vh block object-contain"
|
||||
>
|
||||
<div>
|
||||
<div class="uppercase opacity-70 text-sm pt-1">
|
||||
<div class="text-gray-400 text-sm pt-1">
|
||||
{{ photo.date }}
|
||||
</div>
|
||||
<div class="font-bold text-2xl opacity-90">
|
||||
<div class="font-bold text-2xl text-light-500">
|
||||
{{ photo.title }}
|
||||
</div>
|
||||
<div class="opacity-90 max-w-100 space-y-1 pt-4 whitespace-pre-line">
|
||||
<div class="opacity-90 max-w-100 space-y-1 pt-4 whitespace-pre-line text-light-600">
|
||||
{{ photo.description }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
54
pages/projects.vue
Normal file
54
pages/projects.vue
Normal file
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<TopBarLayout back-target="/" title="Projects">
|
||||
<div class="max-w-160 mx-auto">
|
||||
<LinkCardList :links="projects"/>
|
||||
</div>
|
||||
</TopBarLayout>
|
||||
</template>
|
||||
|
||||
<style module>
|
||||
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import TopBarLayout from "../components/TopBarLayout.vue"
|
||||
import ArrowRightIcon from "~icons/ph/arrow-right"
|
||||
import LinkCardList, { Link } from "../components/LinkCardList.vue"
|
||||
|
||||
export default {
|
||||
name: "ProjectsPage",
|
||||
components: { LinkCardList, TopBarLayout, ArrowRightIcon },
|
||||
setup() {
|
||||
const projects: Link[] = [
|
||||
{
|
||||
label: "JamRSS",
|
||||
description: "An RSS reader app for Android, built with Jetpack\u00A0Compose.",
|
||||
href: "https://github.com/moritzruth/JamRSS#jamrss",
|
||||
icon: "🍓"
|
||||
},
|
||||
{
|
||||
label: "Status Page Finder",
|
||||
description: "Enter the name of a service and get a link to its status page.",
|
||||
href: "https://statuspages.moritzruth.de",
|
||||
icon: "🟢"
|
||||
},
|
||||
{
|
||||
label: "License chooser",
|
||||
description: "Helps you choose the license of your next open-source project.",
|
||||
href: "https://licenses.moritzruth.de",
|
||||
icon: "📜"
|
||||
},
|
||||
{
|
||||
label: "node-enttec-open-dmx-usb",
|
||||
description: "A Node.js library for interacting with the Enttec Open DMX USB Interface.",
|
||||
href: "https://github.com/moritzruth/node-enttec-open-dmx-usb",
|
||||
icon: "💡"
|
||||
}
|
||||
]
|
||||
|
||||
return {
|
||||
projects
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
85
pages/terms.vue
Normal file
85
pages/terms.vue
Normal file
|
@ -0,0 +1,85 @@
|
|||
<template>
|
||||
<TopBarLayout title="Terms and Conditions" back-target="/">
|
||||
<Prose>
|
||||
<p class="italic">
|
||||
For now only available in German.
|
||||
</p>
|
||||
<section>
|
||||
<h2>1. Generelles</h2>
|
||||
<ol>
|
||||
<li>Die nachfolgenden Bestimmungen gelten für alle zwischen Moritz Ruth und dem Auftraggeber geschlossenen Verträge.</li>
|
||||
<li>Abweichende, widersprüchliche oder ergänzende Allgemeine Geschäftsbedingungen des Auftraggebers gelten nur nach ausdrücklicher, schriftlicher Zustimmung von Moritz Ruth.</li>
|
||||
<li>Änderungen und Ergänzungen des Vertrags bedürfen der Schriftform, um wirksam zu sein.</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section>
|
||||
<h2>2. Auftragsdurchführung</h2>
|
||||
<ol>
|
||||
<li>Moritz Ruth führt den Auftrag in eigener Verantwortung durch und hat Gestaltungsfreiheit im Rahmen dessen.</li>
|
||||
<li>Handelt es sich um einen Werkvertrag, sind in der Konzeptions- und Entwurfsphase zwei Korrekturschleifen zulässig.</li>
|
||||
<li>Die Mehrkosten durch eventuelle, von der Leistungsbeschreibung im Angebot abweichende Änderungswünsche hat der Auftraggeber zu tragen.</li>
|
||||
<li>Wurde dem Auftraggeber die Fertigstellung einer Werkleistung in Textform mitgeteilt, hat er 14 Tage Zeit, die Abnahme zu verweigern. Tut er dies nicht, gilt die Leistung als abgenommen.</li>
|
||||
<li>Moritz Ruth ist nicht verpflichtet, Quellcode und offene Dateien herauszugeben. Ist dies dennoch gewünscht, so muss es schriftlich vereinbart und gesondert vergütet werden.</li>
|
||||
<li>Moritz Ruth bestimmt den Tätigkeitsort nach freiem Ermessen.</li>
|
||||
<li>Moritz Ruth steht es frei, auch für andere Auftraggeber tätig zu werden.</li>
|
||||
<li>Moritz Ruth unterliegt keinem Weisungs- oder Direktionsrecht des Auftraggebers.</li>
|
||||
<li>Ein sozialversicherungspflichtiges Arbeitsverhältnis wird durch den Vertrag nicht begründet.</li>
|
||||
<li>Moritz Ruth ist es gestattet, den Vertrag auch unter Zuhilfenahme von Erfüllungsgehilfen zu erfüllen.</li>
|
||||
<li>Das Recht zum Rücktritt und Schadensersatz anstelle der ganzen Leistung besteht nur bei erheblichen Mängeln.</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section>
|
||||
<h2>3. Pflichten des Auftraggebers</h2>
|
||||
<ol>
|
||||
<li>Der Auftraggeber ist verpflichtet, Moritz Ruth sämtliche zur Erfüllung des Vertrags erforderlichen Daten und Dateien zur Verfügung zu stellen.</li>
|
||||
<li>Der Auftraggeber ist zum Ersatz von Schäden, die Moritz Ruth durch Schadprogramme in den vom Auftraggeber bereitgestellten Dateien und Daten entstehen, verpflichtet.</li>
|
||||
<li>Das Anfertigen von Sicherungskopien liegt allein in der Verantwortung des Auftraggebers.</li>
|
||||
<li>Ist zur Erfüllung des Auftrags die Mitwirkung des Auftraggebers erforderlich, muss dieser seiner Mitwirkungspflicht innerhalb von 14 Tagen nach Aufforderung durch Moritz Ruth nachkommen. Andernfalls kann Moritz Ruth den Vertrag kündigen. Sein Entschädigungsanspruch nach § 642 BGB bleibt hiervon unberührt.</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section>
|
||||
<h2>4. Vergütung</h2>
|
||||
<ol>
|
||||
<li>Die Vergütung ist sofort zum Zeitpunkt der ordnungsgemäßen Rechnungsstellung fällig.</li>
|
||||
<li>Grundsätzlich gilt eine Zahlungsfrist von 14 Tagen.</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Nutzungsrechte</h2>
|
||||
<ol>
|
||||
<li>Moritz Ruth ist es erlaubt, die im Rahmen des Auftrags entstandenen Ergebnisse zur Selbstdarstellung zu verwenden (z. B. auf einer Website). Zudem darf er den Auftraggeber als Referenz nennen und in diesem Zuge auch dessen Logo verwenden.</li>
|
||||
<li>Moritz Ruth überträgt nur die Nutzungsrechte, die zur Erfüllung des Vertrages erforderlich sind.</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Haftung</h2>
|
||||
<ol>
|
||||
<li>Moritz Ruth haftet dem Auftraggeber gegenüber für die von ihm vorsätzlich oder grob fahrlässig verursachten Schäden sowie bei der Verletzung von Leben, Körper oder Gesundheit.</li>
|
||||
<li>Moritz Ruth haftet nicht bei leichter Fahrlässigkeit, außer es handelt sich um die Verletzung wesentlicher Vertragspflichten nach den gesetzlichen Bestimmungen, wobei wesentliche Vertragspflichten solche sind, deren Erfüllung die ordnungsgemäße Durchführung des Vertrages überhaupt erst ermöglichen und auf deren Einhaltung der Auftraggeber regelmäßig vertrauen darf.</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Schlussbestimmungen</h2>
|
||||
<ol>
|
||||
<li>Erfüllungsort und Gerichtsstand für alle Streitigkeiten aus und im Zusammenhang mit dieser Vereinbarung ist der Sitz von Moritz Ruth, sofern der Auftraggeber Kaufmann, juristische Person des öffentlichen Rechts oder öffentlich-rechtliches Sondervermögen ist.</li>
|
||||
<li>Sollte eine Bestimmung dieser Vereinbarung ganz oder teilweise unwirksam sein oder werden oder sollte die Vereinbarung unvollständig sein, so wird die Vereinbarung im Übrigen Inhalt nicht berührt. Die Vertragspartner verpflichten sich, die unwirksame Bestimmung durch eine solche Bestimmung zu ersetzen, welche dem Sinn und Zweck der unwirksamen Bestimmung in rechtswirksamer Weise wirtschaftlich am nächsten kommt.</li>
|
||||
<li>Es gilt deutsches Recht unter Ausschluss des UN-Kaufrechts.</li>
|
||||
</ol>
|
||||
</section>
|
||||
</Prose>
|
||||
</TopBarLayout>
|
||||
</template>
|
||||
|
||||
<style module>
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import TopBarLayout from "../components/TopBarLayout.vue"
|
||||
import Prose from "../components/Prose.vue"
|
||||
|
||||
export default {
|
||||
name: "TermsPage",
|
||||
components: { Prose, TopBarLayout }
|
||||
}
|
||||
</script>
|
|
@ -1,5 +1,13 @@
|
|||
# Old domain
|
||||
https://moritz-ruth.de/* https://moritzruth.de/:splat 301!
|
||||
|
||||
# External
|
||||
/matrix https://matrix.to/#/@moritz:moritzruth.de
|
||||
/twitter https://twitter.com/moritzruth
|
||||
|
||||
# Internal
|
||||
/agb /terms
|
||||
/kontakt /contact
|
||||
|
||||
# Uses index.html for all paths
|
||||
/* /index.html 200
|
||||
|
|
|
@ -12,6 +12,7 @@ export default defineConfig({
|
|||
yellow: colors.amber,
|
||||
green: colors.green,
|
||||
blue: colors.blue,
|
||||
gray: colors.gray,
|
||||
dark: colors.dark,
|
||||
light: colors.light,
|
||||
background: "#070707"
|
||||
|
|
Loading…
Add table
Reference in a new issue