diff --git a/src/components/ProjectCard.astro b/src/components/ProjectCard.astro new file mode 100644 index 0000000..c6a8c94 --- /dev/null +++ b/src/components/ProjectCard.astro @@ -0,0 +1,19 @@ +--- +import type { Project } from '../data/projects'; + +interface Props { + project: Project; +} + +const { project } = Astro.props; +--- + +
+
{project.kind}
+

{project.name}

+

{project.short}

+
+ {project.highlights.map((item) => {item})} +
+ View project → +
diff --git a/src/data/legal.ts b/src/data/legal.ts new file mode 100644 index 0000000..7daec1e --- /dev/null +++ b/src/data/legal.ts @@ -0,0 +1,9 @@ +export const legalNotes = { + disclaimer: + 'This website structure is a technical draft. Before public launch, all legal texts should be completed with real company details and reviewed for legal accuracy.', + privacyCommon: [ + 'Server logs may include IP address, request time, requested URL, browser information, referrer and status codes.', + 'This data may be processed to deliver the service securely, protect against abuse and keep the website or app stable.', + 'No optional third-party tracking, contact forms, analytics or advertising details are included here unless they are explicitly added later.', + ], +}; diff --git a/src/data/projects.ts b/src/data/projects.ts new file mode 100644 index 0000000..554f2be --- /dev/null +++ b/src/data/projects.ts @@ -0,0 +1,66 @@ +export type Project = { + slug: string; + name: string; + kind: 'Website' | 'App'; + short: string; + description: string; + audience: string; + highlights: string[]; + status: string; + url?: string; + privacySummary: string; + legalSummary: string; +}; + +export const projects: Project[] = [ + { + slug: 'unverpackt-finder', + name: 'unverpackt-finder.de', + kind: 'Website', + short: 'A website that helps people discover zero-waste and package-free stores more easily.', + description: + 'unverpackt-finder.de is built to make sustainable shopping options easier to discover. The project focuses on clear navigation, straightforward information and a search-driven experience with minimal friction.', + audience: 'People looking for local zero-waste or package-free stores and sustainable shopping alternatives.', + highlights: ['local discovery', 'clear search intent', 'simple content structure', 'SEO-friendly pages'], + status: 'Active project', + url: 'https://unverpackt-finder.de', + privacySummary: + 'This project may process technically required server data such as IP address, request details, browser data and timestamps to deliver the website securely and reliably.', + legalSummary: + 'This website is operated under the Apposaurus brand. Contact and provider details should be listed with the final business information before public launch.', + }, + { + slug: 'seeds-for-minecraft-pe-java', + name: 'Seeds For Minecraft PE & Java', + kind: 'App', + short: 'An app for discovering interesting Minecraft seeds for Pocket Edition and Java.', + description: + 'Seeds For Minecraft PE & Java is designed to present useful world seeds in a fast and easy-to-browse format. The focus is on quick discovery, practical browsing and a straightforward mobile-friendly product experience.', + audience: 'Minecraft players who want to find useful or interesting seeds without wasting time searching through noisy sources.', + highlights: ['mobile-first browsing', 'seed discovery', 'simple UX', 'focused content presentation'], + status: 'Active project', + privacySummary: + 'This app may process technical usage data needed to provide the app, maintain security and ensure stable performance. If analytics, advertising or account features are added later, this policy must be expanded accordingly.', + legalSummary: + 'This app is presented under Apposaurus. Final operator details, contact information and mandatory disclosures should be completed before publication in stores or on the web.', + }, + { + slug: 'thanks-gratitude-mood-journal-app', + name: 'Thanks. Gratitude Mood Journal App', + kind: 'App', + short: 'A gratitude and mood journal app for simple daily reflection.', + description: + 'Thanks is a calm journaling product focused on gratitude, reflection and mood awareness. It is meant to feel approachable, gentle and easy to use on a daily basis without visual clutter or complexity.', + audience: 'People who want a simple way to track gratitude, record mood and build a small daily reflection habit.', + highlights: ['daily reflection', 'mood tracking', 'simple journaling', 'calm product experience'], + status: 'Active project', + privacySummary: + 'This app may process data that is necessary to store entries, secure the service and keep the app working correctly. If cloud sync, sign-in, notifications or third-party services are added later, the policy should be updated.', + legalSummary: + 'This app is part of the Apposaurus portfolio. The final legal notice should include the full operator identity, address, contact details and any additional mandatory commercial disclosures.', + }, +]; + +export function getProject(slug: string) { + return projects.find((project) => project.slug === slug); +} diff --git a/src/data/site.ts b/src/data/site.ts new file mode 100644 index 0000000..a60ba79 --- /dev/null +++ b/src/data/site.ts @@ -0,0 +1,19 @@ +export const company = { + name: 'Apposaurus', + founder: 'Justin Michael Eckenweber', + city: 'Essen', + country: 'Germany', + tagline: 'A simple home for products, apps and websites built with clarity and purpose.', + email: 'hey@unverpackt-finder.de', + phone: '028160031948', + addressLine1: 'Rühlestraße 5', + addressLine2: '45147 Essen', + addressLine3: 'Germany', +}; + +export const seo = { + title: 'Apposaurus — Apps and websites by a developer from Essen', + description: + 'Apposaurus is the home for lightweight, SEO-friendly websites and useful apps. Built in Essen, focused on clarity, speed and good product presentation.', + url: 'https://apposaurus.de', +}; diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro new file mode 100644 index 0000000..4e60593 --- /dev/null +++ b/src/layouts/BaseLayout.astro @@ -0,0 +1,58 @@ +--- +import '../styles/global.css'; +import { company, seo } from '../data/site'; + +interface Props { + title?: string; + description?: string; +} + +const { title = seo.title, description = seo.description } = Astro.props; +const canonical = new URL(Astro.url.pathname, seo.url).toString(); +--- + + + + + + + + + + + + + + + + + + + {title} + + + + + + + diff --git a/src/pages/index.astro b/src/pages/index.astro index 561196b..e65e2e5 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,17 +1,91 @@ --- +import BaseLayout from '../layouts/BaseLayout.astro'; +import { company } from '../data/site'; +import { projects } from '../data/projects'; +--- ---- + +
+
+
+
+ Developer from {company.city} +

A simple home for apps, websites and future products.

+

+ Apposaurus is the umbrella brand for my digital projects. It is meant to feel light, clear and easy to + browse — a place where each product gets a simple presentation and its own legal pages. +

+ +
+ {projects.length} projects + {company.city}, Germany + lightweight and SEO-friendly +
+
- - - - - - - - Astro - - -

Astro

- - +
+

What this site is for

+

+ Apposaurus brings together websites and apps in one consistent place. It stays intentionally simple, + keeps the focus on the products themselves and avoids over-designed layouts. +

+

+ Every project can have its own detail page, privacy policy and legal notice under a clean + /project/... structure. +

+
+
+
+ +
+
+ Projects +

Current apps and websites

+
+ {projects.map((project) => ( +
+
{project.kind}
+
+

{project.name}

+

{project.short}

+
+ {project.highlights.map((item) => {item})} +
+
+
+ Open + {project.url && Visit} +
+
+ ))} +
+
+
+ +
+
+
+ About +

Built to feel straightforward and welcoming

+

+ The goal is not to make Apposaurus look like a developer portfolio full of boxes and effects. It should + feel more like a calm product website: clear structure, readable copy and enough space for the projects + themselves. +

+
+
+

What can be added later

+
    +
  • more products and launch pages
  • +
  • store links and download links
  • +
  • company information and contact details
  • +
  • partnerships, references or case studies
  • +
+
+
+
+
+
diff --git a/src/pages/legal-notice.astro b/src/pages/legal-notice.astro new file mode 100644 index 0000000..85efc67 --- /dev/null +++ b/src/pages/legal-notice.astro @@ -0,0 +1,41 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import { company } from '../data/site'; +--- + + +
+
+ Legal notice +

Apposaurus

+

+ This legal notice applies to the Apposaurus website. Individual projects may provide additional project-level + legal notice pages under their own /project/... routes. +

+ +
+

Provider information

+

+ {company.founder}
+ {company.addressLine1}
+ {company.addressLine2}
+ {company.addressLine3} +

+

+ Email: {company.email}
+ Phone: {company.phone} +

+
+ +
+

Responsible for content

+

+ {company.founder}
+ {company.addressLine1}
+ {company.addressLine2}
+ {company.addressLine3} +

+
+
+
+
diff --git a/src/pages/privacy-policy.astro b/src/pages/privacy-policy.astro new file mode 100644 index 0000000..74a6370 --- /dev/null +++ b/src/pages/privacy-policy.astro @@ -0,0 +1,41 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import { company } from '../data/site'; +import { legalNotes } from '../data/legal'; +--- + + +
+
+ Privacy policy +

Apposaurus

+

+ This privacy policy applies to the Apposaurus website. Individual projects may also have their own privacy + policy pages under their respective /project/... routes. +

+ +
+

General processing information

+
    + {legalNotes.privacyCommon.map((item) =>
  • {item}
  • )} +
+
+ +
+

Controller

+

+ {company.founder}
+ {company.addressLine1}
+ {company.addressLine2}
+ {company.addressLine3}
+ Email: {company.email}
+ Phone: {company.phone} +

+
+ +
+

{legalNotes.disclaimer}

+
+
+
+
diff --git a/src/pages/project/[slug]/index.astro b/src/pages/project/[slug]/index.astro new file mode 100644 index 0000000..ee98f63 --- /dev/null +++ b/src/pages/project/[slug]/index.astro @@ -0,0 +1,50 @@ +--- +import BaseLayout from '../../../layouts/BaseLayout.astro'; +import { projects } from '../../../data/projects'; + +export function getStaticPaths() { + return projects.map((project) => ({ + params: { slug: project.slug }, + props: { project }, + })); +} + +const { project } = Astro.props; +--- + + +
+
+
+
{project.kind}
+

{project.name}

+

{project.short}

+

{project.description}

+ +

Who it is for

+

{project.audience}

+ +

Highlights

+
+ {project.highlights.map((item) => {item})} +
+
+ + +
+
+
diff --git a/src/pages/project/[slug]/legal-notice.astro b/src/pages/project/[slug]/legal-notice.astro new file mode 100644 index 0000000..30988f5 --- /dev/null +++ b/src/pages/project/[slug]/legal-notice.astro @@ -0,0 +1,41 @@ +--- +import BaseLayout from '../../../layouts/BaseLayout.astro'; +import { projects } from '../../../data/projects'; +import { company } from '../../../data/site'; +import { legalNotes } from '../../../data/legal'; + +export function getStaticPaths() { + return projects.map((project) => ({ + params: { slug: project.slug }, + props: { project }, + })); +} + +const { project } = Astro.props; +--- + + +
+
+
+
Legal notice
+

{project.name}

+

{project.legalSummary}

+ +

Provider information

+

+ {company.name}
+ Responsible person: {company.founder}
+ {company.addressLine1}
+ {company.addressLine2}
+ Email: {company.email}
+ Phone: {company.phone} +

+ +
+

{legalNotes.disclaimer}

+
+
+
+
+
diff --git a/src/pages/project/[slug]/privacy-policy.astro b/src/pages/project/[slug]/privacy-policy.astro new file mode 100644 index 0000000..2f7bf94 --- /dev/null +++ b/src/pages/project/[slug]/privacy-policy.astro @@ -0,0 +1,47 @@ +--- +import BaseLayout from '../../../layouts/BaseLayout.astro'; +import { projects } from '../../../data/projects'; +import { company } from '../../../data/site'; +import { legalNotes } from '../../../data/legal'; + +export function getStaticPaths() { + return projects.map((project) => ({ + params: { slug: project.slug }, + props: { project }, + })); +} + +const { project } = Astro.props; +--- + + +
+
+
+
Privacy policy
+

{project.name}

+

{project.privacySummary}

+ +

General processing information

+
    + {legalNotes.privacyCommon.map((item) =>
  • {item}
  • )} +
+ +

Controller

+

+ {company.name}
+ {company.addressLine1}
+ {company.addressLine2}
+ Email: {company.email} +

+ +
+

+ This page is a structured draft. Before launch, it should be completed with the real processing details, + data categories, legal bases, storage periods and third-party services used by this specific project. +

+
+
+
+
+
diff --git a/src/styles/global.css b/src/styles/global.css new file mode 100644 index 0000000..431139b --- /dev/null +++ b/src/styles/global.css @@ -0,0 +1,278 @@ +body { + margin: 0; + font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + color: #1f2937; + background: #ffffff; +} + +* { + box-sizing: border-box; +} + +a { + color: inherit; + text-decoration: none; +} + +.container { + width: min(1020px, calc(100% - 32px)); + margin: 0 auto; +} + +.site-header { + background: rgba(255, 255, 255, 0.96); + border-bottom: 1px solid #eceff3; + position: sticky; + top: 0; + z-index: 20; +} + +.nav { + min-height: 72px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; +} + +.brand { + font-size: 1.08rem; + font-weight: 700; + color: #111827; +} + +.nav-links, +.footer-links { + display: flex; + flex-wrap: wrap; + gap: 18px; + color: #6b7280; + font-size: 0.95rem; +} + +.nav-links a:hover, +.footer-links a:hover, +.project-link:hover { + color: #111827; +} + +.hero { + padding: 88px 0 48px; +} + +.hero h1 { + font-size: clamp(2.7rem, 5vw, 4.8rem); + line-height: 0.97; + letter-spacing: -0.05em; + color: #111827; + margin: 0 0 18px; +} + +h2, +h3 { + color: #111827; + margin-top: 0; +} + +h2 { + font-size: clamp(1.55rem, 3vw, 2.1rem); + margin-bottom: 12px; +} + +h3 { + font-size: 1.12rem; + margin-bottom: 8px; +} + +p, +li { + line-height: 1.7; + color: #4b5563; +} + +.section { + padding: 26px 0 54px; +} + +.eyebrow { + display: inline-block; + margin-bottom: 14px; + color: #2563eb; + font-size: 0.92rem; + font-weight: 600; +} + +.muted { + color: #6b7280; +} + +.button-row { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 22px; +} + +.button { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 46px; + padding: 0 18px; + border-radius: 999px; + font-weight: 600; + border: 1px solid transparent; +} + +.button.primary { + background: #111827; + color: white; +} + +.button.secondary { + background: #fff; + color: #111827; + border-color: #d1d5db; +} + +.hero-grid, +.two-col, +.detail-grid { + display: grid; + grid-template-columns: 1.3fr 0.85fr; + gap: 36px; +} + +.hero-note { + padding-top: 10px; +} + +.simple-panel { + border-top: 1px solid #eceff3; + padding-top: 18px; +} + +.stats { + display: flex; + flex-wrap: wrap; + gap: 18px; + margin-top: 28px; + color: #6b7280; +} + +.stats strong { + color: #111827; +} + +.projects-list { + border-top: 1px solid #eceff3; +} + +.project-row { + display: grid; + grid-template-columns: 160px 1fr auto; + gap: 18px; + padding: 22px 0; + border-bottom: 1px solid #eceff3; + align-items: start; +} + +.project-kind { + color: #2563eb; + font-size: 0.92rem; + font-weight: 600; + padding-top: 4px; +} + +.project-row h3 { + margin-bottom: 6px; +} + +.project-actions { + display: flex; + gap: 12px; + align-items: center; + justify-content: flex-end; + white-space: nowrap; +} + +.project-link { + font-weight: 600; + color: #111827; +} + +.tag-list { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: 10px; +} + +.tag { + background: #f6f7f9; + color: #4b5563; + border-radius: 999px; + padding: 7px 11px; + font-size: 0.84rem; +} + +.simple-list { + display: grid; + gap: 10px; + padding-left: 18px; +} + +.card { + border-top: 1px solid #eceff3; + padding-top: 18px; +} + +.notice { + border-left: 3px solid #d1d5db; + padding-left: 16px; + margin-top: 18px; +} + +.footer { + border-top: 1px solid #eceff3; + background: #fff; + margin-top: 56px; +} + +.footer-inner { + padding: 26px 0 38px; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + gap: 16px; +} + +.footer-copy { + color: #6b7280; + font-size: 0.95rem; +} + +code { + background: #f3f4f6; + padding: 2px 6px; + border-radius: 6px; + color: #374151; +} + +@media (max-width: 900px) { + .hero-grid, + .two-col, + .detail-grid, + .project-row { + grid-template-columns: 1fr; + } + + .hero { + padding-top: 56px; + } + + .project-actions { + justify-content: flex-start; + } +}