Skip to content

Commit 4cf397c

Browse files
committed
RelayStack site: the workshop labelling world
The site is written in the embossed label-tape system: every heading, section label and action is a piece of black tape with raised white capitals, stuck on a painted-steel wall. There are no cards, no pills and no rounded panels — the tape strip is the only container in the world. - Astro, static, zero client JavaScript. One 9 KB stylesheet. - Self-hosted variable fonts (Archivo, Archivo Narrow). No fonts.googleapis.com, so no third-party request and no consent banner. - Content collections for the four services and the three articles. - Native sitemap.xml, robots.txt and llms.txt built from the same collections, so they cannot drift from the pages. - Organization schema only: no postal address is emitted because none is published. Inventing one would be worse than omitting it. - Prices come from DACH market research, shown next to the market figures they were placed against rather than hidden. - No testimonials, no client names, no percentages. The honest limits are a section of the page, not a footnote. - Impressum is deliberately a marked draft and noindex: the mandatory details are not published yet.
0 parents  commit 4cf397c

40 files changed

Lines changed: 7482 additions & 0 deletions

‎.github/workflows/deploy.yml‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: deploy
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: pages
15+
cancel-in-progress: true
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v7
22+
- uses: actions/setup-node@v7
23+
with:
24+
node-version: 22
25+
cache: npm
26+
- run: npm ci
27+
- run: npm run build
28+
- name: Fail if the SEO files are missing or empty
29+
run: |
30+
for f in dist/sitemap.xml dist/robots.txt dist/llms.txt; do
31+
test -s "$f" || { echo "missing or empty: $f"; exit 1; }
32+
done
33+
- uses: actions/upload-pages-artifact@v3
34+
with:
35+
path: dist
36+
37+
deploy:
38+
needs: build
39+
runs-on: ubuntu-latest
40+
environment:
41+
name: github-pages
42+
url: ${{ steps.deployment.outputs.page_url }}
43+
steps:
44+
- id: deployment
45+
uses: actions/deploy-pages@v4

‎.gitignore‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
node_modules/
2+
dist/
3+
.astro/
4+
.env
5+
.env.*
6+
.DS_Store
7+
*.log
8+
9+
# Impeccable build/review artefacts stay local
10+
.impeccable/mocks/
11+
.impeccable/review/
12+
.impeccable/build/
13+
14+
# Development-only: Impeccable artifacts and the local screenshot helper
15+
.impeccable/
16+
scripts/shoot.mjs

‎PRODUCT.md‎

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Product
2+
3+
<!-- impeccable:product-schema 1 -->
4+
5+
## Platform
6+
7+
web
8+
9+
## Stack
10+
11+
Astro, static output, deployed to GitHub Pages (`relaystack.github.io`) via a GitHub Actions workflow. Chosen by the user. Content lives in Markdown content collections. Zero client-side JavaScript by default. A custom domain is a later decision, not part of this build.
12+
13+
## Users
14+
15+
Owner-operators of small and medium service businesses in the German-speaking market (Germany, Austria, Switzerland) — trades, practices, studios, studios, local services. They run the business themselves and buy from a person, not a procurement department. They arrive sceptical, usually after being let down by a previous website or a retainer that showed no results.
16+
17+
Their job: get found — by people searching Google, and increasingly by people asking an AI assistant — and turn those arrivals into enquiries.
18+
19+
Secondary audience: developers and technically-minded buyers who find the open-source tooling first and evaluate the person behind it. English serves them.
20+
21+
## Product Purpose
22+
23+
A marketing site that converts a sceptical DACH business owner into a conversation, and secondarily establishes technical credibility with developers.
24+
25+
Success means: a visitor asks a question on Telegram. Not a form submission, not a newsletter signup, not a metric — a conversation started.
26+
27+
## Positioning
28+
29+
Most agencies in DACH sell one half of visibility and are vague about the other. This one sells both, and is specific about the difference: classic search (sitemap, schema, indexation, quotable content) and AI assistants (being the source an assistant reads and repeats).
30+
31+
The claim a neighbouring agency could not truthfully copy: the operator publishes the tooling being used, including a public statement of what does *not* work — `llms.txt` does nothing for Google. Competitors sell AI visibility without being able to demonstrate they understand it; this one has published open-source software for it.
32+
33+
## Operating Context
34+
35+
- Delivery is remote across DACH. Geography is deliberately absent from the offer: no city, no catchment area, no "kommt vorbei".
36+
- Contact happens on Telegram, not email or a web form.
37+
- Work is sold as fixed-scope packages in CHF and EUR, not hourly.
38+
- The business is run by one person, working alone. Copy must not imply a team or an agency.
39+
- German is the primary language. English exists for developers and international visitors.
40+
- The site is built with the same stack and the same tooling the services sell.
41+
42+
## Capabilities and Constraints
43+
44+
- Static site, no server, no database. Any contact mechanism must work without a backend.
45+
- German at the root, English at `/en/`, with `hreflang` between them.
46+
- Legal pages required: Impressum and Datenschutzerklärung. No third-party scripts that would require a consent banner if avoidable.
47+
- Prices are published. Derived from researched DACH market data (see Evidence), not invented.
48+
- No location may be published: no city, no canton, no region of residence.
49+
- **Explicitly undecided:** the custom domain. `relaystack.ch` and `relaystack.de` are both available but the user does not want one yet.
50+
- **Explicitly undecided:** whether any client work will ever be published with names or numbers.
51+
52+
## Brand Commitments
53+
54+
- Name: RelayStack. Existing bio: "Astro websites & SEO for Swiss SMEs".
55+
- Voice: plain, technical, unhyped, willing to say what does not work. German copy uses formal address (*Sie*).
56+
- Telegram is the contact channel: `https://t.me/relaystack`.
57+
- Verified brand assets: none beyond the name. No logo, no wordmark, no palette exists yet. Nothing may be reused from the unrelated `buweb.ch` project.
58+
59+
## Evidence on Hand
60+
61+
Real and linkable:
62+
- `astro-seo-toolkit` — published on npm as `astro-seo-toolkit@0.5.0`, MIT, 33 tests, an Astro integration and eight CLI bins. https://github.com/RelayStack/astro-seo-toolkit
63+
- `astro-local-business` — public Astro starter for local service businesses, MIT.
64+
- `smmscout-data` — public dataset of SMM panels with measured latency and risk scores.
65+
66+
Market research for pricing (DACH, 2026), to be used as-is and attributed:
67+
- 7-page KMU website: freelancer average CHF 2'100, small agency CHF 6'800, mid CHF 15'200, large CHF 29'500; 31 offers ranged CHF 790–47'500 (Zürich price study, 2026)
68+
- Swiss KMU web design typically CHF 1'500–7'000; ongoing CHF 40–150/month
69+
- Google Business Profile optimisation in Switzerland: CHF 990–5'000; local SEO audit + optimisation package CHF 2'400
70+
- Swiss SEO retainers CHF 3'000–7'000/month; smaller local work from CHF 500/month
71+
- German SEO retainers: local €1'000–2'000/month, mid-market €2'000–4'000/month
72+
- SEO hourly, DACH: freelancers €70–150, agencies €90–180; Switzerland CHF 150–260
73+
- AI visibility (GEO), emerging and US-led: one-time audit $500–2'000, monitoring $500–1'500/month
74+
75+
**Absences this build must not fabricate:**
76+
- No testimonials, no client names, no case studies, no client counts. Client work may be described by sector only, without names or numbers.
77+
- No performance guarantees, no "120-day guarantee", no "or you pay nothing".
78+
- No "10+ years experience", no team, no office, no awards, no certifications.
79+
- No invented metrics of any kind — no percentages, no lead increases, no traffic claims.
80+
81+
## Product Principles
82+
83+
1. **Never invent proof.** Anonymity is chosen, so credibility must come from real, verifiable artefacts — the open-source tooling and the published market data — not from claims.
84+
2. **Say what does not work.** Naming the limits of a service (as with `llms.txt` and Google) is the differentiator, not a weakness to be managed.
85+
3. **Sell the outcome, show the mechanics.** Business owners buy enquiries; the technical detail is evidence, not the pitch.
86+
4. **One conversation beats all vanity metrics.** Every surface points to a single, low-friction next step: asking a question on Telegram.
87+
5. **Practice what is sold.** The site must itself be fast, schema-correct, and legible to AI assistants.
88+
89+
## Accessibility & Inclusion
90+
91+
No product-specific requirement was established. Follow the platform baseline: semantic HTML, keyboard-operable, visible focus states, sufficient contrast, and respect for `prefers-reduced-motion`.

‎astro.config.mjs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @ts-check
2+
import { defineConfig } from "astro/config";
3+
4+
// The site is served from GitHub Pages for now. Every canonical URL, sitemap
5+
// entry and schema `url` is derived from this, so it must be correct.
6+
//
7+
// No @astrojs/sitemap: sitemap.xml, robots.txt and llms.txt are native
8+
// endpoints built from the same content collections as the pages, so they
9+
// cannot drift from what the site actually serves.
10+
export default defineConfig({
11+
site: "https://relaystack.github.io",
12+
trailingSlash: "always",
13+
build: { inlineStylesheets: "auto" },
14+
});

0 commit comments

Comments
 (0)