From 5321f7054043d3eb561db2b39315c6d401d19901 Mon Sep 17 00:00:00 2001 From: Bendik Aagaard Lynghaug Date: Wed, 29 Jul 2026 12:51:55 +0200 Subject: [PATCH] Initial content: opener, project, subscribed, applied --- README.md | 49 +++++++++++++++++++++++++++ questions/applied.yaml | 18 ++++++++++ questions/index.yaml | 70 +++++++++++++++++++++++++++++++++++++++ questions/project.yaml | 16 +++++++++ questions/subscribed.yaml | 14 ++++++++ 5 files changed, 167 insertions(+) create mode 100644 README.md create mode 100644 questions/applied.yaml create mode 100644 questions/index.yaml create mode 100644 questions/project.yaml create mode 100644 questions/subscribed.yaml diff --git a/README.md b/README.md new file mode 100644 index 0000000..449cffd --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# portal-content + +Question/alternative/feature content for the [`portal`](../portal) app, +kept in its own repo so content edits don't require a Rust rebuild or +touch app code at all. + +## Schema + +Each file in `questions/` is one `Question` (see `portal`'s +`src/content.rs` for the exact struct). A question has one or more +`alternatives`; each alternative is a small form made of `features`, +each holding zero or more `requirements` (input fields). + +```yaml +id: /some-path # matches a route; "/" is the landing page; English slugs +name: Headline +description: > + Markdown body text. +alternatives: + - name: Alternative label + description: One line explaining this path. + action: /next-question # id of the question to advance to on submit + consequence: [Button label] + features: + - name: A feature/section heading + description: Optional supporting text. + requirements: + - name: email + label: Email + type: email +``` + +`type` on a requirement is one of: `text`, `textarea`, `email`, `tel`, +`select`. Omit for plain text. Mark a requirement `optional: true` if +it isn't required. + +There is deliberately no `color`/`icon` styling here — the app has a +single brand accent variable, not per-alternative colors. And there's +no branching/criteria language yet: today a human reads submissions off +NATS and decides what happens next. If that grows into something an LLM +posts follow-up questions into later, it publishes into the same shape +these files already are — this repo's format doesn't need to change for +that, just its source. + +## Adding a question + +Drop a new `questions/.yaml` file and reference its `id` from an +existing alternative's `action`. No registration step - the app loads +every file in the directory at startup. diff --git a/questions/applied.yaml b/questions/applied.yaml new file mode 100644 index 0000000..1341a7c --- /dev/null +++ b/questions/applied.yaml @@ -0,0 +1,18 @@ +id: /applied +route: ^/applied +name: Thanks — it's in front of us +description: > + Someone here will actually read this and write back. If it's a + match, you'll get a personal invite next, not an automated welcome + email. +alternatives: + - name: What happens now + description: "" + features: + - name: A person reads it + description: No filter decides for us. + - name: You get an invite, not an account + description: > + If it's a match, we hand you a real key that gives you + access and a bit of responsibility — and, eventually, the + ability to invite the next person yourself. diff --git a/questions/index.yaml b/questions/index.yaml new file mode 100644 index 0000000..92e6b89 --- /dev/null +++ b/questions/index.yaml @@ -0,0 +1,70 @@ +id: / +name: We build things worth using +description: > + Software, run the way a connoisseur pours a drink: slowly enough to + notice what's actually there. Three ways in — pick the one that fits. +alternatives: + - name: I want something built + description: > + Infrastructure, tools, or a product that needs an owner who reads + the whole glass before writing tasting notes. + action: /project + consequence: [Tell us what you're after] + encouragements: + - No proposal mill — a real reply from a person who read it. + features: + - name: What are you after? + description: A few lines is plenty to start a conversation. + requirements: + - name: name + label: Name + - name: email + label: Email + type: email + - name: project + label: What do you need built? + type: textarea + placeholder: The shape of it, not a spec — we'll ask questions. + + - name: Keep me posted + description: > + Occasional notes on what we're building and why. No funnel, no + growth-hacked cadence. + action: /subscribed + consequence: [Subscribe] + features: + - name: Where to send it + description: "" + requirements: + - name: email + label: Email + type: email + + - name: I want in + description: > + We onboard collaborators the same deliberate way we build — + by hand, with a real conversation, not a form that vanishes into + a queue. + action: /applied + consequence: [Apply] + encouragements: + - Every application gets read by a person, not a filter. + features: + - name: Who are you? + description: "" + requirements: + - name: name + label: Name + - name: email + label: Email + type: email + - name: What draws you here? + description: "" + requirements: + - name: interest + label: What do you want to work on? + type: textarea + - name: note + label: Anything else worth knowing + type: textarea + optional: true diff --git a/questions/project.yaml b/questions/project.yaml new file mode 100644 index 0000000..11b89ad --- /dev/null +++ b/questions/project.yaml @@ -0,0 +1,16 @@ +id: /project +route: ^/project +name: Got it +description: > + That's on its way to a real inbox, not a CRM stage. Expect a reply + from a person within a couple of days. +alternatives: + - name: What happens now + description: "" + features: + - name: We read it + description: Properly — before we write back, not while we write back. + - name: We ask questions + description: > + Usually more of them than you expect. Good software starts + with a good argument about what it's actually for. diff --git a/questions/subscribed.yaml b/questions/subscribed.yaml new file mode 100644 index 0000000..0f0082d --- /dev/null +++ b/questions/subscribed.yaml @@ -0,0 +1,14 @@ +id: /subscribed +route: ^/subscribed +name: You're on the list +description: > + We'll write when there's something worth your time — that's the + whole promise. +alternatives: + - name: What to expect + description: "" + features: + - name: Rare, not routine + description: No weekly filler. A few notes a year, maybe. + - name: Easy to leave + description: Every note has a real unsubscribe link, not a maze.