This commit is contained in:
Felix Klement committed 2026-09-18 16:04:05 +02:00
commit 4cda1ca41b
72 files changed
+8169

No files matched your search

+4
View File
@@ -0,0 +1,4 @@
---
import NotFound from './_NotFound.astro';
---
<NotFound lang="en" />
+28
View File
@@ -0,0 +1,28 @@
---
import Base from '../layouts/Base.astro';
import Hero from '../components/home/Hero.astro';
import Manifesto from '../components/home/Manifesto.astro';
import Method from '../components/home/Method.astro';
import Stages from '../components/home/Stages.astro';
import Sectors from '../components/home/Sectors.astro';
import Proof from '../components/home/Proof.astro';
import Quote from '../components/home/Quote.astro';
import Insights from '../components/home/Insights.astro';
import Contact from '../components/home/Contact.astro';
import { t, type Lang } from '../i18n/ui';
interface Props { lang: Lang }
const { lang } = Astro.props;
const ui = t(lang);
---
<Base lang={lang} title={ui.meta.home.title} description={ui.meta.home.description}>
<Hero lang={lang} />
<Manifesto lang={lang} />
<Method lang={lang} />
<Stages lang={lang} />
<Sectors lang={lang} />
<Proof lang={lang} />
<Quote lang={lang} />
<Insights lang={lang} />
<Contact lang={lang} />
</Base>
+80
View File
@@ -0,0 +1,80 @@
---
import { getCollection } from 'astro:content';
import { Picture } from 'astro:assets';
import Base from '../layouts/Base.astro';
import { formatDate, localePath, t, type Lang } from '../i18n/ui';
interface Props { lang: Lang }
const { lang } = Astro.props;
const ui = t(lang);
const posts = (await getCollection('insights')).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
---
<Base lang={lang} title={ui.meta.insights.title} description={ui.meta.insights.description}>
<section class="section section--intro">
<div class="container grid">
<h1 class="display index__title">{ui.insights.title}</h1>
<p class="index__lead">{ui.insights.intro}</p>
</div>
</section>
<section class="section--list" aria-label={ui.insights.title}>
<div class="container">
<ul class="posts" role="list">
{posts.map((post) => (
<li class="post">
<a class="post__link" href={localePath(lang, `/insights/${post.id}`)} lang={post.data.lang !== lang ? post.data.lang : undefined}>
<div class="post__media">
<Picture
src={post.data.cover}
alt={post.data.coverAlt}
formats={['avif']}
fallbackFormat="webp"
widths={[400, 640, 960]}
sizes="(min-width: 48rem) 40vw, 100vw"
loading="lazy"
decoding="async"
class="post__img img-doc"
/>
</div>
<div class="post__text">
<p class="small muted post__meta">
<span>{post.data.category}</span>
<time datetime={post.data.date.toISOString().slice(0, 10)}>{formatDate(post.data.date, lang)}</time>
<span>{ui.insights.readingTime(post.data.readingTime)}</span>
</p>
<h2 class="h2">{post.data.title}</h2>
{post.data.subtitle && <p class="muted">{post.data.subtitle}</p>}
{post.data.lang !== lang && <p class="small muted">{ui.insights.inEnglish}</p>}
</div>
</a>
</li>
))}
</ul>
</div>
</section>
</Base>
<style>
.index__title { grid-column: 1 / -1; }
.index__lead { grid-column: 1 / -1; max-width: var(--measure); color: var(--ink-muted); }
@media (min-width: 48rem) {
.index__title { grid-column: 1 / span 8; }
.index__lead { grid-column: 1 / span 5; }
}
.section--list { padding-bottom: var(--section); }
.posts { border-top: var(--hairline) solid var(--line); }
.post { border-bottom: var(--hairline) solid var(--line); }
.post__link {
display: grid;
gap: var(--space-5) var(--gap);
padding-block: var(--space-7);
text-decoration: none;
}
.post__link:hover h2 { text-decoration: underline; text-decoration-thickness: var(--hairline); text-underline-offset: 0.12em; }
.post__img, :global(.post__img) { width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; }
.post__text { display: grid; gap: var(--space-4); align-content: start; }
.post__meta { display: flex; flex-wrap: wrap; gap: var(--space-4); }
@media (min-width: 48rem) {
.post__link { grid-template-columns: 5fr 7fr; }
}
</style>
+35
View File
@@ -0,0 +1,35 @@
---
import Base from '../layouts/Base.astro';
import type { Lang } from '../i18n/ui';
interface Props { lang: Lang; title: string; description: string; eyebrow?: string; lead?: string }
const { lang, title, description, eyebrow, lead } = Astro.props;
---
<Base lang={lang} title={title} description={description}>
<section class="section">
<div class="container grid">
<div class="legal__head">
{eyebrow && <p class="eyebrow">{eyebrow}</p>}
<h1 class="h2">{title}</h1>
{lead && <p class="muted legal__lead">{lead}</p>}
</div>
<div class="prose legal__body">
<slot />
</div>
</div>
</section>
</Base>
<style>
.legal__head { grid-column: 1 / -1; display: grid; gap: var(--space-4); align-content: start; }
.legal__lead { max-width: var(--measure); }
.legal__body { grid-column: 1 / -1; }
@media (min-width: 48rem) {
.legal__head { grid-column: 1 / span 4; }
.legal__body { grid-column: 6 / span 7; }
}
@media (min-width: 64rem) {
.legal__head { grid-column: 1 / span 4; }
.legal__body { grid-column: 6 / span 6; }
}
</style>
+27
View File
@@ -0,0 +1,27 @@
---
import Base from '../layouts/Base.astro';
import { localePath, t, type Lang } from '../i18n/ui';
interface Props { lang: Lang }
const { lang } = Astro.props;
const ui = t(lang);
---
<Base lang={lang} title={ui.notFound.title} description={ui.notFound.body}>
<section class="section">
<div class="container grid">
<h1 class="display nf__title">{ui.notFound.title}</h1>
<div class="nf__body">
<p class="muted">{ui.notFound.body}</p>
<a class="link" href={localePath(lang, '/')}>{ui.notFound.link}</a>
</div>
</div>
</section>
</Base>
<style>
.nf__title { grid-column: 1 / -1; }
.nf__body { grid-column: 1 / -1; display: grid; gap: var(--space-5); max-width: var(--measure); }
@media (min-width: 48rem) {
.nf__title { grid-column: 1 / span 8; }
.nf__body { grid-column: 1 / span 5; }
}
</style>
+74
View File
@@ -0,0 +1,74 @@
---
import type { CollectionEntry } from 'astro:content';
import { render } from 'astro:content';
import { Picture } from 'astro:assets';
import Base from '../layouts/Base.astro';
import { formatDate, localePath, t, type Lang } from '../i18n/ui';
interface Props { lang: Lang; post: CollectionEntry<'insights'> }
const { lang, post } = Astro.props;
const ui = t(lang);
const { Content } = await render(post);
const d = post.data;
---
<Base lang={lang} title={d.title} description={d.description}>
<article class="post" lang={d.lang}>
<header class="section section--intro post__head">
<div class="container grid">
<div class="post__meta-col">
<a class="link" href={localePath(lang, '/insights')} lang={lang}>{ui.insights.back}</a>
</div>
<div class="post__title-col">
<p class="small muted post__meta">
<span>{d.category}</span>
<time datetime={d.date.toISOString().slice(0, 10)}>{formatDate(d.date, lang)}</time>
<span lang={lang}>{ui.insights.readingTime(d.readingTime)}</span>
</p>
<h1 class="h2 post__title">{d.title}</h1>
{d.subtitle && <p class="post__subtitle muted">{d.subtitle}</p>}
<p class="post__author"><span lang={lang}>{ui.insights.by}</span> <span class="post__author-name">{d.author}</span><span class="muted">, {d.authorRole}</span></p>
</div>
</div>
</header>
<div class="container">
<Picture
src={d.cover}
alt={d.coverAlt}
formats={['avif']}
fallbackFormat="webp"
widths={[640, 960, 1440, 1920]}
sizes="(min-width: 90rem) 1440px, 100vw"
loading="eager"
decoding="async"
class="post__cover img-doc"
/>
</div>
<div class="section container grid">
<div class="prose post__body">
<Content />
</div>
</div>
</article>
</Base>
<style>
.post__meta-col { grid-column: 1 / -1; }
.post__title-col { grid-column: 1 / -1; display: grid; gap: var(--space-5); }
.post__meta { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.post__title { text-wrap: balance; }
.post__subtitle { font-size: var(--step-h3); letter-spacing: var(--track-h3); line-height: var(--leading-h3); max-width: var(--measure); }
.post__author-name { font-weight: var(--weight-medium); }
.post__cover, :global(.post__cover) { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; object-position: 50% 12%; }
.post__body { grid-column: 1 / -1; }
@media (min-width: 48rem) {
.post__meta-col { grid-column: 1 / span 2; }
.post__title-col { grid-column: 3 / span 9; }
.post__body { grid-column: 3 / span 8; }
}
@media (min-width: 64rem) {
.post__title-col { grid-column: 3 / span 8; }
.post__body { grid-column: 3 / span 7; }
}
</style>
+99
View File
@@ -0,0 +1,99 @@
---
import { Picture } from 'astro:assets';
import Base from '../layouts/Base.astro';
import teamPhoto from '../assets/images/team.png';
import { team } from '../data/team';
import { t, type Lang } from '../i18n/ui';
interface Props { lang: Lang }
const { lang } = Astro.props;
const ui = t(lang);
---
<Base lang={lang} title={ui.meta.team.title} description={ui.meta.team.description}>
<section class="section section--intro team-intro">
<div class="container grid">
<h1 class="display team-intro__title">
{ui.team.title.map((line) => <span class="line">{line}</span>)}
</h1>
<p class="team-intro__lead">{ui.team.intro}</p>
</div>
</section>
<div class="team-photo">
<Picture
src={teamPhoto}
alt={ui.team.photoAlt}
formats={['avif']}
fallbackFormat="webp"
widths={[640, 960, 1440]}
sizes="100vw"
loading="eager"
decoding="async"
class="img-cover img-mono team-photo__img"
pictureAttributes={{ class: 'team-photo__picture' }}
/>
<div class="team-photo__overlay" aria-hidden="true"></div>
</div>
<section class="section" aria-label={ui.nav.team}>
<div class="container">
<ul class="people" role="list">
{team.map((p) => (
<li class="person">
<Picture
src={p.portrait}
alt={p.name}
formats={['avif']}
fallbackFormat="webp"
widths={[320, 480, 640]}
sizes="(min-width: 64rem) 22vw, (min-width: 48rem) 45vw, 100vw"
loading="lazy"
decoding="async"
class="img-mono img-print person__img"
/>
<h2 class="h3 person__name">{p.name}</h2>
<p class="muted">{ui.team.roles[p.role]}</p>
<ul class="person__links small" role="list">
{p.github && <li><a href={p.github} rel="noopener">{ui.team.links.github}</a></li>}
{p.linkedin && <li><a href={p.linkedin} rel="noopener">{ui.team.links.linkedin}</a></li>}
<li><a href={`mailto:${p.email}`}>{ui.team.links.email}</a></li>
</ul>
</li>
))}
</ul>
</div>
</section>
</Base>
<style>
.line { display: block; }
.team-intro__title { grid-column: 1 / -1; }
.team-intro__lead { grid-column: 1 / -1; max-width: var(--measure); color: var(--ink-muted); }
@media (min-width: 48rem) {
.team-intro__title { grid-column: 1 / span 7; }
.team-intro__lead { grid-column: 9 / span 4; align-self: end; }
}
.team-photo {
position: relative;
/* Explicit height: an aspect-ratio with max-height would transfer the cap to the width. */
height: min(66.67vw, 80svh);
min-height: 20rem;
overflow: hidden;
}
:global(.team-photo__picture) { position: absolute; inset: 0; }
.team-photo__img, :global(.team-photo__img) { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
.team-photo__overlay { position: absolute; inset: 0; background: var(--overlay); opacity: 0.6; }
.people {
display: grid;
gap: var(--space-8) var(--gap);
}
.person { display: grid; gap: var(--space-2); align-content: start; }
.person__img, :global(.person__img) { width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; margin-bottom: var(--space-2); }
.person__links { display: flex; gap: var(--space-4); margin-top: var(--space-2); }
.person__links a { text-decoration: underline; text-decoration-thickness: var(--hairline); text-underline-offset: 0.2em; }
@media (min-width: 30rem) { .people { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 64rem) { .people { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
</style>
+19
View File
@@ -0,0 +1,19 @@
---
import Legal from '../_Legal.astro';
import { t } from '../../i18n/ui';
const ui = t('de');
---
<Legal lang="de" title={ui.meta.imprint.title} description={ui.meta.imprint.description} eyebrow={ui.legal.imprintEyebrow}>
<h2>Verantwortlich</h2>
<p>Dr. Felix Klement<br />Innstr. 43<br />94032 Passau<br />Deutschland</p>
<p>Telefon: <a href="tel:+498515093218">+49 851 509 3218</a><br />E-Mail: <a href="mailto:felix.klement@ciphercell.de">felix.klement@ciphercell.de</a></p>
<h2>Inhalt der Website</h2>
<p>CipherCell (der Webseitenbetreiber) prüft und aktualisiert die Informationen auf seinen Webseiten regelmäßig. Trotz aller Sorgfalt übernimmt der Webseitenbetreiber keine Haftung oder Garantie für die Aktualität, Richtigkeit, Vollständigkeit oder Qualität der online verfügbaren Informationen. Alle Angebote sind freibleibend und unverbindlich. Der Webseitenbetreiber behält es sich ausdrücklich vor, einzelne Seiten oder das gesamte Onlineangebot ohne vorhergehende Ankündigung zu verändern, zu ergänzen, zu löschen oder das Angebot auf bestimmte Zeit oder auch endgültig einzustellen.</p>
<h2>Verweise und Links</h2>
<p>CipherCell haftet nicht für den Inhalt von fremden Webseiten, auf die im Onlineangebot von CipherCell z. B. mittels Hyperlinks verwiesen wird. Dies gilt auch für alle Einträge Dritter in vom Webseitenbetreiber eingerichteten Gästebüchern, Diskussionsforen, Pinnwänden und Mailinglisten.</p>
<h2>Urheber- und Kennzeichenrecht</h2>
<p>Inhalt und Struktur der Webseite von CipherCell sind urheberrechtlich geschützt. Die Vervielfältigung von Grafiken, Tondokumenten, Bildmaterialien, Film- und Videoausschnitten und Texten in anderen elektronischen oder gedruckten Medien und Publikationen ist ohne die ausdrückliche Erlaubnis von CipherCell nicht gestattet.</p>
</Legal>
+4
View File
@@ -0,0 +1,4 @@
---
import Home from '../_Home.astro';
---
<Home lang="de" />
+11
View File
@@ -0,0 +1,11 @@
---
import { getCollection } from 'astro:content';
import Post from '../../_Post.astro';
export async function getStaticPaths() {
const posts = await getCollection('insights');
return posts.map((post) => ({ params: { slug: post.id }, props: { post } }));
}
const { post } = Astro.props;
---
<Post lang="de" post={post} />
+4
View File
@@ -0,0 +1,4 @@
---
import InsightsIndex from '../../_InsightsIndex.astro';
---
<InsightsIndex lang="de" />
+25
View File
@@ -0,0 +1,25 @@
---
import Legal from '../_Legal.astro';
import { t } from '../../i18n/ui';
const ui = t('de');
---
<Legal lang="de" title={ui.meta.privacy.title} description={ui.meta.privacy.description} eyebrow={ui.legal.asOf} lead="CipherCell nimmt die Belange des Datenschutzes ernst und erhebt, verarbeitet und nutzt Ihre personenbezogenen Daten ausschließlich in Übereinstimmung mit den nachfolgend beschriebenen Grundsätzen und unter Beachtung der anwendbaren Datenschutzgesetze.">
<h2>Verantwortliche Stelle</h2>
<p>Die verantwortliche Stelle für den Betrieb der CipherCell-Website (im Folgenden „Website“) sowie die Erhebung, Verarbeitung und Nutzung Ihrer personenbezogenen Daten im Sinne des anwendbaren Datenschutzrechts ist Dr. Felix Klement, Innstr. 43, 94032 Passau, Deutschland.</p>
<h2>Webanalyse mit Matomo (ohne Cookies)</h2>
<p>Wir verwenden auf unserer Website die Open-Source-Webanalysesoftware Matomo, um das Nutzungsverhalten auf datenschutzfreundliche Weise auszuwerten und unsere Website technisch und inhaltlich zu verbessern. Dabei haben wir Matomo so konfiguriert, dass keine Cookies gesetzt werden und Ihre IP-Adresse anonymisiert gespeichert wird. Es werden keine personenbezogenen Daten verarbeitet, und es erfolgt keine Weitergabe an Dritte. Die Verarbeitung erfolgt auf Grundlage unseres berechtigten Interesses gemäß Art. 6 Abs. 1 lit. f DSGVO an der statistischen Analyse des Nutzerverhaltens zur Optimierung unseres Webangebots. Wenn Ihr Browser die „Do Not Track“-Funktion unterstützt und aktiviert ist, wird Ihr Besuch von Matomo automatisch ignoriert. Sie können der anonymisierten Analyse Ihres Besuchs dennoch jederzeit widersprechen. Nutzen Sie dazu bitte den folgenden Opt-out.</p>
<p><a href="https://cipher.uber.space/matomo/index.php?module=CoreAdminHome&action=optOut&language=de" rel="noopener">Matomo Opt-out</a></p>
<h2>Datensicherheit</h2>
<p>Ihre Nutzerdaten sind bei der Übermittlung auf unsere Server durch den Einsatz von TLS in Verbindung mit einer 256-Bit-Verschlüsselung geschützt. Sie können die Sicherheit der Verbindung anhand der Angaben in der Adresszeile Ihres Browsers prüfen. Beginnt die Adresszeile mit „https“, liegt eine gesicherte Verbindung vor.</p>
<h2>Kontaktaufnahme</h2>
<p>Wenn Sie uns per E-Mail oder auf anderem Wege kontaktieren, speichern wir Ihre übermittelten personenbezogenen Daten (z. B. Name, E-Mail-Adresse, Inhalt der Nachricht), um Ihre Anfrage zu bearbeiten. Diese Daten werden ausschließlich für die Kommunikation mit Ihnen verwendet und nicht an Dritte weitergegeben. Rechtsgrundlage für die Verarbeitung der Daten ist Art. 6 Abs. 1 lit. b DSGVO (Anbahnung eines Vertragsverhältnisses) oder Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an der Bearbeitung der Anfrage).</p>
<h2>Recht auf Auskunft, Berichtigung, Sperrung oder Löschung</h2>
<p>Nach dem anwendbaren Datenschutzrecht haben Sie ein Recht auf unentgeltliche Auskunft über Ihre gespeicherten Daten sowie ggf. ein Recht auf Berichtigung, Sperrung oder Löschung dieser Daten. Wenden Sie sich bei weitergehenden Fragen zum Datenschutz und zur Verarbeitung Ihrer personenbezogenen Daten, bei Auskünften oder zur Ausübung Ihres Rechts auf Berichtigung, Sperrung oder Löschung oder für den Fall des Widerrufs einer Einwilligung bitte per E-Mail an <a href="mailto:office@ciphercell.de">office@ciphercell.de</a>. Selbstverständlich können Sie auch die im Impressum angegebenen Kontaktdaten oder das Kontaktformular auf der Website nutzen. CipherCell verarbeitet und nutzt die von Ihnen mitgeteilten Informationen ausschließlich für die Bearbeitung Ihres Anliegens.</p>
<h2>Anpassungen</h2>
<p>CipherCell behält sich vor, diese Datenschutzbestimmungen von Zeit zu Zeit anzupassen. Wir werden Sie von jeder Änderung oder Ergänzung vorab rechtzeitig unterrichten und, soweit erforderlich, Ihre Einwilligung in die geänderte Verarbeitung oder Nutzung Ihrer personenbezogenen Daten einholen.</p>
</Legal>
+4
View File
@@ -0,0 +1,4 @@
---
import Team from '../_Team.astro';
---
<Team lang="de" />
+19
View File
@@ -0,0 +1,19 @@
---
import Legal from './_Legal.astro';
import { t } from '../i18n/ui';
const ui = t('en');
---
<Legal lang="en" title={ui.meta.imprint.title} description={ui.meta.imprint.description} eyebrow={ui.legal.imprintEyebrow}>
<h2>Responsible</h2>
<p>Dr. Felix Klement<br />Innstr. 43<br />94032 Passau<br />Germany</p>
<p>Telephone: <a href="tel:+498515093218">+49 851 509 3218</a><br />Email: <a href="mailto:felix.klement@ciphercell.de">felix.klement@ciphercell.de</a></p>
<h2>Website content</h2>
<p>CipherCell (the website operator) regularly reviews and updates the information on its websites. Despite all due care, the website operator accepts no liability or guarantee for the timeliness, accuracy, completeness, or quality of the information available online. All offers are subject to change and non-binding. The website operator expressly reserves the right to change, supplement, delete or discontinue the offer at any time without prior notice. The website operator is not responsible for the content of external links.</p>
<h2>References and links</h2>
<p>CipherCell is not liable for the content of external websites referred to in CipherCell's online offering, e.g. via hyperlinks. This also applies to all entries by third parties in guest books, discussion forums, message boards, and mailing lists set up by the website operator.</p>
<h2>Copyright and trademark law</h2>
<p>The content and structure of the CipherCell website are protected by copyright. The reproduction of graphics, audio documents, image material, film and video excerpts, and texts in other electronic or printed media and publications is not permitted without the express permission of CipherCell. The use of trademarks and logos is also subject to the provisions of the applicable trademark law.</p>
</Legal>
+4
View File
@@ -0,0 +1,4 @@
---
import Home from './_Home.astro';
---
<Home lang="en" />
+11
View File
@@ -0,0 +1,11 @@
---
import { getCollection } from 'astro:content';
import Post from '../_Post.astro';
export async function getStaticPaths() {
const posts = await getCollection('insights');
return posts.map((post) => ({ params: { slug: post.id }, props: { post } }));
}
const { post } = Astro.props;
---
<Post lang="en" post={post} />
+4
View File
@@ -0,0 +1,4 @@
---
import InsightsIndex from '../_InsightsIndex.astro';
---
<InsightsIndex lang="en" />
+25
View File
@@ -0,0 +1,25 @@
---
import Legal from './_Legal.astro';
import { t } from '../i18n/ui';
const ui = t('en');
---
<Legal lang="en" title={ui.meta.privacy.title} description={ui.meta.privacy.description} eyebrow={ui.legal.asOf} lead="CipherCell takes data protection seriously and collects, processes and uses your personal data exclusively in accordance with the principles described below and in compliance with applicable data protection law.">
<h2>Responsible body</h2>
<p>The responsible body for the operation of the CipherCell website (hereinafter referred to as "website") and the collection, processing, and use of your personal data within the meaning of applicable data protection law is Dr. Felix Klement, Innstr. 43, 94032 Passau, Germany.</p>
<h2>Web analytics with Matomo (without cookies)</h2>
<p>We use the open source web analytics software Matomo on our website to evaluate user behavior in a privacy-friendly manner and to improve our website in terms of technology and content. We have configured Matomo so that no cookies are set and your IP address is stored anonymously. No personal data is processed and no data is passed on to third parties. Processing is based on our legitimate interest pursuant to Art. 6 (1) lit. f GDPR in the statistical analysis of user behavior for the purpose of optimizing our website. If your browser supports and has activated the "Do Not Track" function, your visit will be automatically ignored by Matomo. You can still object to the anonymized analysis of your visit at any time. To do so, please use the opt-out below.</p>
<p><a href="https://cipher.uber.space/matomo/index.php?module=CoreAdminHome&action=optOut&language=en" rel="noopener">Matomo opt-out</a></p>
<h2>Data security</h2>
<p>Your user data is protected during transmission to our servers through the use of TLS in conjunction with 256-bit encryption. You can check the security of the connection by looking at the information in your browser's address bar. If the beginning of the address line reads "https", the connection is secure.</p>
<h2>Contact</h2>
<p>If you contact us by email or other means, we will store the personal data you provide (e.g. name, email address, content of the message) in order to process your request. This data will be used exclusively for communication with you and will not be passed on to third parties. The legal basis for processing the data is Art. 6 para. 1 lit. b GDPR (initiation of a contractual relationship) or Art. 6 para. 1 lit. f GDPR (legitimate interest in processing the request).</p>
<h2>Right to information, correction, blocking, or deletion</h2>
<p>Under applicable data protection law, you have the right to obtain information about your stored data free of charge and, if necessary, the right to correct, block, or delete this data. If you have any further questions about data protection and the processing of your personal data, if you require information, or if you wish to exercise your right to correction, blocking, or deletion, or in the event of revocation of consent, please send an email to <a href="mailto:office@ciphercell.de">office@ciphercell.de</a>. You can also use the contact details provided in the legal notice or the contact form on the website. CipherCell processes and uses the information you provide exclusively for the purpose of processing your request.</p>
<h2>Adjustments</h2>
<p>CipherCell reserves the right to amend these data protection provisions from time to time. We will inform you in advance of any changes or additions and, where necessary, obtain your consent to the amended processing or use of your personal data.</p>
</Legal>
+4
View File
@@ -0,0 +1,4 @@
---
import Team from './_Team.astro';
---
<Team lang="en" />