From 1d3ba956cbd6dbd8c25024c74e55931911bd8354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20Sch=C3=A4fer?= Date: Thu, 16 Jul 2026 00:05:23 +0200 Subject: [PATCH 1/2] feat(planner): restyle Export + SaveToJournal buttons on tokens Bring the two slotted topbar actions onto the design system so the bar reads as one cohesive surface: - SaveToJournalButton: primary Button primitive; "saved" uses the accent, error uses a new --color-danger token, and the return link gets secondary token styling. - ExportButton: token split-button (secondary look, chevron icon, single divider) and a token dropdown menu (raised surface, soft shadow, muted descriptions). - New --color-danger token (#a03c3c, the no-go hue at full strength) for error text. Behavior and i18n unchanged. Co-Authored-By: Claude Opus 4.8 --- apps/planner/app/components/ExportButton.tsx | 44 +++++++++---------- .../app/components/SaveToJournalButton.tsx | 18 ++++---- packages/ui/src/theme.css | 1 + 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/apps/planner/app/components/ExportButton.tsx b/apps/planner/app/components/ExportButton.tsx index 87ceabc..34b786c 100644 --- a/apps/planner/app/components/ExportButton.tsx +++ b/apps/planner/app/components/ExportButton.tsx @@ -52,45 +52,45 @@ export function ExportButton({ yjs }: { yjs: YjsState }) { const hasMultipleDays = hasDayBreaks(yjs); + const item = + "block w-full px-3 py-1.5 text-left transition-colors hover:bg-bg-subtle"; + const split = + "h-7 border border-border bg-bg-raised text-sm font-medium text-text-hi transition-colors hover:bg-bg-subtle focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent"; + return (
{open && ( -
- - {hasMultipleDays && ( - )}
diff --git a/apps/planner/app/components/SaveToJournalButton.tsx b/apps/planner/app/components/SaveToJournalButton.tsx index d464cf4..217d6e7 100644 --- a/apps/planner/app/components/SaveToJournalButton.tsx +++ b/apps/planner/app/components/SaveToJournalButton.tsx @@ -1,5 +1,6 @@ import { useState, useCallback } from "react"; import { useTranslation } from "react-i18next"; +import { Button } from "@trails-cool/ui"; import { computeSurfaceBreakdown } from "@trails-cool/map-core"; import type { YjsState } from "~/lib/use-yjs"; import { buildPlanGpx } from "~/lib/gpx-export"; @@ -64,17 +65,16 @@ export function SaveToJournalButton({ yjs, sessionId, returnUrl }: SaveToJournal return (
- - {saved && {t("saved")}} - {error && {error}} + + {saved && {t("saved")}} + {error && {error}} {saved && returnUrl && ( - + {t("returnToJournal")} )} diff --git a/packages/ui/src/theme.css b/packages/ui/src/theme.css index b3135d4..8bb178d 100644 --- a/packages/ui/src/theme.css +++ b/packages/ui/src/theme.css @@ -41,6 +41,7 @@ --color-stop-border: rgba(139, 109, 58, 0.25); /* ── Danger / no-go ── */ + --color-danger: #a03c3c; /* solid danger — error text, matches the no-go hue */ --color-nogo: rgba(160, 60, 60, 0.12); --color-nogo-border: rgba(160, 60, 60, 0.3); From 3603624b70b80bcf5ed154d7054e1f8a848e085f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20Sch=C3=A4fer?= Date: Thu, 16 Jul 2026 00:43:30 +0200 Subject: [PATCH 2/2] fix(planner): distinct aria-label for export dropdown toggle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The restyled Export split-button's dropdown toggle got aria-label "Export GPX", colliding with the main button's text and breaking the E2E selector that clicked the old "▾" glyph. Give it a dedicated exportOptions label (en + de) and target it in the E2E test. Co-Authored-By: Claude Opus 4.8 --- apps/planner/app/components/ExportButton.tsx | 2 +- e2e/planner-routing.test.ts | 2 +- packages/i18n/src/locales/de.ts | 1 + packages/i18n/src/locales/en.ts | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/planner/app/components/ExportButton.tsx b/apps/planner/app/components/ExportButton.tsx index 34b786c..13fbe08 100644 --- a/apps/planner/app/components/ExportButton.tsx +++ b/apps/planner/app/components/ExportButton.tsx @@ -68,7 +68,7 @@ export function ExportButton({ yjs }: { yjs: YjsState }) {