pages and imprint
This commit is contained in:
@@ -131,6 +131,36 @@
|
||||
{/each}
|
||||
</nav>
|
||||
|
||||
<!-- About / legal links (hidden when collapsed; the pages stay reachable
|
||||
via any expanded sidebar and the signup page footer) -->
|
||||
{#if !collapsed}
|
||||
<div class="px-4 py-3 text-[11px] leading-relaxed text-sidebar-foreground/60">
|
||||
<a
|
||||
class="hover:text-sidebar-foreground hover:underline"
|
||||
href={resolve('/about')}
|
||||
onclick={onMobileClose}>About</a
|
||||
>
|
||||
<span aria-hidden="true"> · </span>
|
||||
<a
|
||||
class="hover:text-sidebar-foreground hover:underline"
|
||||
href={resolve('/legal/imprint')}
|
||||
onclick={onMobileClose}>Imprint</a
|
||||
>
|
||||
<span aria-hidden="true"> · </span>
|
||||
<a
|
||||
class="hover:text-sidebar-foreground hover:underline"
|
||||
href={resolve('/legal/privacy')}
|
||||
onclick={onMobileClose}>Privacy</a
|
||||
>
|
||||
<span aria-hidden="true"> · </span>
|
||||
<a
|
||||
class="hover:text-sidebar-foreground hover:underline"
|
||||
href={resolve('/legal/terms')}
|
||||
onclick={onMobileClose}>Terms</a
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Collapse toggle (desktop sidebar only; the mobile drawer omits onToggle) -->
|
||||
{#if onToggle}
|
||||
<div class="border-t border-sidebar-border px-2 py-3">
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
/** Optional muted line under the title (e.g. "Last updated ..."). */
|
||||
subtitle?: string;
|
||||
children: Snippet;
|
||||
}
|
||||
|
||||
let { title, subtitle, children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{title} · Drizz.li</title>
|
||||
</svelte:head>
|
||||
|
||||
<article class="mx-auto max-w-3xl py-2 lg:py-4">
|
||||
<h1 class="text-2xl font-bold tracking-tight lg:text-3xl">{title}</h1>
|
||||
{#if subtitle}
|
||||
<p class="mt-1.5 text-sm text-muted-foreground">{subtitle}</p>
|
||||
{/if}
|
||||
<div class="prose-body mt-6">
|
||||
{@render children()}
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<style>
|
||||
/* Lightweight typography for long-form pages (about / legal), themed with the
|
||||
app tokens so it reads correctly in light and dark. */
|
||||
.prose-body {
|
||||
line-height: 1.65;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.prose-body :global(h2) {
|
||||
margin: 2rem 0 0.6rem;
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
.prose-body :global(h3) {
|
||||
margin: 1.4rem 0 0.4rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.prose-body :global(p) {
|
||||
margin: 0.6rem 0;
|
||||
}
|
||||
.prose-body :global(ul) {
|
||||
margin: 0.6rem 0;
|
||||
padding-left: 1.4rem;
|
||||
}
|
||||
.prose-body :global(li) {
|
||||
margin: 0.25rem 0;
|
||||
}
|
||||
.prose-body :global(a) {
|
||||
color: var(--primary);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
.prose-body :global(strong) {
|
||||
font-weight: 600;
|
||||
}
|
||||
.prose-body :global(address) {
|
||||
font-style: normal;
|
||||
margin: 0.6rem 0;
|
||||
padding: 0.8rem 1rem;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 0.625rem;
|
||||
background: var(--card);
|
||||
}
|
||||
.prose-body :global(hr) {
|
||||
margin: 2rem 0;
|
||||
border: 0;
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
</style>
|
||||
@@ -52,9 +52,10 @@
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-bold tracking-tight">{feature} is a premium feature</h2>
|
||||
<h2 class="text-xl font-bold tracking-tight">{feature} is a supporter extra</h2>
|
||||
<p class="mx-auto mt-1.5 max-w-sm text-sm text-muted-foreground">
|
||||
Support this open-source weather project and unlock the extras from {price}.
|
||||
Drizz.li is free and open source. Chip in from {price} to keep it running - as a thank-you, supporters
|
||||
unlock the extras.
|
||||
</p>
|
||||
|
||||
<ul class="mx-auto mt-5 grid max-w-sm gap-2 text-left">
|
||||
@@ -81,7 +82,7 @@
|
||||
rel="noopener"
|
||||
class="inline-flex h-10 w-full items-center justify-center rounded-lg bg-primary px-5 text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/90 sm:w-auto"
|
||||
>
|
||||
Subscribe
|
||||
Become a supporter
|
||||
</a>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
? 'border-amber-400/50 bg-amber-400/10 text-amber-700 hover:bg-amber-400/20 dark:text-amber-300'
|
||||
: 'border-border/70 text-muted-foreground hover:bg-muted hover:text-foreground'}"
|
||||
onclick={() => (open = true)}
|
||||
title={$isPremium ? 'Premium active' : 'Unlock premium'}
|
||||
aria-label={$isPremium ? 'Premium active' : 'Unlock premium'}
|
||||
title={$isPremium ? 'Supporter extras active' : 'Support Drizz.li'}
|
||||
aria-label={$isPremium ? 'Supporter extras active' : 'Support Drizz.li'}
|
||||
>
|
||||
{#if $isPremium}
|
||||
<!-- star -->
|
||||
|
||||
@@ -60,9 +60,9 @@
|
||||
<Dialog.Root bind:open>
|
||||
<Dialog.Content class="sm:max-w-md">
|
||||
<Dialog.Header>
|
||||
<Dialog.Title>Drizz.li Premium</Dialog.Title>
|
||||
<Dialog.Title>Drizz.li Supporter</Dialog.Title>
|
||||
<Dialog.Description>
|
||||
Paste the access key from your subscription email to unlock premium pages.
|
||||
Paste the access key from your supporter email to unlock the extras.
|
||||
</Dialog.Description>
|
||||
</Dialog.Header>
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
rel="noopener"
|
||||
class="font-semibold text-primary underline-offset-2 hover:underline"
|
||||
>
|
||||
Subscribe from {price}
|
||||
Support the project from {price}
|
||||
</a>
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
@@ -13,7 +13,7 @@ const stripTrailingSlash = (url: string): string => url.replace(/\/+$/, '');
|
||||
|
||||
/** Base URL of the self-hosted verify API (drizzli-paywall). */
|
||||
export const PAYWALL_API_BASE = stripTrailingSlash(
|
||||
env.VITE_PAYWALL_API_BASE ?? 'https://paywall.drizz.li'
|
||||
env.VITE_PAYWALL_API_BASE ?? 'https://support.drizz.li'
|
||||
);
|
||||
|
||||
/** Where prospective subscribers go to sign up (the paywall repo's signup form). */
|
||||
@@ -60,8 +60,8 @@ export function getPremiumPrice(): string {
|
||||
return currency === 'CHF' ? `${symbol} 3 / month` : `${symbol}3 / month`;
|
||||
}
|
||||
|
||||
/** Short, human list of what premium unlocks (shown on the locked panel). */
|
||||
/** Short, human list of what supporting unlocks (shown on the locked panel). */
|
||||
export const PREMIUM_PERKS = [
|
||||
'Historical weather & climate-normal comparisons',
|
||||
'New premium features as they land'
|
||||
'New supporter extras as they land'
|
||||
];
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<script lang="ts">
|
||||
import ProsePage from '$lib/components/prose-page.svelte';
|
||||
</script>
|
||||
|
||||
<ProsePage title="About Drizz.li" subtitle="A small, open-source weather site.">
|
||||
<p>
|
||||
Drizz.li is an independent weather site. It shows multi-model forecasts, model comparisons,
|
||||
14-day outlooks, weather maps and historical weather - without accounts, ads or trackers.
|
||||
</p>
|
||||
|
||||
<h2>How it works</h2>
|
||||
<p>
|
||||
All weather data comes from the excellent open-data APIs of
|
||||
<a href="https://open-meteo.com" target="_blank" rel="noopener">Open-Meteo</a>, which aggregates
|
||||
national weather services (DWD, NOAA, Météo-France, MeteoSwiss and more). Drizz.li is a static
|
||||
site: forecasts are fetched directly by your browser and rendered on your device.
|
||||
</p>
|
||||
<p>
|
||||
The site is open source. Anyone can read the code, report issues or contribute improvements.
|
||||
</p>
|
||||
|
||||
<h2>Supporting the project</h2>
|
||||
<p>
|
||||
Drizz.li is free to use. If you find it useful, you can support it with a small monthly
|
||||
contribution (from €3 / month) - it helps cover the domain, hosting and development time. As a
|
||||
thank-you, supporters unlock the extras: historical weather with climate-normal comparisons, and
|
||||
new supporter features as they land.
|
||||
</p>
|
||||
<p>
|
||||
Contributions are handled by a simple bank transfer - no payment processor, no stored card
|
||||
details. The details of how that works are in the
|
||||
<a href="/legal/terms/">supporter terms</a> and the
|
||||
<a href="/legal/privacy/">privacy policy</a>.
|
||||
</p>
|
||||
|
||||
<h2>Contact</h2>
|
||||
<p>
|
||||
Questions, feedback or bug reports:
|
||||
<a href="mailto:drizzli@vincentvanderwal.nl">drizzli@vincentvanderwal.nl</a>
|
||||
</p>
|
||||
</ProsePage>
|
||||
@@ -0,0 +1,36 @@
|
||||
<script lang="ts">
|
||||
import ProsePage from '$lib/components/prose-page.svelte';
|
||||
</script>
|
||||
|
||||
<!-- TODO(vincent): replace the [bracketed] placeholders with your real postal
|
||||
address and country before deploying. An imprint without a serviceable
|
||||
address does not satisfy the imprint/contact requirements. -->
|
||||
<ProsePage title="Imprint" subtitle="Legal notice / provider identification.">
|
||||
<h2>Service provider</h2>
|
||||
<address>
|
||||
Vincent van der Wal<br />
|
||||
[Street and number]<br />
|
||||
[Postal code, City]<br />
|
||||
[Country]
|
||||
</address>
|
||||
<p>
|
||||
Email: <a href="mailto:drizzli@vincentvanderwal.nl">drizzli@vincentvanderwal.nl</a>
|
||||
</p>
|
||||
<p>
|
||||
Drizz.li is operated as a personal, independent project. Responsible for the content of this
|
||||
website: Vincent van der Wal (address above).
|
||||
</p>
|
||||
|
||||
<h2>Disclaimer</h2>
|
||||
<p>
|
||||
Weather data shown on this site is provided for general information only. Forecasts are
|
||||
inherently uncertain; do not rely on them where life, health or property is at stake - consult
|
||||
official warnings from your national weather service instead.
|
||||
</p>
|
||||
<p>
|
||||
Weather and geodata are retrieved from
|
||||
<a href="https://open-meteo.com" target="_blank" rel="noopener">Open-Meteo</a>, which is not
|
||||
affiliated with this site. External links are provided in good faith; their content is the
|
||||
responsibility of the respective operators.
|
||||
</p>
|
||||
</ProsePage>
|
||||
@@ -0,0 +1,146 @@
|
||||
<script lang="ts">
|
||||
import ProsePage from '$lib/components/prose-page.svelte';
|
||||
</script>
|
||||
|
||||
<!-- TODO(vincent): fill in the [bracketed] placeholders (address, hosting
|
||||
provider, supervisory authority) before deploying. -->
|
||||
<ProsePage title="Privacy policy" subtitle="Last updated: 1 August 2026">
|
||||
<p>
|
||||
Drizz.li is built to need as little of your data as possible: there are no user accounts, no
|
||||
cookies, no advertising and no analytics or tracking scripts. This page explains what little
|
||||
processing does happen - when you browse the site, and when you support the project with a
|
||||
contribution.
|
||||
</p>
|
||||
|
||||
<h2>1. Controller</h2>
|
||||
<address>
|
||||
Vincent van der Wal<br />
|
||||
[Street and number], [Postal code, City], [Country]<br />
|
||||
Email: <a href="mailto:drizzli@vincentvanderwal.nl">drizzli@vincentvanderwal.nl</a>
|
||||
</address>
|
||||
<p>
|
||||
This policy covers the websites drizz.li (the weather app) and support.drizz.li (the supporter
|
||||
signup page).
|
||||
</p>
|
||||
|
||||
<h2>2. Browsing the site</h2>
|
||||
<h3>Weather data requests</h3>
|
||||
<p>
|
||||
Drizz.li is a static site: when you open a forecast, your browser fetches the weather data
|
||||
directly from the open-data APIs of
|
||||
<a href="https://open-meteo.com" target="_blank" rel="noopener">Open-Meteo</a>
|
||||
(api.open-meteo.com, geocoding-api.open-meteo.com, archive-api.open-meteo.com, ensemble-api.open-meteo.com,
|
||||
and map tiles from maps.open-meteo.com / map-tiles.open-meteo.com / map-assets.open-meteo.com). Like
|
||||
any web request, this transmits your IP address and the requested location or search term to Open-Meteo.
|
||||
We do not receive or store any of this. See
|
||||
<a href="https://open-meteo.com/en/terms" target="_blank" rel="noopener"
|
||||
>Open-Meteo's terms and privacy information</a
|
||||
>. Legal basis: our legitimate interest in delivering the content you request (Art. 6(1)(f)
|
||||
GDPR).
|
||||
</p>
|
||||
<h3>Hosting</h3>
|
||||
<p>
|
||||
The static site is served by [hosting provider, location]. The hosting infrastructure may keep
|
||||
short-lived technical server logs (IP address, requested URL, timestamp) for security and
|
||||
operations. Legal basis: legitimate interest in a secure, reliable service (Art. 6(1)(f) GDPR).
|
||||
</p>
|
||||
<h3>Settings on your device (local storage)</h3>
|
||||
<p>
|
||||
Your preferences - theme, measurement units, last searched location, and (for supporters) your
|
||||
access key and its last verification result - are stored only in your browser's local storage.
|
||||
They never leave your device except as described below for key verification, and you can clear
|
||||
them at any time via your browser.
|
||||
</p>
|
||||
|
||||
<h2>3. Supporting the project (contributions)</h2>
|
||||
<p>
|
||||
Supporter contributions unlock the supporter extras, so legally they are a paid agreement, not a
|
||||
pure gift - and this is what we process to handle them:
|
||||
</p>
|
||||
<h3>Signup form</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Email address</strong> (required) - to send you the transfer details and, after your contribution
|
||||
arrives, your access key.
|
||||
</li>
|
||||
<li><strong>Name</strong> (optional) - to help match your bank transfer.</li>
|
||||
<li>
|
||||
<strong>Currency and amount</strong> - shown based on your browser's locale/timezone, detected on
|
||||
your device (no geolocation request is made).
|
||||
</li>
|
||||
<li>
|
||||
<strong>IP address and technical anti-bot signals</strong> - kept with the signup request to prevent
|
||||
abuse and spam of the form.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Payment reference</strong> (e.g. DRZ-XXXXXX) - generated per request to match your transfer
|
||||
to your signup.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
The transfer details (bank account and reference) are sent to you by email rather than shown on
|
||||
the page. Legal bases: performance of the agreement (Art. 6(1)(b) GDPR) and, for the anti-abuse
|
||||
measures, legitimate interest (Art. 6(1)(f) GDPR).
|
||||
</p>
|
||||
<h3>Bank transfer</h3>
|
||||
<p>
|
||||
Contributions are paid by ordinary bank transfer. Your bank and ours process the transfer data
|
||||
under their own responsibility; on our bank statement we see the usual transfer details (your
|
||||
name, account number, amount, reference). We use them only to match your contribution and are
|
||||
required to retain accounting records under statutory bookkeeping and tax law (Art. 6(1)(c)
|
||||
GDPR).
|
||||
</p>
|
||||
<h3>Access key and verification</h3>
|
||||
<p>
|
||||
After your transfer is matched (manually, usually within 24 hours), you receive an access key by
|
||||
email. When you paste it into Drizz.li, your browser sends the key to our verification endpoint
|
||||
(support.drizz.li) to check whether it is active; the response contains only the validity, tier
|
||||
and expiry. The subscriber list (key, email, expiry) is stored on our server for as long as your
|
||||
access is active.
|
||||
</p>
|
||||
<h3>Email</h3>
|
||||
<p>
|
||||
Transactional emails (transfer details, access key, renewals) are sent through our email
|
||||
provider, Strato (Strato AG, Germany), acting as a processor. We send no newsletters or
|
||||
marketing email.
|
||||
</p>
|
||||
|
||||
<h2>4. Retention</h2>
|
||||
<ul>
|
||||
<li>Signup requests that are never paid are deleted after 6 months at the latest.</li>
|
||||
<li>
|
||||
Supporter records (key, email, expiry) are kept while your access is active and deleted within
|
||||
12 months after it expires, unless you ask us to delete them sooner.
|
||||
</li>
|
||||
<li>
|
||||
Accounting records (bank statements showing your transfer) are kept for the statutory
|
||||
retention period (up to 10 years, depending on jurisdiction).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>5. Recipients</h2>
|
||||
<p>
|
||||
We do not sell or share personal data with third parties for their own purposes. Recipients are
|
||||
limited to: Open-Meteo (weather requests made directly by your browser), our hosting provider,
|
||||
our email provider (Strato), and the banks involved in your transfer.
|
||||
</p>
|
||||
|
||||
<h2>6. Your rights</h2>
|
||||
<p>
|
||||
Under the GDPR you have the right to access, rectification, erasure, restriction of processing,
|
||||
data portability, and to object to processing based on legitimate interest. Where processing is
|
||||
based on consent, you may withdraw it at any time. To exercise any of these rights, email
|
||||
<a href="mailto:drizzli@vincentvanderwal.nl">drizzli@vincentvanderwal.nl</a>. You also have the
|
||||
right to lodge a complaint with a supervisory authority, in particular in the EU member state of
|
||||
your residence, or with [competent supervisory authority of the controller].
|
||||
</p>
|
||||
<p>
|
||||
For visitors from Switzerland: the corresponding rights under the Swiss Federal Act on Data
|
||||
Protection (FADP) apply equivalently.
|
||||
</p>
|
||||
|
||||
<h2>7. Changes</h2>
|
||||
<p>
|
||||
We may update this policy when the service changes; the date above reflects the latest revision.
|
||||
</p>
|
||||
</ProsePage>
|
||||
@@ -0,0 +1,84 @@
|
||||
<script lang="ts">
|
||||
import ProsePage from '$lib/components/prose-page.svelte';
|
||||
</script>
|
||||
|
||||
<!-- TODO(vincent): confirm the governing-law country in section 8. -->
|
||||
<ProsePage title="Supporter terms" subtitle="Last updated: 1 August 2026">
|
||||
<p>
|
||||
Drizz.li is free to use. These terms cover the optional supporter contribution: a small payment
|
||||
that helps keep the project running and, as a thank-you, unlocks the supporter extras. Although
|
||||
we call it a contribution, features are unlocked in return - so legally it is a paid agreement
|
||||
between you and the provider named in the
|
||||
<a href="/legal/imprint/">imprint</a>, and consumer protection rules apply to it.
|
||||
</p>
|
||||
|
||||
<h2>1. What you get</h2>
|
||||
<p>
|
||||
A supporter contribution unlocks the supporter extras for the paid period: currently historical
|
||||
weather with climate-normal comparisons, plus new supporter features as they land. The free
|
||||
parts of Drizz.li stay free for everyone.
|
||||
</p>
|
||||
|
||||
<h2>2. How it works</h2>
|
||||
<ul>
|
||||
<li>
|
||||
You request the transfer details on the signup page; we email them to you together with a
|
||||
personal payment reference.
|
||||
</li>
|
||||
<li>
|
||||
You transfer the amount (from €3 / $3 / CHF 3 per month) by ordinary bank transfer, including
|
||||
the reference.
|
||||
</li>
|
||||
<li>
|
||||
Transfers are matched manually. Once your contribution arrives - usually within 24 hours, at
|
||||
most a few days - you receive a personal access key by email.
|
||||
</li>
|
||||
<li>
|
||||
You paste the key into Drizz.li once; it is stored on your device and verified automatically.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>3. No auto-renewal</h2>
|
||||
<p>
|
||||
Contributions are one-off and prepaid: nothing renews automatically and we never charge you.
|
||||
When your period ends, the extras simply lock again; contributing again with the same email
|
||||
extends your existing key.
|
||||
</p>
|
||||
|
||||
<h2>4. Withdrawal and refunds</h2>
|
||||
<p>
|
||||
If you are a consumer in the EU/EEA, you have a statutory 14-day right of withdrawal. Beyond
|
||||
that, we keep it simple: if you are unhappy for any reason within 14 days of receiving your
|
||||
access key, email
|
||||
<a href="mailto:drizzli@vincentvanderwal.nl">drizzli@vincentvanderwal.nl</a> and we will refund your
|
||||
contribution in full.
|
||||
</p>
|
||||
|
||||
<h2>5. Fair use</h2>
|
||||
<p>
|
||||
The access key is personal. Please don't publish or share it; keys that are clearly abused (e.g.
|
||||
shared publicly) may be revoked. If your key is revoked without cause, you are entitled to a
|
||||
pro-rata refund.
|
||||
</p>
|
||||
|
||||
<h2>6. Service and availability</h2>
|
||||
<p>
|
||||
Drizz.li is a personal open-source project, provided as-is. We work to keep it available and
|
||||
accurate, but we cannot guarantee uninterrupted availability or the correctness of forecasts -
|
||||
weather data is informational only (see the disclaimer in the imprint). If the supporter extras
|
||||
become permanently unavailable during a period you paid for, we will refund the remaining period
|
||||
on request.
|
||||
</p>
|
||||
|
||||
<h2>7. Data</h2>
|
||||
<p>
|
||||
How we handle your data (email, payment reference, bank transfer details) is described in the
|
||||
<a href="/legal/privacy/">privacy policy</a>.
|
||||
</p>
|
||||
|
||||
<h2>8. Governing law</h2>
|
||||
<p>
|
||||
These terms are governed by the law of [Switzerland], without prejudice to mandatory consumer
|
||||
protection provisions of your country of residence.
|
||||
</p>
|
||||
</ProsePage>
|
||||
Reference in New Issue
Block a user