From 5961d969b1c472de57c6af974b2f0441713219ea Mon Sep 17 00:00:00 2001 From: Khalid Abdi Date: Wed, 15 Jul 2026 20:23:33 +0300 Subject: [PATCH] frontend: give settings frames the COSS default padding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Clinician profile frame inset its content 40px and drew a second border around it — a box inside a box. Both came from CardFramePanel, added in 44d653f. It doesn't exist in the COSS registry: upstream @coss/card ships Card, CardFrame, CardFrameHeader/Title/Description/ Action/Footer and nothing else. There is no body part because the frame isn't meant to pad its body. CardFrame styles its cards through *direct-child* selectors — -m-px, the clip-path, rounded-t/b-xl, shadow-none, before:hidden — pulling each card out by a pixel so it sits flush inside the frame's own border. The panel wrapper made every card a grandchild, so none of those selectors matched: the 20px came from the panel's p-5, the second border came from the card keeping the treatment the frame was supposed to suppress. The commit that added it claimed the cards would "pick up the frame's card treatment"; they never did. Drop the panel and render children directly inside the frame, which is the COSS default. Body padding goes on the Card, where COSS puts it, so content is inset once rather than twice. Card-bearing bodies now get the frame treatment they were meant to have, and the divide-y lists in Records, Care team and Signing stack flush, which is what -m-px and rounded-t-xl were for. The notification ToggleRows lose their space-y wrapper and read as one list. Frames holding raw form content (the AI panel, Care team's error and toolbar) get an explicit padded Card instead of leaning on the frame. card.tsx is now upstream @coss/card verbatim, minus font-heading on CardTitle. Co-Authored-By: Claude Opus 4.8 --- frontend/components/settings/settings-ai.tsx | 43 ++++++++++------- .../settings/settings-care-team.tsx | 10 ++-- .../components/settings/settings-parts.tsx | 34 ++++++------- .../settings/settings-preferences.tsx | 48 +++++++++---------- frontend/components/ui/card.tsx | 20 -------- 5 files changed, 70 insertions(+), 85 deletions(-) diff --git a/frontend/components/settings/settings-ai.tsx b/frontend/components/settings/settings-ai.tsx index 3f395fa..695eb3b 100644 --- a/frontend/components/settings/settings-ai.tsx +++ b/frontend/components/settings/settings-ai.tsx @@ -15,6 +15,7 @@ import { } from "@/components/ui/select"; import { FieldLabel, + SettingsCard, SettingsFrame, ToggleRow, } from "@/components/settings/settings-parts"; @@ -209,7 +210,6 @@ export function AIPanel() { <> {policy ? ( @@ -238,7 +238,7 @@ export function AIPanel() { /> ) : null} {policyDirty ? ( -
+
+ ) : null} ) : ( -

- {policy.aiEnabled - ? policy.disabledForEmployees - ? t("settings.ai.availability.readonlyEmployeesOnly") - : t("settings.ai.availability.readonlyEnabled") - : t("settings.ai.availability.readonlyDisabled")} -

+ +

+ {policy.aiEnabled + ? policy.disabledForEmployees + ? t("settings.ai.availability.readonlyEmployeesOnly") + : t("settings.ai.availability.readonlyEnabled") + : t("settings.ai.availability.readonlyDisabled")} +

+
)}
) : null} @@ -267,7 +269,7 @@ export function AIPanel() { description={t("settings.ai.modeDescription")} title={t("settings.ai.modeTitle")} > -
+ {t("settings.ai.mode")}
+ ) : ( +
{t("settings.ai.ollamaBaseUrl")} @@ -432,15 +437,16 @@ export function AIPanel() { ? t("settings.ai.testing") : t("settings.ai.testConnection")} + )} {config.mode !== "off" ? ( +
{t("settings.ai.veilLevel")}