Commit graph

44 commits

Author SHA1 Message Date
Lara
ad92f1f512 Load the zoom view in strips so it opens instantly
The full-page captures (up to 1.3 MB each) are now cut into strips by
scripts/ganzseiten-kacheln.mjs. The first strip is ~60 KB and is fetched
as soon as a device scrolls into view; further strips load just before
they are scrolled to. Strip sizes are in the file names, so the dialog
has its full height immediately without layout jumps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 12:19:46 +02:00
Lara
f000d64cca Design round: logo colours, own fonts, blob shapes, broken grid
Prototype for review, not deployed. Newsreader + Schibsted Grotesk
(served locally, italic included), palette from the logo (petrol, sage,
sand, rose) instead of gold, the logo blob as a recurring shape, petrol
bands with a wave edge, margin-note section labels and uneven columns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 12:09:28 +02:00
Lara
3ae5f815e8 Brand favicon, link preview image, and zoomable portfolio devices
Replace the Astro placeholder favicon (white L on indigo) with the larpaso
"la" mark from the prototype, in SVG/ICO/PNG sizes plus an Apple touch
icon, and add Open Graph tags with a 1200x630 preview image so shared links
show the logo. Icons are rebuilt with scripts/icons-bauen.mjs.

Clicking or tapping the laptop or phone in the hero and the portfolio now
opens a full-page capture of the example site in a dialog, scrollable and
switchable between desktop and mobile. The scroll videos stay as they were.
New content fields mappe.items[].fullImage / fullMobileImage, also in the
admin schema.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 11:44:09 +02:00
Lara
1c1687dcf3 Add Saturday (by arrangement) to the opening-hours card
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 11:06:28 +02:00
Lara
5d27e663f8 Add contact hours: Mon-Thu 9-18, Fri 9-14, Sat by arrangement
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 11:04:10 +02:00
Lara
ff102bad9b Fill in the free-slots line: 3 of 3, as of 5 October 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 11:01:09 +02:00
Lara
2fa8dc6615 Serve fonts ourselves and write the privacy policy
Fonts: every Google font the editor offers (13 families, latin and
latin-ext, 1.2 MB) now lives in public/fonts; the layout inlines
@font-face rules only for the fonts in use, built from
src/lib/font-faces.json. scripts/fonts-holen.py re-fetches them.
The admin font preview loads the same files via /admin/fonts and
/admin/api/font-faces. Checked: no request leaves larpaso.de on the
start page, Impressum or Datenschutz, nor in the admin editor.

nginx: access_log off, so visitor IPs are not stored. Caddy has no
access log configured either.

Privacy policy replaces the placeholder and describes only what the
site actually does: controller (from the Impressum), hosting at netcup
in Nuremberg (from the server IP), no access logs, HTTPS, mailto
contact form and e-mail, self-hosted fonts and media, no cookies,
data subject rights and the Lower Saxony supervisory authority.
The closing note is no longer styled as a warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 10:54:24 +02:00
Lara
1b72de46ad Describe the optional hosting and care package consistently
Owners' decision: hosting plus care is offered as an optional package
for 50-100 EUR a month. Updated the excluded-items line, the
"Warum so günstig?" aside (the website itself is still a one-off
payment without a contract term), service 05 and the last FAQ entry,
whose question now reads "Was kostet es nach dem Start?".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 10:35:30 +02:00
Lara
ef94d9370f Answer four more FAQ entries
Wording based on the owners' notes, kept factual: changes are made
before going live, photos can be added later, the timeline follows
the first meeting, and an existing site gets an honest assessment.
The yearly-cost answer is still open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 10:33:53 +02:00
Lara
9453827076 Sharpen positioning and copy after an outside review
An outside review (ChatGPT, from a screenshot) found the hero too
generic and the copy full of agency words. Checked each point against
the live page; the valid ones are done here:

- Hero now says who it is for: "Webdesign für Betriebe vor Ort",
  "Websites, auf denen Ihre Kunden sofort finden, was sie suchen."
  This matches the 500 € offer and the three portfolio pieces, which
  were already about local businesses.
- Second hero button "Arbeiten ansehen" (#arbeiten); every primary
  button now reads "Projekt besprechen".
- "Was wir anders machen" replaces "Individuell, sorgfältig,
  technisch solide."; highlights I and III and the service texts are
  rewritten as concrete statements.
- Mappe entries show "Die Aufgabe" / "Unsere Lösung". No invented
  results: all three are concept work.
- Two FAQ answers filled where the facts are known (self-editing is
  part of the offer; no on-site meetings).
- Two em dashes in body copy replaced.

Not taken over: the "500+" figure and "Mehr erfahren" button the
review mentions do not exist on the page.

Admin schema gains hero.secondaryLabel and mappe.items[].aufgabe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 10:23:43 +02:00
Lara
06df50fc74 Replace Tanzhaus Kranich with an invented electrician in the Mappe
All three portfolio pieces shared the same handwriting: cream ground,
serif type, quiet editorial layout, two of them dance schools. Visitors
read that as one template in three colours.

New piece: Rabe Elektrotechnik, an invented electrical contractor.
Anthracite and signal yellow, Barlow Condensed for headlines, a price
data sheet in the hero, schematic line work instead of photos. It now
leads the Mappe as the wide card, and its phone view sits next to the
laptop in the hero. Kranich's video and stills are removed; the
prototype itself stays untouched in Downloads.

Prototype checked with Playwright: 133 text elements, 0 WCAG AA
failures, no overflow at 1440/1280/390, no console errors, both
fonts confirmed active.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 10:07:30 +02:00
Lara
c2e0b22977 Bring back the dark bands for offer and contact
The original prototype broke up the light page with two dark "Nacht"
bands (#1E1A14): the offer right after the hero, and the contact at the
end. Restored as .section-dark, which redefines the color variables
instead of overriding single rules, so cards, buttons, form fields and
placeholders all turn with it. Measured in the rendered DOM: 42 text
elements, 0 WCAG AA failures; form field borders 3.41:1.

Also fixes the missing space in "der Datenschutzerklärung" below the
contact form (Astro dropped the line break before the link).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 09:56:29 +02:00
Lara
85c63cd714 Show the portfolio on devices and tone down the AI wording
- Mappe: each design now sits in a CSS laptop frame with a phone view
  beside it. Maison Verte and Tanzhaus Kranich play a short muted
  scroll loop (565/728 KB, H.264), started only while in view and not
  at all with prefers-reduced-motion. Atelier Rosenhain is a short
  one-pager, so it keeps its still.
- Hero: the Google result mock-up is replaced by a laptop + phone
  showing two of the designs. customImage still overrides it.
- Admin schema follows: hero.visual laptop/phone, mappe mobileImage
  and video; the Google-card fields are gone.
- "KI" now appears once, honestly, in the About paragraph. Replaced in
  the meta description, hero lead, highlight II, services lead and
  card 02, process step 03, the About quote and the footer. The
  section title now reads "Individuell, sorgfältig, technisch solide."

Em dashes in the prototypes were replaced in the browser before
recording, so none show up in the videos.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 09:41:28 +02:00
Lara
b3a3680d76 Add deploy.sh so the rollout is one short command
The full ssh one-liner is long enough that copying it reliably is a
problem. "bash deploy.sh" is short enough to type by hand.

Same sequence as before, with the mandatory order documented in the
file: build admin before publishing, because publish-content-to-live.sh
builds inside the admin container.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 18:41:40 +02:00
Lara
7247964855 Remove em dashes from the visible area of all three portfolio shots
Reported as reading "krass nach KI" on the Maison Verte shot. The Mappe
copy itself has none - the dashes were inside the screenshot, i.e. in
the prototype's own text. The prototype carries 34 em dashes overall;
four of them sat in the area the shot captures:

- "bei null an — Ballett, ..."        -> colon
- "höflich absagen — wir rufen ..."   -> full stop, new sentence
- "Prototyp — Studio, Personen, ..."  -> middle dot
- "Foto hochkant — Tänzerin ..."      -> middle dot

Checked the other two shots for the same flaw, since they sit right
next to it, and fixed one each: Tanzhaus Kranich ("Discofox bei — in
Gruppen" -> comma) and Atelier Rosenhain's banner, which I had written
that way myself.

All three screenshots recaptured and verified: zero em dashes in the
captured viewport of each. Sources edited in Downloads, which is where
the prototypes live.

The em dash is a known AI-slop marker here; the same cleanup was done
once before on the faceart prototype.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 14:23:56 +02:00
Lara
78ccad9c2d Reduce the readability section to the opening hours
The section showed the same information twice side by side - a dashed
"PDF" card labelled "So sieht es heute oft aus" against an hours table
labelled "So sieht es nachher aus". Reported as confusing; the file side
is dropped, the table stays.

The copy had to follow: it literally said "Dieselben Angaben, zweimal.
Einmal als Datei ... Einmal als Tabelle", which describes a comparison
that no longer exists. Rewritten to stand on its own, and the heading
"Lesbar schlägt vollständig" with it - it only made sense against the
file.

Also dropped the table's "TAG" header row. It had no counterpart on the
right and was left over from the two-column layout.

Removed throughout rather than hidden: the pdf-card/pdf-icon/pdf-name/
pdf-meta and readability-label/hours-head rules, the two-column grid
including its mobile override, and the four now-meaningless fields in
the admin schema.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 14:10:54 +02:00
Lara
ef36d5183f Show step durations only where one is set
Three of the four Ablauf steps had no duration and therefore rendered a
red "[Dauer?]" placeholder. Requested: drop those, keep the "2–3 Tage"
on step 03.

The span is now only rendered when step.dauer is filled, instead of
falling back to a placeholder. Each .ablauf-step is its own grid, so the
auto-width third column simply collapses and the text takes the space -
no layout shift. The editor label no longer claims that an empty field
produces a placeholder.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 14:06:28 +02:00
Lara
b2dde6f904 Drop the webshop mention from the price list too
Requested as a follow-up to removing "Keine Onlineshops." from the
"Was wir nicht machen" list. The exclusion now reads "Nicht enthalten:
Fotoshooting, Logo-Neuentwurf" - the other two still stand.

No mention of shops is left anywhere in the content.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 14:00:27 +02:00
Lara
d591faca0c Drop the paragraph explaining what the name larpaso is made of
Removed on request. The about section now ends after the paragraph
about AI tools; no other place explains the name, so nothing dangles.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 13:53:19 +02:00
Lara
b18b8eb26b Replace the raster logo with the original vector, drop the webshop line
The logo was blurry because logo.png came from a 320x60 JPEG. It is
drawn 299 css px wide, so a 2x display needs ~597px and a 3x phone
~896px - it had roughly half, respectively a third, of the pixels it
needed. No amount of rescaling fixes that.

The real source was in the repo's own history instead: the prototype
in Downloads/lara-webdesign.html carries the mark as one SVG with a
single viewBox - the wave field plus the "larpaso" wordmark as a path
drawn from EB Garamond italic. Both paths, the sage/straw/rose gradient
and the petrol #2C4A42 are taken from there verbatim, so this is the
decided mark, not a redrawing. It only looked like a smooth pill
because the JPEG was too coarse to show the waves.

The "WEBDESIGN" label is converted to outlines from Schibsted Grotesk
rather than set as <text>: an SVG loaded via <img> gets no webfonts and
would silently fall back to a system face - the same reasoning the
existing wortmarke-zu-pfad.py gives for the wordmark.

Also removed "Keine Onlineshops." from the "Was wir nicht machen" list,
as requested. The price list still reads "Nicht enthalten: Fotoshooting,
Logo-Neuentwurf, Onlineshop" - that one scopes the 500 € package rather
than declaring what we do at all, so it is left for now.

logo.png and logo.jpg stay in place as fallbacks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 13:47:30 +02:00
Lara
9cdeb53859 Adopt the names entered via the admin editor, de-duplicating first names
The live content volume held three values that were never in git,
entered through the editor: both surnames and a company line added to
the Impressum. Publishing from git would have silently wiped them, so
they are adopted here first.

Corrected while adopting: the footer fields are surnames - the template
already prints "Lara" and "Pascal" in front - but full names had been
entered, so larpaso.de currently reads "Lara Lara Kristin Löhr und
Pascal Pascal Scholz". Storing "Kristin Löhr" yields the intended
"Lara Kristin Löhr und Pascal Scholz".

The Impressum line is taken over verbatim, company name included.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 13:35:45 +02:00
Lara
f8763ed6f5 Switch the site to the light "Papier & Gold" palette
Requested: make the site lighter, the way the colours were originally.
Taken from the house palette "Papier & Gold" (warm off-white, gold as
the only accent): papier #FCFAF6, papier-2 #F4EFE4, card #FFFDF8, ink
#1C1813, quiet #6B6154.

Gold needs more than one hex value. The old dark theme used a single
light gold for both text and fills, which works on a dark ground but
breaks on paper: #C9A461 as text scores 2.25:1. So primary and accent
are now the dark gold #7A5D1F, which carries fill *and* type (5.90:1 on
paper, and takes cream text on top), with #FFFDF8 as its contrast.
googleBlue became Google's actual link blue so the search mock stays
readable on a light ground. Fonts untouched.

Fixed a pre-existing bug this exposed: ".nav-links a" also matched the
header CTA and overrode .btn-primary's colour, so the button rendered
muted text on the primary fill - 1.01:1, effectively invisible. It just
never showed on the dark theme, where both tones were light. Narrowed
to ".nav-links ul a", matching the :hover rule right below it.

Rebuilt the logo as a transparent PNG: logo.jpg had the old dark
background baked in and sat on the page as a black box, with its
"WEBDESIGN" label in light grey that disappears on paper. The pill is
preserved pixel for pixel (row-wise fill so the dark lettering inside
stays opaque, then eroded 1px to drop the old anti-aliasing halo); the
label is recoloured to ink. logo.jpg is kept.

Verified in the browser across all three pages: 228 rendered text
elements measured, 0 WCAG AA failures, tightest pair 5.82 - which is
exactly the documented figure for "quiet on paper". No horizontal
scroll, no console errors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 13:19:51 +02:00
Lara
a105bee995 Remove the Lara/Pascal short bios from the about section
Dropped on request. The two bios were never written, so the section
rendered two red placeholder paragraphs asking for three to four
sentences each.

Removed in all four places so nothing dangles: the .about-bios markup
block and its CSS rule in index.astro, the laraBio/pascalBio keys in
content/site.json, and the two fields in the admin editor's schema -
otherwise the editor would still offer inputs that no longer render.

The about section keeps its eyebrow, title, quote and three paragraphs,
the last of which already explains that the name is built from Lara and
Pascal plus "paso".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 13:11:14 +02:00
Lara
dd4411f182 Replace the withheld faceart entry with an invented cosmetics studio
The third Mappe slot referred to the faceart Goslar prototype, which
carries a real business's name, prices and copy that the owner never
approved - so it had to stay nameless behind nameHidden, leaving a
placeholder in the portfolio.

Built a fresh prototype for a fully invented studio instead ("Atelier
Rosenhain" in the invented town of Bad Ellerstein, fictional prices),
matching the other two entries, which are invented businesses too. It
carries the same "frei erfunden" banner as Maison Verte. Source lives
next to the other prototypes:
Downloads/kosmetik-rosenhain-prototyp.html

Uses the house "Rosenholz" palette and the EB Garamond + Archivo
pairing. Verified in the browser: 40 rendered text elements measured,
0 WCAG AA failures (tightest pair 5.22), both fonts actually active,
no horizontal scroll at 1600px or 390px.

The existing entry text already promised "jede Behandlung mit Dauer und
Preis, Termin direkt aus der Liste heraus", so the treatment list with
duration, price and a per-row booking button sits in the hero where the
screenshot shows it. Text left unchanged.

nameHidden is now false and the Mappe renders no placeholders at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 13:06:49 +02:00
Lara
7c2b1557da Add portfolio screenshots for the two in-house concept studies
The Mappe section rendered "Bildschirmfoto einsetzen" placeholders for
all three entries. Two of them are our own concept work with invented
businesses, so they can be shown:

- Maison Verte (tanzschulprototyp-maisonverte.html)
- Tanzhaus Kranich, Terra variant (tanzhaus-kranich-terra.html)

Captured at 1600x900 @2x via Playwright, downscaled to WebP. The first
card spans the full grid width (.mappe-item:first-child), which maxes
out at 1104px, so Maison Verte is 2208px wide for a true 2x; the
half-width card is 1200px. 60 KB and 32 KB.

Stored under public/mappe/ rather than public/uploads/, because uploads
are gitignored (production mounts a volume there) and these are fixed
repo assets that must ship with the build.

The third entry (faceart Goslar) deliberately keeps its placeholder: it
carries a real business's name, prices and copy, and the owner has not
approved any of it - which is why nameHidden is already true. A
screenshot would put her name on our sales page regardless.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 13:03:08 +02:00
Lara
da52c95583 Fill in Pascal's surname in the footer
The footer rendered a red "[Nachname]" placeholder for both names.
Pascal's surname is already in the repo via impressum.anbieterAngaben
("Pascal Scholz, Weinkampswende 14, 30539 Hannover"), so it can be
filled in without guessing.

Lara's surname stays empty on purpose - it is not recorded anywhere in
the repo and must not be invented.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-04 12:55:20 +02:00
807022a62a Improve accessibility: keyboard-operable mobile nav, skip link, focus styles
- Replace the checkbox-hack mobile menu (display:none checkbox was
  unreachable by keyboard/screen readers) with a real button using
  aria-expanded/aria-controls
- Add a skip-to-content link
- Add a consistent :focus-visible outline across interactive elements
- Underline prose links by default instead of only on hover (WCAG 1.4.1
  use-of-color), keep nav/button links unstyled since they're already
  visually distinct
- Respect prefers-reduced-motion for smooth scrolling

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 23:10:23 +02:00
cf8d6a65ea Document correct order when content and admin code change together
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 22:58:32 +02:00
dcc722b6db Add VSBG dispute-resolution notice and Haftungsausschluss to Impressum
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 22:55:01 +02:00
f75296da44 Add sync/publish scripts for content changes made via Claude Code
Lets content edits pushed through Git reach the live admin-content
volume (and vice versa) without silently overwriting whatever was
changed through the admin editor UI in the meantime.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 22:49:01 +02:00
a920880a20 Fill in Impressum with real Anbieter-Angaben
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 22:35:37 +02:00
0a702dac16 Add onboarding guide for Lara's Claude (repo + SSH access)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 19:57:22 +02:00
7c2ed96fab Fix build-log close button not hiding the panel
.build-log set display:flex unconditionally, which as an author rule
beat the browser's default [hidden]{display:none} (author styles always
win over user-agent styles regardless of the hidden attribute). Add an
explicit .build-log[hidden]{display:none} rule so closing the panel -
and its initial hidden state on page load - actually works.
2026-09-21 23:16:20 +02:00
7c67ae1ff5 Add WYSIWYG rich-text editor and reorganize admin UI into tabs
Rich-text fields (hero lead, paragraphs, FAQ-style copy, datenschutz
sections, etc.) now use a proper toolbar editor - bold/italic/underline
buttons plus a per-selection font picker drawn from the same curated
font list as the Design tab - instead of typed **markdown** syntax.

Content is stored as a small allowlisted HTML subset (strong/em/u/span
with a validated data-font/br) and sanitized server-side with
sanitize-html on every save (admin/lib/rich-sanitize.js), independent
of what the client sends - verified this rejects script tags, event
handlers, and made-up font names while preserving legitimate markup,
and that re-saving already-sanitized content is a no-op.

The Astro site mirrors the same allowlist at render time for
defense-in-depth (src/lib/rich-sanitize.ts) and only requests Google
Fonts for fonts actually referenced somewhere in content, in addition
to the two Design-tab fonts - verified a font used via a data-font span
gets its own Google Fonts request and [data-font] CSS rule in the
built page, and that unused fonts don't get requested.

Migrated the three existing fields that used the old markdown-lite
syntax (**bold**/*italic*) to real HTML so they keep rendering
correctly under the new system.

Also replaces the single long scrolling admin page with a tabbed
sidebar (grouped "Inhalte"/"Design") to cut down on clutter, per
feedback that the all-in-one-page layout was hard to navigate.
2026-09-21 23:11:19 +02:00
b625bc208b Fix B6/B7 in deploy guide: escape $ for docker compose env_file parsing
Docker Compose interpolates $VAR references within env_file values (not
just docker-compose.yml), so a raw bcrypt hash like $2a$12$... gets
partially swallowed as undefined variables - exactly the truncation
Pascal hit. Pipe hash-password.js output through `sed 's/\$/$$/g'` and
store the escaped hash; document the 63-char (60 + 3 escaped $) length
check to verify it went in correctly.
2026-09-21 22:45:54 +02:00
9a21c72f08 Support multiple admin logins
ADMIN_USERNAME/ADMIN_PASSWORD_HASH now optionally extends to _2, _3, ...
for additional accounts (e.g. a second login for Lara), all with equal
access - no roles, still no self-service password reset. Falls back to
a dummy bcrypt compare on unknown usernames to keep login timing
consistent. Verified locally: both users log in, wrong password and
unknown usernames are rejected, and single-user setups still work
unchanged (backward compatible).

Also documents the optional second-user setup in DEPLOYMENT_ADMIN.md (B6/B7).
2026-09-21 22:24:52 +02:00
f539514fad Fix B6 in deploy guide: hash-password.js path inside the admin container
Dockerfile.admin sets WORKDIR /app and copies the whole repo there, so
hash-password.js lives at /app/admin/hash-password.js, not /app/hash-password.js
(same pattern as the existing admin/server.js CMD). The docker compose run
command in B6 was missing the admin/ prefix, causing MODULE_NOT_FOUND.
2026-09-21 22:14:17 +02:00
6478e87fb3 Restructure deploy guide: generate admin credentials from the built image
The ad-hoc `npm install bcryptjs` in a throwaway container hit npm's known
"Tracker 'idealTree' already exists" bug. Reorder Teil B so the admin
service is built first (a proper `npm ci`, the same path already used for
the real deployment), then generate the password hash and session secret
via `docker compose run --rm admin ...` against that image instead.
2026-09-21 22:00:02 +02:00
ab7d506eea Fix B2 in deploy guide: generate admin credentials via Docker, not host npm
The deploy host only has Docker installed, not Node/npm directly, so the
original `npm install` / `node hash-password.js` steps failed with
"command not found". Both the bcrypt hash and session secret are now
generated with a throwaway `node:22-alpine` container instead.
2026-09-21 21:46:54 +02:00
93178a24e3 Add login-protected admin editor for content and design
Adds a self-service editor at admin.larpaso.de so texts, images, links,
Impressum/Datenschutz, fonts, font sizes and colors can be changed without
a developer. All homepage/legal content moves into content/site.json and
a new content/theme.json drives every CSS color/font/size token; the
Astro pages read from these at build time.

The admin/ service (Node/Express) provides bcrypt+session login with
rate limiting, a schema-driven form UI (including a hex/RGB/alpha color
picker), image upload, and a publish action that runs the Astro build
and republishes into a volume shared with the nginx website container -
so edits go live without redeploying that container.

See DEPLOYMENT_ADMIN.md for the server-side setup steps.
2026-09-21 21:35:09 +02:00
478e032b0b Redesign homepage as single-page site with new dark/gold branding
Replaces the previous multi-page structure (Startseite, Leistungen,
Über uns, Kontakt) with one long-form page covering pricing, work
samples, process and FAQ, matching the new visual identity (dark
theme, serif display type, sage-green logo mark). Old routes now
redirect to the corresponding anchors. Adds Impressum and Datenschutz
stub pages with clearly marked placeholders for the still-missing
real content (contact details, founder bios, portfolio, pricing
specifics).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 20:13:26 +02:00
ec872efa42 Document live deployment status and future update workflow
larpaso.de is now confirmed live (verified 200 OK + valid TLS cert).
Records what was done for Teil B and clarifies the ongoing workflow:
Claude Code can edit/build/push code changes directly, but the
server-side rebuild step still needs to run on the server manually
unless an auto-deploy hook is set up later.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T8eccP4XnXFJvpSYMm26as
2026-09-12 04:01:17 +02:00
e688eaa265 Add ready-to-run copy-paste blocks for server deployment (Teil B)
Documents that Teil A is verified (build tested locally) and provides
exact commands for deploy key, docker-compose service, Caddyfile
block, and DNS steps so the server-side rollout needs no improvisation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T8eccP4XnXFJvpSYMm26as
2026-09-12 03:32:49 +02:00
28ba23102a Add Docker deployment setup for static Astro site
Multi-stage Dockerfile (node build -> nginx serve), nginx config with
_astro asset caching, .dockerignore, and .gitignore hardening for
TLS key files. Astro already builds static output with site set to
https://larpaso.de.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JmTVcwbGJBYP7gu4P7b1yG
2026-09-12 03:21:47 +02:00