Tighten typography and XWorkmate layout defaults
This commit is contained in:
parent
3bdcc0b147
commit
17206d02f8
40
skills/ui.typography.v1.md
Normal file
40
skills/ui.typography.v1.md
Normal file
@ -0,0 +1,40 @@
|
||||
# Skill: UI Typography Consistency
|
||||
|
||||
## When to Use
|
||||
|
||||
- Global typography tuning
|
||||
- New page or component design
|
||||
- Sidebar, form, dialog, and dashboard cleanup
|
||||
- UI refresh work that should feel closer to ChatGPT Web reading density
|
||||
|
||||
## Defaults
|
||||
|
||||
- Base body and message text: `16px` with `line-height: 1.5`
|
||||
- Sidebar, helper text, and secondary descriptions: `14px`
|
||||
- Metadata, timestamps, and micro labels: `12px` to `13px`
|
||||
- Primary page headings: `24px` to `28px`
|
||||
- Text color: use deep gray such as `#0d0d0d`, not pure black
|
||||
- Font stack: default to the project sans font and keep it consistent across all pages
|
||||
|
||||
## Steps
|
||||
|
||||
1. Start from the global tokens in [`/Users/shenlan/workspaces/cloud-neutral-toolkit/console.svc.plus/src/app/globals.css`](/Users/shenlan/workspaces/cloud-neutral-toolkit/console.svc.plus/src/app/globals.css).
|
||||
2. Keep body copy at `16px` unless the surface is explicitly metadata-heavy.
|
||||
3. Use `14px` for sidebars, helper text, chip labels, and supporting descriptions.
|
||||
4. Reserve `12px` to `13px` for timestamps, disclaimers, and low-emphasis metadata.
|
||||
5. Tighten layout density together with typography: if text gets smaller, reduce padding and corner radius proportionally.
|
||||
6. Verify at least one dense workspace page and one marketing or document page after the change.
|
||||
|
||||
## Do
|
||||
|
||||
- Do keep line height readable at `1.5` for paragraphs, lists, inputs, and buttons.
|
||||
- Do make typography decisions in the global design tokens first.
|
||||
- Do keep container radius and spacing visually consistent with the text scale.
|
||||
- Do prefer neutral grays for body text and muted text over saturated colors.
|
||||
|
||||
## Do Not
|
||||
|
||||
- Do not mix multiple body font sizes on the same page without a clear hierarchy.
|
||||
- Do not use oversized rounded corners on dense workflow surfaces.
|
||||
- Do not rely on one-off component overrides when the issue is global.
|
||||
- Do not use pure black text for normal reading surfaces.
|
||||
@ -11,19 +11,19 @@
|
||||
--app-shell-nav-offset: 5.5rem;
|
||||
|
||||
/* Light theme defaults */
|
||||
--color-background: #f4f6fb;
|
||||
--color-background-muted: #e7ecf6;
|
||||
--color-background: #f7f7f8;
|
||||
--color-background-muted: #ececef;
|
||||
--color-surface: #ffffff;
|
||||
--color-surface-elevated: rgba(255, 255, 255, 0.96);
|
||||
--color-surface-translucent: rgba(255, 255, 255, 0.88);
|
||||
--color-surface-muted: #f1f4fb;
|
||||
--color-surface-hover: #f0f4ff;
|
||||
--color-surface-border: #d6e0ff;
|
||||
--color-surface-border-strong: #b4c5ff;
|
||||
--color-text: #1e2e55;
|
||||
--color-heading: #2e3a59;
|
||||
--color-text-muted: #4a5672;
|
||||
--color-text-subtle: #61708c;
|
||||
--color-surface-translucent: rgba(255, 255, 255, 0.92);
|
||||
--color-surface-muted: #f3f4f6;
|
||||
--color-surface-hover: #f7f8fb;
|
||||
--color-surface-border: #e5e7eb;
|
||||
--color-surface-border-strong: #d1d5db;
|
||||
--color-text: #0d0d0d;
|
||||
--color-heading: #111827;
|
||||
--color-text-muted: #4b5563;
|
||||
--color-text-subtle: #6b7280;
|
||||
--color-text-inverse: #f8fbff;
|
||||
--color-primary: #3366ff;
|
||||
--color-primary-hover: #4d7aff;
|
||||
@ -45,31 +45,92 @@
|
||||
--color-info: #3366ff;
|
||||
--color-info-muted: #f0f4ff;
|
||||
--color-info-foreground: #254edb;
|
||||
--color-overlay: rgba(30, 46, 85, 0.45);
|
||||
--color-overlay: rgba(17, 24, 39, 0.42);
|
||||
--color-ring: #d6e0ff;
|
||||
--color-focus: rgba(51, 102, 255, 0.35);
|
||||
--color-divider: rgba(15, 23, 42, 0.08);
|
||||
--color-divider: rgba(17, 24, 39, 0.08);
|
||||
--color-badge-surface: #e5e7eb;
|
||||
--color-badge-muted: #f3f4f6;
|
||||
--color-badge-foreground: #1f2937;
|
||||
|
||||
--gradient-app-from: #f5f8ff;
|
||||
--gradient-app-via: #eef3ff;
|
||||
--gradient-app-to: #f4f9ff;
|
||||
--gradient-app-from: #fafafa;
|
||||
--gradient-app-via: #f4f5f7;
|
||||
--gradient-app-to: #f7f7f8;
|
||||
--gradient-primary-from: #3366ff;
|
||||
--gradient-primary-to: #254edb;
|
||||
|
||||
--shadow-sm: 0 1px 3px rgba(30, 46, 85, 0.08), 0 1px 2px rgba(30, 46, 85, 0.04);
|
||||
--shadow-md: 0 12px 32px rgba(30, 46, 85, 0.12);
|
||||
--shadow-sm: 0 1px 2px rgba(17, 24, 39, 0.06), 0 1px 3px rgba(17, 24, 39, 0.04);
|
||||
--shadow-md: 0 10px 24px rgba(17, 24, 39, 0.08);
|
||||
|
||||
--radius-lg: 1rem;
|
||||
--radius-xl: 1.5rem;
|
||||
--radius-lg: 0.875rem;
|
||||
--radius-xl: 1.125rem;
|
||||
--radius-pill: 999px;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: var(--font-geist-sans);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-geist-sans);
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
background-color: var(--color-background);
|
||||
color: var(--color-text);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
transition: background-color 150ms ease, color 150ms ease;
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
textarea,
|
||||
select {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
p,
|
||||
li,
|
||||
label,
|
||||
input,
|
||||
textarea,
|
||||
select,
|
||||
button {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: var(--color-heading);
|
||||
font-weight: 600;
|
||||
line-height: 1.25;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 0.8125rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: rgba(51, 102, 255, 0.18);
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ export default function XWorkmatePage() {
|
||||
const defaults = getConsoleIntegrationDefaults();
|
||||
|
||||
return (
|
||||
<div className="h-[calc(100vh-var(--app-shell-nav-offset))] w-full p-4">
|
||||
<div className="h-[calc(100vh-var(--app-shell-nav-offset))] w-full">
|
||||
<Suspense fallback={<XWorkmateLoading />}>
|
||||
<XWorkmateWorkspacePage defaults={defaults} />
|
||||
</Suspense>
|
||||
|
||||
@ -1893,7 +1893,7 @@ export function XWorkmateWorkspacePage({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative h-full min-h-0 overflow-hidden rounded-[var(--radius-xl)] border border-[color:var(--color-surface-border)] bg-[var(--color-surface-elevated)] shadow-[var(--shadow-md)]">
|
||||
<div className="relative h-full min-h-0 overflow-hidden rounded-[var(--radius-lg)] border border-[color:var(--color-surface-border)] bg-[var(--color-surface-elevated)] shadow-[var(--shadow-md)]">
|
||||
{sidebarState === "hidden" ? (
|
||||
<div className="pointer-events-none absolute inset-y-0 left-0 z-10 flex items-start p-4">
|
||||
<button
|
||||
@ -1911,7 +1911,7 @@ export function XWorkmateWorkspacePage({
|
||||
{sidebarState !== "hidden" ? (
|
||||
<aside
|
||||
className={cn(
|
||||
"flex h-full shrink-0 flex-col border-r border-[color:var(--color-surface-border)] bg-[var(--color-background)]/90 px-2.5 py-3 backdrop-blur transition-[width] duration-200",
|
||||
"flex h-full shrink-0 flex-col border-r border-[color:var(--color-surface-border)] bg-[var(--color-background)]/90 px-2 py-2.5 backdrop-blur transition-[width] duration-200",
|
||||
collapsed ? "w-[88px]" : "w-[292px]",
|
||||
)}
|
||||
>
|
||||
@ -2027,8 +2027,8 @@ export function XWorkmateWorkspacePage({
|
||||
<section className="flex min-w-0 flex-1 flex-col">
|
||||
<header
|
||||
className={cn(
|
||||
"border-b border-[color:var(--color-surface-border)] px-4",
|
||||
activeSection === "assistant" ? "py-2.5" : "py-4",
|
||||
"border-b border-[color:var(--color-surface-border)] px-3.5",
|
||||
activeSection === "assistant" ? "py-2" : "py-3",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
@ -2109,7 +2109,7 @@ export function XWorkmateWorkspacePage({
|
||||
</div>
|
||||
|
||||
{activeDefinition.tabs.length > 0 ? (
|
||||
<div className="mt-4 flex flex-wrap gap-2">
|
||||
<div className="mt-3 flex flex-wrap gap-2">
|
||||
{activeDefinition.tabs.map((tab) => (
|
||||
<button
|
||||
key={tab.key}
|
||||
@ -2131,11 +2131,11 @@ export function XWorkmateWorkspacePage({
|
||||
|
||||
<div
|
||||
className={cn(
|
||||
"min-h-0 flex-1 p-4",
|
||||
"min-h-0 flex-1 p-3",
|
||||
activeSection === "assistant" ? "overflow-hidden" : "overflow-auto",
|
||||
)}
|
||||
>
|
||||
<div className={cn("space-y-4", activeSection === "assistant" ? "h-full min-h-0" : "")}>
|
||||
<div className={cn("space-y-3", activeSection === "assistant" ? "h-full min-h-0" : "")}>
|
||||
{renderSectionOverview()}
|
||||
{renderMainContent()}
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user