Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/app/ckb-v2-tokens.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
--measure: 68ch; /* prose measure - never wider */
--header-h: 4rem; /* 64 */

/* Responsive breakpoint tokens - standard named scale (Task #336) */
--bp-phone: 640px;
--bp-tablet: 768px;
--bp-desktop: 1024px;

/* Type - 7 steps, each with its own line-height and tracking */
--text-xs: 0.75rem;
--text-xs-lh: 1rem;
Expand Down
10 changes: 10 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@
* New overlays go through components/ui/sheet.tsx rather than a new layer.
*/
@theme {
/* Named responsive breakpoint tokens (Task #336) */
--breakpoint-phone: 640px;
--breakpoint-tablet: 768px;
--breakpoint-desktop: 1024px;

/* Radius ladder: 4 · 6 · 10 · 12 · 16 · 20 — the 4px grid with two deliberate
half-steps. `sm` is 6px, for chips and pills that read as too heavy at 8.
`md` is 10px because it is the control rung, and it is the one value the v2
Expand Down Expand Up @@ -277,6 +282,11 @@

/* Theme tokens */
:root {
/* Named responsive breakpoint tokens (Task #336) */
--bp-phone: 640px;
--bp-tablet: 768px;
--bp-desktop: 1024px;

/* Layout constraints */
--content-max-width: 1440px;
--rail-width: 480px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ export function ResultSortControl({
* floor from `sm`, exactly like the filter controls.
*/
const emptyStateAction =
"inline-flex min-h-tap items-center gap-1.5 rounded-lg border border-[color:var(--border)] px-3 text-xs font-extrabold text-[color:var(--text-muted)] hover:text-[color:var(--text)] sm:min-h-10";
"inline-flex min-h-tap items-center gap-1.5 rounded-lg border border-[color:var(--border)] px-3 text-xs font-semibold text-[color:var(--text-muted)] hover:text-[color:var(--text)] sm:min-h-10";

export function SearchResultsEmptyState({
modeId,
Expand Down Expand Up @@ -978,7 +978,7 @@ export function SearchResultsEmptyState({
<Search className="h-5 w-5" aria-hidden />
)}
</span>
<Title className="mt-3 text-sm font-extrabold text-[color:var(--text-heading)]">{emptyTitle}</Title>
<Title className="mt-3 text-sm font-semibold text-[color:var(--text-heading)]">{emptyTitle}</Title>
<p className="mt-1 text-xs font-medium text-[color:var(--text-muted)]">{emptyBody}</p>
{!filtered ? (
<div aria-live="polite" className="sr-only">
Expand All @@ -999,7 +999,7 @@ export function SearchResultsEmptyState({
onClick={lastFilter.onRemove}
data-testid="search-results-empty-remove-filter"
className={cn(
"inline-flex min-h-9 items-center gap-1.5 rounded-lg border border-[color:var(--clinical-accent-border)] bg-[color:var(--clinical-accent-soft)] px-3 text-xs font-extrabold text-[color:var(--clinical-accent)] hover:border-[color:var(--clinical-accent)]",
"inline-flex min-h-tap items-center gap-1.5 rounded-lg border border-[color:var(--clinical-accent-border)] bg-[color:var(--clinical-accent-soft)] px-3 text-xs font-semibold text-[color:var(--clinical-accent)] hover:border-[color:var(--clinical-accent)] sm:min-h-9",
focusRing,
)}
>
Expand Down
10 changes: 5 additions & 5 deletions src/components/forms/form-detail-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ function DetailCard({
<button
type="button"
onClick={onOpenDetail}
className="min-w-0 flex-1 rounded-md text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--focus-ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-[color:var(--surface-lux)]"
className="min-w-0 flex-1 rounded-md text-left focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]"
aria-label={`${label}: ${displayText(card.title)}. Open detail.`}
>
{content}
Expand Down Expand Up @@ -542,7 +542,7 @@ function PathwayContextCard({
aria-selected={activeTab === "pathway"}
onClick={() => setActiveTab("pathway")}
className={cn(
"rounded-md px-3 py-2 text-center transition",
"min-h-tap rounded-md px-3 py-2 text-center transition focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)] sm:min-h-9",
activeTab === "pathway"
? "bg-[color:var(--clinical-accent)] text-[color:var(--clinical-accent-contrast)]"
: "text-[color:var(--text-muted)] hover:bg-[color:var(--surface-subtle)]",
Expand All @@ -556,7 +556,7 @@ function PathwayContextCard({
aria-selected={activeTab === "source"}
onClick={() => setActiveTab("source")}
className={cn(
"rounded-md px-3 py-2 text-center transition",
"min-h-tap rounded-md px-3 py-2 text-center transition focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)] sm:min-h-9",
activeTab === "source"
? "bg-[color:var(--clinical-accent)] text-[color:var(--clinical-accent-contrast)]"
: "text-[color:var(--text-muted)] hover:bg-[color:var(--surface-subtle)]",
Expand Down Expand Up @@ -1066,7 +1066,7 @@ export function FormDetailPage({ form }: { form: FormRecord }) {
href={form.source.url}
target="_blank"
rel="noopener noreferrer"
className="inline-flex min-h-10 items-center justify-center gap-1.5 rounded-lg text-sm font-semibold text-[color:var(--clinical-accent)] hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]"
className="inline-flex min-h-tap items-center justify-center gap-1.5 rounded-lg text-sm font-semibold text-[color:var(--clinical-accent)] hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)] sm:min-h-10"
>
Official
<ExternalLink className="h-4 w-4" aria-hidden />
Expand All @@ -1077,7 +1077,7 @@ export function FormDetailPage({ form }: { form: FormRecord }) {
href={details.localPdfPath}
target="_blank"
rel="noopener noreferrer"
className="inline-flex min-h-10 items-center justify-center gap-1.5 rounded-lg text-sm font-semibold text-[color:var(--text-muted)] hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)]"
className="inline-flex min-h-tap items-center justify-center gap-1.5 rounded-lg text-sm font-semibold text-[color:var(--text-muted)] hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus)] sm:min-h-10"
>
Stored copy
<Download className="h-4 w-4" aria-hidden />
Expand Down
2 changes: 1 addition & 1 deletion src/components/mode-home-template.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export function ModeHomeHero({
>
<Heading
id={`${testId ?? "mode-home"}-title`}
className="text-balance text-hero font-extrabold leading-display tracking-normal text-[color:var(--text-heading)]"
className="text-balance text-hero font-semibold leading-display tracking-normal text-[color:var(--text-heading)]"
>
{title}
</Heading>
Expand Down
3 changes: 2 additions & 1 deletion tests/audit-content-services-regressions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ describe("content and services audit regressions", () => {
expect(normalizedFormDetailSource).toContain("href={form.source.url}");
expect(normalizedFormDetailSource).toContain('target="_blank"');
expect(normalizedFormDetailSource).toContain('rel="noopener noreferrer"');
expect(normalizedFormDetailSource).toContain("inline-flex min-h-10");
expect(normalizedFormDetailSource).toContain("inline-flex min-h-tap");
expect(normalizedFormDetailSource).toContain("sm:min-h-10");
expect(formDetailSource).toContain("Source link pending");
expect(formDetailSource).toContain("Official");
});
Expand Down
16 changes: 16 additions & 0 deletions tests/design-token-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -470,3 +470,19 @@ describe("focus ring", () => {
expect(body, "the shared focus rule must not paint a box-shadow").not.toContain("box-shadow");
});
});

describe("responsive breakpoint tokens (Task #336)", () => {
it("declares standard named breakpoint tokens in :root, @theme, and ckb-v2", () => {
expect(light.get("--bp-phone")).toBe("640px");
expect(light.get("--bp-tablet")).toBe("768px");
expect(light.get("--bp-desktop")).toBe("1024px");

expect(v2Light.get("--bp-phone")).toBe("640px");
expect(v2Light.get("--bp-tablet")).toBe("768px");
expect(v2Light.get("--bp-desktop")).toBe("1024px");

expect(themeConfigBlock).toContain("--breakpoint-phone: 640px;");
expect(themeConfigBlock).toContain("--breakpoint-tablet: 768px;");
expect(themeConfigBlock).toContain("--breakpoint-desktop: 1024px;");
});
});
Loading