i18n(admin,settings): copy consistency sweep

Several smaller A8 copy nits in one pass:

- Notifications settings subtitle no longer hard-codes "Telegram,
  ntfy, Web Push" — the channel-reliability board only shows
  configured channels, so naming all three made one of them look
  missing.
- Admin /feedback page subtitle widened to "feedback, bug reports,
  and feature requests" so it matches what the inbox actually
  contains; the duplicate card-level title + description on
  /admin/feedback is gone (page header already provides them).
- /admin/services subtitle now mentions integrations alongside
  notification channels (the API and moodLog toggles live there
  too); per-row "system-wide" suffixes dropped — the section
  subtitle already establishes the scope.
- /admin/ai-quality subtitle reads as a sentence instead of the
  jargon "(severity x provider)" expression.
- /admin/feedback empty state is "All caught up" / "Alles erledigt"
  instead of the English-idiom "Inbox zero".
- /achievements subtitle rewritten in both EN + DE to drop the
  dev-speak "from feature rollout onward".
- /admin/api-tokens permission badges show "All" (with a tooltip)
  instead of the bare regex glob `*`.
- Brand spelling normalized: every Glitchtip → GlitchTip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc-André BombeckandClaude Opus 4.7 committed 2026-05-10 13:47:51 +02:00
1 parent 1f4d6a28a5
commit 3f6e670894
5 files changed
+57 -42

No files matched your search

@@ -109,7 +109,10 @@ describe("ApiTokenOverviewSection — responsive", () => {
// last-used/created labels are all present.
expect(html).toContain("marc"); // username
expect(html).toContain("iOS app"); // token name
expect(html).toMatch(/\*/); // permission badge content
// F-19 (v1.4.19): the wildcard `*` permission renders as the
// human-readable "All" with a tooltip explaining the semantics,
// not the literal asterisk.
expect(html).toContain("All");
});
it("uses a smaller card padding on mobile (p-4 sm:p-6)", () => {
@@ -162,9 +162,13 @@ export function ApiTokenOverviewSection() {
key={p}
variant="secondary"
className="max-w-full truncate text-xs"
title={p}
title={
p === "*"
? t("admin.tokenPermissionAllTooltip")
: p
}
>
{p}
{p === "*" ? t("admin.tokenPermissionAll") : p}
</Badge>
))}
</div>
@@ -254,9 +258,13 @@ export function ApiTokenOverviewSection() {
key={p}
variant="secondary"
className="max-w-full truncate text-[10px]"
title={p}
title={
p === "*"
? t("admin.tokenPermissionAllTooltip")
: p
}
>
{p}
{p === "*" ? t("admin.tokenPermissionAll") : p}
</Badge>
))}
</div>
@@ -74,13 +74,13 @@ export function FeedbackInboxSection() {
return (
<div className="bg-card border-border rounded-xl border p-6">
{/* v1.4.19 A8 / F-08 + F-20: this is the only card on
`/admin/feedback`, so the page header already provides the
title + description — the card-level repetition was just
visual noise. The icon stays as a low-key card affordance. */}
<div className="flex items-center gap-2">
<Inbox className="text-primary h-5 w-5" />
<div className="text-lg font-semibold">{t("admin.feedback.title")}</div>
<Inbox className="text-primary h-5 w-5" aria-hidden="true" />
</div>
<p className="text-muted-foreground mt-1 text-xs">
{t("admin.feedback.description")}
</p>
<Tabs
value={activeStatus}