From 1a7152a7af7d6151df128b5c091deed7596120d1 Mon Sep 17 00:00:00 2001 From: Jakob Wennberg <149234542+jakobwennberg@users.noreply.github.com> Date: Mon, 27 Jul 2026 16:41:22 +0200 Subject: [PATCH] feat(settings): skyline masthead on Abonnemang + AI works-with marks on API tab (#1241) The Abonnemang tab gets a quiet decorative masthead: the marketing site's halftone Stockholm skyline as a wide banner strip on the frame tint, waterline pinned to the strip's bottom edge (same physics as the onboarding backdrop). Shown in every billing state; purely decorative. The API tab's "Anslut MCP-klient" group gets a works-with strip using the site's monochrome halftone Claude and OpenAI marks (copied into public/illustrations and registered in the shared manifest), with a bilingual caption. Co-authored-by: Claude Fable 5 --- DECISIONS.md | 2 + .../onboarding/onboarding-illustrations.ts | 2 + components/settings/ApiKeysPanel.tsx | 29 +++++++++++++ .../sections/BillingSettingsContent.tsx | 38 +++++++++++++++++- messages/en.json | 1 + messages/sv.json | 1 + public/illustrations/logo-claude.webp | Bin 0 -> 1380 bytes public/illustrations/logo-openai.webp | Bin 0 -> 1680 bytes 8 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 public/illustrations/logo-claude.webp create mode 100644 public/illustrations/logo-openai.webp diff --git a/DECISIONS.md b/DECISIONS.md index aff2d482..5eb54cca 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -609,3 +609,5 @@ One line per decision: `[YYYY-MM-DD] : `. Appended by agents and [2026-07-27] POSTHOG_SECRET_API_KEY is server-only (no NEXT_PUBLIC_ prefix) and the HMAC is computed in the dashboard layout; only the derived per-user hash reaches the browser. The key signs identity hashes AND authenticates external API requests, so it is a real credential unlike the phc_ project token, which is public by design and embedded in the client bundle. [2026-07-27] Support ticket free-text is declared as its own data category (user.content.support) in .compliance/ropa.yaml and named on the privacy page, separate from analytics. Analytics events deliberately carry no message body (the breadcrumb sends only the subject), but a ticket carries what the user wrote, because that is the point of writing to support. Keeping the two purposes distinct is what stops the privacy page drifting out of date the way the Recapt row did. [2026-07-27] Removed the granular "BFNAR 2013:2 punkt 9.x" citations from public/docs/systemdokumentation-mall.md instead of renumbering them to kap 8: the swedish-accounting-compliance skill and our own route comments both place systemdokumentation in kap 8, the template asserted kapitel 9 with a full point-by-point mapping (9.1, 9.2, 9.3-9.5, 9.6-9.8, 9.9, 9.16), and neither could be verified against BFN's actual text from here. A downloadable statutory template is the wrong place to guess a legal citation, and a wrong precise cite is worse than a correct general one, so the doc now cites BFL 5 kap. 11 § and BFNAR 2013:2 without pinning points. Restore the points once someone confirms the chapter against the standard. +[2026-07-27] Abonnemang masthead uses the halftone Stockholm skyline, not key-adding-machine and no new asset: the wide engraving crops cleanly into a banner strip (waterline pinned to the bottom edge, same physics as the onboarding backdrop) while the machine vignette read noisy and lopsided at banner crop; screenshots of both compared before choosing. +[2026-07-27] The requested Claude/OpenAI logos went into the API tab's "Anslut MCP-klient" group as a quiet works-with strip, using the marketing site's monochrome halftone marks instead of the raw colored brand tiles: full-color trademark tiles would fight the editorial monochrome chrome, and the halftone versions already exist as shared brand assets. diff --git a/components/onboarding/onboarding-illustrations.ts b/components/onboarding/onboarding-illustrations.ts index 6705c0c9..8e74c3ee 100644 --- a/components/onboarding/onboarding-illustrations.ts +++ b/components/onboarding/onboarding-illustrations.ts @@ -6,6 +6,8 @@ export const ILLUSTRATIONS = { 'about-stockholm': { w: 2648, h: 1318 }, calculator: { w: 745, h: 525 }, 'key-adding-machine': { w: 1650, h: 1318 }, + 'logo-claude': { w: 524, h: 525 }, + 'logo-openai': { w: 518, h: 525 }, notebook: { w: 636, h: 525 }, pencil: { w: 542, h: 525 }, } as const diff --git a/components/settings/ApiKeysPanel.tsx b/components/settings/ApiKeysPanel.tsx index 74215b5b..e8130d8b 100644 --- a/components/settings/ApiKeysPanel.tsx +++ b/components/settings/ApiKeysPanel.tsx @@ -30,6 +30,7 @@ import { Loader2, Plus, Copy, Check, Trash2, Key, ChevronDown, AlertTriangle } f import { cn, formatDateLong } from '@/lib/utils' import { copyToClipboard } from '@/lib/browser/copy-to-clipboard' import { getBranding } from '@/lib/branding/service' +import { ILLUSTRATIONS, illustrationSrc } from '@/components/onboarding/onboarding-illustrations' import { STAGING_SCOPES } from '@/lib/auth/api-keys' import type { ApiKeyScope } from '@/lib/auth/api-keys' @@ -474,6 +475,34 @@ export function ApiKeysPanel() { + {/* The marketing site's halftone AI marks (Claude, OpenAI): a quiet + "works with" cue, not chrome. Text carries the meaning; the marks + are decorative. */} +
+
+ {/* eslint-disable-next-line @next/next/no-img-element */} + + {/* eslint-disable-next-line @next/next/no-img-element */} + +
+

{t('works_with_ai')}

+
+ {/* Anchored so the skyline's waterline sits on the strip's bottom edge + (the water reflection falls below it), spires reaching up into the + strip: same physics as the onboarding backdrop. */} + {/* eslint-disable-next-line @next/next/no-img-element */} + + + ) +} + function FeatureList({ heading, items }: { heading: string; items: string[] }) { return (
@@ -149,7 +180,12 @@ export function BillingSettingsContent() { return () => { active = false } }, [reloadKey, errorLocale]) - const header = + const header = ( + <> + + + + ) if (!view) { return ( diff --git a/messages/en.json b/messages/en.json index 55795eab..a73bcc90 100644 --- a/messages/en.json +++ b/messages/en.json @@ -2139,6 +2139,7 @@ "copy_aria": "Copy", "copy_failed": "Could not copy. Select the text above and copy it manually.", "connect_mcp_title": "Connect MCP client", + "works_with_ai": "Works with Claude, ChatGPT, and other AI assistants.", "recommended_badge": "Recommended", "claude_ai_instructions": "Go to Settings → Connectors → Add custom connector and paste the MCP server URL. You sign in via your {connectorName} account: no API key needed.", "claude_code_cursor": "Claude Code / Cursor", diff --git a/messages/sv.json b/messages/sv.json index e198e36d..d1827ab0 100644 --- a/messages/sv.json +++ b/messages/sv.json @@ -2139,6 +2139,7 @@ "copy_aria": "Kopiera", "copy_failed": "Kunde inte kopiera. Markera texten ovan och kopiera manuellt.", "connect_mcp_title": "Anslut MCP-klient", + "works_with_ai": "Fungerar med Claude, ChatGPT och andra AI-assistenter.", "recommended_badge": "Rekommenderat", "claude_ai_instructions": "Gå till Settings → Connectors → Add custom connector och klistra in MCP-serverns URL. Du loggas in via ditt {connectorName}-konto: ingen API-nyckel behövs.", "claude_code_cursor": "Claude Code / Cursor", diff --git a/public/illustrations/logo-claude.webp b/public/illustrations/logo-claude.webp new file mode 100644 index 0000000000000000000000000000000000000000..f012d120f5978c959e782e8bdcce74fe2b4c2573 GIT binary patch literal 1380 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