* feat(frontend): give the project and the people their own page, and the home p…age the data
The home page was carrying two things a visitor does not open a weather app for: two paragraphs on
what Wetterdienst is, and the maintainers' avatars. Both are worth saying -- just not above the
fold of a page whose job is to get someone to their weather.
They move to a new /about page, reachable from the footer and from a link at the bottom of the home
page. There the project description gets a third paragraph (open source, MIT, free to use), the
maintainer gets a real introduction -- what he writes, that he runs the hosted instance, where he
is, how to reach him -- and Andreas stays flat: name, avatar, contact, no write-up, plus a pointer
to CONTRIBUTORS.md for everyone else. The maintainer's own paragraph is a marked placeholder with a
reminder banner, following the pattern the Impressum already uses for fields only he can fill in;
nothing about him is invented here.
What replaces it on the home page is what the app actually delivers: four headline numbers, all 22
weather services named with their flags, and the six kinds of data behind them -- measurements,
forecasts, water levels, radar, warnings, road weather. The provider list is written out rather
than fetched, because it is a static claim and not worth a request on the landing page, so
`test_frontend_home_lists_every_provider` holds it to the backend registry in both directions.
All new strings are translated into the eleven locales.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(frontend): do not claim the maintainer wrote most of the code
"and writes most of it" was my inference from the commit history, and it is not the maintainer's
account of how the web app came about. The sentence now says what is plainly true -- that he has
maintained the project since April 2020, and which parts that covers -- without a claim about
authorship.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): write the maintainer's bio, in his own account
Hydrology in Dresden from 2013 to 2020, R for the bachelor's thesis, then wanting Python and
needing something real to learn on -- which is what Wetterdienst was. It answers the question the
rest of the page raises without meaning to: why a weather library reaches into river levels and
discharge at all.
The placeholder and its reminder banner are gone with it, and the text lives in the locale files
like every other string on the page, translated into all eleven. A test asserts the page carries
the account rather than a marked placeholder.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(frontend): make the German bio read like German
Three things were off. "Hydrologie studiert, und das Interesse an Hydrologie und Meteorologie"
repeated the noun a clause later; "in R zu skripten" is Denglish where "seine ersten Skripte in R
schreiben" is the plain German; and "Wetterdienst wurde es" inverted the sentence for no reason
where "daraus wurde Wetterdienst" is the natural order. The closing sentence also leaned on a
vague "es" -- "der Bibliothek merkt man das an" says what it means.
The Hamburg variant follows, in the Perfekt that variant already uses elsewhere.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): close the home page with the values statement
It sat between the task cards and the data section, where it interrupted the path from "what would
you like to do" to "what data you get". It closes the page now, after the data and the features and
before the link to /about. The footer carries the same stance on every page regardless.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): show the maintainer's age, counted from the birthday
Next to the location in the maintainer card, from a birth date in the component rather than a
number in the copy: written down as "32" it would be wrong from the next birthday onwards, and
nobody edits an about page for that.
The date is kept as year/month/day parts rather than a `Date`: parsing "1993-11-28" yields UTC
midnight, and reading it back with local getters turns the birthday into the day before for anyone
west of Greenwich. A test pins the clock either side of 28 November and asserts 32 then 33.
Czech and Polish inflect the noun by the number -- 32 lata against 35 lat -- which vue-i18n cannot
do without per-locale plural rules, so those two read "wiek: 32" and "věk: 32", which is
grammatical at every age. The other nine take the natural form.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor(frontend): stop the home page repeating itself
The features row was written when the home page said nothing else about the data. It does now, so
two of its four cards had become echoes: "multiple data sources -- no API key or account needed"
against the 22-service card, the 0 € tile and the intro line, and "geospatial queries" against the
Explorer card directly above it.
What is left is what the page says nowhere else -- the export formats, and interpolation and
summarization, the latter rewritten to say what they actually do rather than listing stripes again.
The heading follows: "what you can do with it" is what the section lists, where "Features" invited
exactly the padding it accumulated.
The keys are renamed from the positional feature1..4 to featureExport and featureAnalysis, so a
later addition cannot land in a numbered slot whose meaning has drifted.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs(frontend): merge the duplicated Unreleased sections
The Unreleased block had grown two "Added" and two "Changed" headings: the existing entries were
ordered Fixed, Changed, Added, and my new ones went in above them under headings of their own
rather than into the sections that were already there. One heading each now, in Keep a Changelog's
order, with no entry text touched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor(frontend): take Support out of the task navigation
The navigation mixed two kinds of destination: things you do with weather data -- forecast,
stripes, explorer, history, api, glossary -- and one thing about the project. That is why About had
nowhere obvious to go: adding it would have made the mixture worse and the bar nine entries long.
Support joins About and the legal notice instead, and the navigation is seven entries with one rule
between them. Support does not simply get quieter for it: it moves to the header's project links as
a heart, which is where "sponsor this project" is conventionally found and is one click from every
page, and it gains a footer link. The mobile menu renders the same nav array, so the bottom bar
carries the heart too -- otherwise the hamburger would have lost Support entirely.
The e2e test clicked "Support" by role from the home page; there are two such links now, so it
scopes to the header and the footer and asserts both routes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): split the footer into two rows by kind
Six items on one line, one separator, one weight: the values statements read as two more entries in
a link list. They are a statement, so they get their own row, and the copyright and links keep the
other. Pipes become middots, and the stance row drops separators entirely in favour of wider gaps.
The separators are flex siblings with no idea where a line breaks, so a wrapped row used to end on
a dangling "|" -- and after the split the links row still began a wrapped line with an orphan "·"
at 390 px. Below the `sm` breakpoint that row now drops its separators and widens the gap instead,
which is checked at 390, 768 and 1280.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): reserve the hover lift for cards that are links
The home page had three kinds of card and two hover behaviours, split down the wrong line: the task
cards lifted and ringed, the stat tiles, service list and data kinds did not, and the two feature
cards lifted like the task cards while being plain text. A hover state is how a card promises it is
a link; those two promised and did nothing.
Hover now means clickable, on this page and on /about, where the only hovers left are the two
avatars that link to GitHub.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): say that the maintainer founded Wetterdienst, in fewer words
The bio ran three sentences to arrive at the project sideways -- bachelor's thesis, then R, then
wanting Python, then Wetterdienst "became" the thing to learn on. Two sentences now, with the
founding as the fact the paragraph turns on, and the hydrology kept because it is what explains a
weather library carrying river levels and discharge.
The paragraph above it loses "since April 2020, days after the project started": that phrasing said
someone else started the project, and the date belongs to the bio now.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(frontend): make the German about copy read like German
The bio: "nach dem R seiner Bachelorarbeit" gives a programming language an article and a genitive
and reads like a translation; the founding sat behind its object rather than behind the time. It is
"im April 2020 Wetterdienst gegründet: ein Projekt, an dem er Python lernen wollte, nachdem er für
seine Bachelorarbeit mit R angefangen hatte" now, and "die Hydrologie ist ihm geblieben", which is
how that is said.
Two more: "die gehostete Instanz" is Denglish where "die öffentliche Instanz" is the plain German,
and "frei nutzbar -- auch diese gehostete App" trailed the same word twice in three lines, so it
closes with "diese App eingeschlossen".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(frontend): a maintainer pflegt rather than betreut
"betreuen" is what one does with people, patients and theses. German open source says a maintainer
"pflegt" a project and "entwickelt es weiter", which is also the pair that covers what the sentence
lists -- keeping the library running and moving it forward.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): the maintainer invented Wetterdienst, and the card says so once
The role reads "Erfinder und Maintainer" / "Creator and maintainer", and the bio opens with it:
"Benjamin hat Wetterdienst erfunden und entwickelt es bis heute weiter."
That made the paragraph above it redundant twice over. "Benjamin pflegt Wetterdienst und entwickelt
es weiter" said the same thing in other words, and its list -- library, REST API, command-line
client, web app -- is already in the project card two paragraphs up. It is gone, and the card now
runs bio, then the hosted instance, which is the only fact left that neither the role nor the
project card carries.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): the bio says the degree and the day job
"Studierte von 2013 bis 2020" described the years rather than what came of them. The MSc in
hydrology, finished in Dresden in 2020, and the data engineering he has done since are the two
facts a reader wants, and they carry the same point in fewer words: the hydrology is why a weather
library has river levels in it.
The project's start date drops out with it -- the founding is already in the first sentence and in
the role above.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): run the maintainer's paragraph together
The bio and the line about the hosted instance were two paragraphs with a gap between them, which
made the card read as two half-finished blocks rather than one short write-up. They are one
paragraph now; the strings stay separate keys, since they are separate facts to translate.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): add LinkedIn and Mastodon to the maintainer card
Next to the GitHub and email buttons, since they are the maintainer's rather than the project's.
The Mastodon link carries rel="me" explicitly: that is what lets the profile on mastodon.social
verify a link back to this site and show it as confirmed. A _blank link would otherwise be given
rel="noopener noreferrer" by default, which does not include it, so both are spelled out.
Lucide has a linkedin glyph but no mastodon one, and the at-sign reads as a fediverse handle
without pulling in a second icon set for a single button.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): use the real Mastodon logo
The at-sign was a stand-in for a glyph Lucide does not have. simple-icons does, and no icon in this
app is bundled from a local collection -- there are no @iconify-json packages installed, so
i-lucide-github and the rest already resolve through Iconify, and the CSP already allows it. One
more icon from the same place, no new dependency.
Checked in the running app rather than in the markup: the button renders the logo at 104x28 rather
than the blank box a missing icon leaves behind.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): give the co-author the same card as the maintainer
Both people render from one shape now -- avatar, role, paragraph, links -- rather than one write-up
and one name with an email under it. What differs is the facts, not the layout.
Andreas' paragraph comes from two places and nowhere else: this repository's own record, where his
373 commits since June 2020 sit in continuous integration, packaging, the radar tests and the docs,
and what he has published about himself -- his pinned projects, and the tagline about keeping
systems healthy that the paragraph paraphrases.
What his card does not carry is as deliberate. No employer: a web page says Crate.IO, the GitHub
API says `company: null`, and the API is the source he controls. No location or age: his profile's
location field is the joke `$PYTHONPATH`. No LinkedIn or Mastodon: he lists neither, and a guessed
profile link points strangers at a stranger.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): stop the people cards naming the role twice
A card headed "Maintainer" whose first line reads "Erfinder und Maintainer", and one headed
"Co-author" over "Co-Maintainer". The headers said less than the lines beneath them, so they are
gone, replaced by one "the people behind it" above both cards. `maintainerTitle` and
`coAuthorTitle` go with them in all eleven locales rather than being left as dead strings.
The heading structure reads About Wetterdienst / The people behind it / Links, with each person an
h3 under the group heading -- which is also the more honest outline than two h2s that both meant
"a person".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): put both people in one card, like the sections around them
Removing the per-person card headers left "the people behind it" as a bare heading between two
bordered, rounded cards, so it read as belonging to neither. The two people share one card with
that heading now, separated by a rule, and the page is three sections of the same shape again --
about, people, links.
The role is still stated once, in the line under each name, which is what removing those headers
was for.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): the co-author is in Berlin
From the maintainer, who works with him. It is the same granularity the maintainer's own card
carries, and his GitHub profile gives no location -- its location field is the joke `$PYTHONPATH`.
No age beside it: he has not published one anywhere, and a person's age is not a thing to go
looking for on his behalf.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): the contributors line belongs to the project, not to the co-author
It sat inside Andreas' block behind a `v-if="person.key === 'coauthor'"` -- a per-person template
carrying a paragraph that was never about that person, and which read as a footnote to his
biography, as though the others had contributed alongside him rather than to the project.
It closes the card now, below both people and their rule, where "many more people" means what it
says.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): LGBTQI+ rather than LGBTQ+
The I is intersex people, and leaving it out of a solidarity statement is the kind of omission the
statement exists to refuse. All eleven locales.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): add the climate line to what the project stands for
"Erderwärmung ist keine Meinung." / "Global warming is not an opinion."
The two statements already there are moral positions anyone can hold. This one is a claim only a
weather-data project can make with authority: it serves the measurements, and the warming stripes
are two clicks away. It is also a refusal rather than a request, which is the register the band is
already in.
The README has opened with "What do we want? Climate Justice! When do we want it? Now!" since the
beginning, and nothing in the app said anything about climate at all.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): all four values in the footer, spelled out on hover
The footer carried two of the four, in short forms of their own ("Love who you want", "FCKNZS"),
while the home page spelled all four out. Two wordings of the same statement in two places is a
drift waiting to happen, and four sentences at the foot of every page is a banner rather than a
footer.
Both now read from one `values` section per locale, and the footer shows the four as icons with the
full sentence on hover. Hover is not an accessibility story, so each carries role="img" and an
aria-label with that same sentence: a screen reader gets the words, and so does keyboard focus.
Removing `footer.lgbtq` and `footer.antifascist` from the locales before updating the template made
`@intlify/vue-i18n/no-missing-keys` fail the lint, which is the guard working.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): name the two open-source programmes behind the project
JetBrains for a PyCharm licence, Anthropic for a Claude Max subscription, as badges between the
features and the values band -- in the same rounded-chip shape the 22 weather services wear above,
so the page has one vocabulary for a list of names. Each links to the programme and says what it
gives on hover.
On the home page rather than on Support: the page that asks for nothing is where naming who already
gives reads as gratitude, while on the page that asks it reads as leverage.
The hover is a native `title` rather than `UTooltip`. UTooltip needs the `UApp` provider, which the
running app has and an isolated page mount does not -- adding it broke all seven home page tests
with a render error. `title` plus `aria-label` needs no ancestor and is the accessible name either
way; the footer keeps UTooltip, where the provider is genuinely present.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): give the end of the home page a structure
Three blocks in a row, three different treatments: a thin section of two cards, badges floating in
bare whitespace with no container or heading, then the gradient band. Nothing grouped them, so the
page stopped looking organised exactly where it should have felt finished.
"What you can do with it" is a subsection of the data block now -- it is still about the data, and
as a peer heading over two cards it read as a stub after the block above it. The supporters moved
inside the closing band under a rule, so one block closes the page with what the project stands for
and who backs it. Their heading is a real h3 rather than a muted paragraph, which also puts them
back in the document outline.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* style(frontend): two closing bands, one gloss
"Wofür wir stehen" and the supporters shared a box, with the second half reading as a footnote to
the first. They are two bands now, carrying the same gradient and the same border, told apart by
the gap between them: two statements the project makes about itself, of equal weight.
The supporters heading is an h2 again with it -- its own section rather than a subheading -- and it
drops "bereits" in all eleven locales: "Unterstützt von", "Supported by", "Soutenu par".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): point developers at the library, the API and MCP
The home page linked to four routes and none of them said the data was reachable without clicking:
the Python library the project started as, the REST API the app itself runs on, and the MCP
endpoint. They are three chips now, in the shape the weather services and the supporters already
use.
The glossary link goes where the "514 parameters" claim is made, so the number leads to the page
that explains what each one measures.
The chips are NuxtLink throughout. Switching the component per entry with `resolveComponent` in the
template rendered two of the three as plain text rather than links -- and the test passed anyway,
because it asserted the words. It asserts href and label together now.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat(frontend): serve the API reference on this origin, and point the chips at it
The REST API chip pointed at the page describing the API rather than at the API, and there was
nowhere better to send it: `/docs` on the app's origin answered with the SPA shell, because only
`/api/**` and `/mcp` were proxied. Swagger UI lives on the backend, which is not published.
`/docs` and `/openapi.json` are proxied now, in the same shape as the data proxy -- GET only, no
client headers forwarded, and the backend's `set-cookie`, `alt-svc` and `server` stripped, since
those describe the backend rather than this origin. Both were needed: Swagger fetches its schema
from the origin root, so proxying the page alone would have rendered an empty one.
The chips point at this instance now: PyPI, `/docs`, `/mcp`. All three are `external` links --
nitro serves the last two, so a client-side navigation would land on the SPA's 404 instead. The MCP
chip carries a hover line saying it is an endpoint rather than a page, because a browser GET
answers 400 by design and a link that looks broken is worse than one that explains itself.
Verified against the running stack: /docs returns Swagger (not the shell), /openapi.json is a 3.1.0
schema with 17 paths including /api/coverage. Two e2e cases assert both.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs(frontend): correct and refile the Unreleased entries
Three faults of my own making, found by reading the section back rather than the diffs:
- the About entry read "and a the same for the co-author", a word left behind by an in-place edit
- the tail entry opened "is one block rather than three" and then described two bands, because the
bands were split after the entry was written
- four entries sat under Changed that describe things that did not exist before: the /docs proxy,
the developer row, the supporters badges and the third values statement
The developer row also now mentions the glossary link, which went in with it and was unrecorded.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(frontend): one Hamburg register instead of three
The de-hh catalog mixed Hamburger Platt, Missingsch and plain informal German. Wikipedia's article
on the Hamburger Dialekt separates exactly those: Platt is the historical Low German language and
is rarely spoken now, Missingsch is High German vocabulary on Low German grammar, and Hamburgisch is
High German with the regional layer -- the loanwords, the particles, the lenition.
Sixteen strings were written in full Platt: "Wat jeder Parameter misst un in welke Eenheit de
Weerten torüchkaamt", "Warrt laadt…", "Keen Parameter passt to de Söök", "Datenanfraag is
fehlslaan". They sat between High German ones, so the catalog changed language mid-page and lost
readers who read German but not Platt.
A further fourteen still said "Sie", inherited unchanged from de, against sixteen that said "du".
Everything is Hamburgisch now: High German structure, "du" throughout, "nich" and "is" and "guck"
and "such dir" where a Hamburger would say them, and the loanwords that are genuinely current
(Klönschnack, Tüdelkram, schnacken, "denn man tau") kept where they already were. Heavy eye-dialect
is deliberately not reproduced -- "bidde" for "bitte", "hassu" for "hast du" -- because a UI label
is read, not heard, and the article's phonetic features do not survive being written down.
"Moin" also stops prefixing the solidarity statement: it is a greeting, and one belongs on the
start page, not in front of "wir stehen an der Seite der LGBTQI+-Community".
83 of 570 strings now differ from de, up from 73, and none of them differ by being another
language.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(frontend): Hamburg nouns, German syntax, in the last three strings
The register sweep caught full sentences and missed phrases. "Offene Wetterdaten för de Lüüd" is
Low German preposition, article and noun, on a page that says "die Lüüd dahinter" a screen further
down; the two parameter-restriction errors carried "bi dit", "för dissen" and "Dat" the same way.
German syntax with the Hamburg word in it, which is what the rest of the catalog does: "für die
Lüüd", "is bei diesem Backend nich verfügbar".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>