Commit graph

12 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
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
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
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
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
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
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
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
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