style(web): 统一生产界面圆角为6px

This commit is contained in:
yuxuanhui
2026-08-10 16:58:16 +08:00
parent 7f99ac5027
commit 3ce186f977
23 changed files with 83 additions and 81 deletions
@@ -32,6 +32,12 @@ export function Button({
- 复杂页面用 `Card`、`CardHeader`、`CardContent` 等 composition primitive,而不是复制一套容器样式。
- 新建 shared primitive 前先搜索是否已有 `Button`、`Badge`、`Card` 或 `cn`。
### 统一圆角
- 生产前端所有有圆角的页面布局和组件统一使用 6px;`src/styles/globals.css` 中的 `--radius`、`--radius-sm`、`--radius-md`、`--radius-lg` 和 `--radius-xl` 必须最终解析为 6px。
- 组件 class 优先使用 `rounded-md` 及其方向变体;只有结构性边缘可以使用 `rounded-none`。不要新增 `rounded-full`、不同 named radius 或 arbitrary radius,以免组件之间重新出现圆角漂移。
- 该约定同样适用于 Badge、Avatar、Progress 和滚动条等 shared primitive,不因原有胶囊或圆形语义保留例外。
## 页面状态
页面应把加载、错误、成功状态转成用户可见的语义文本。`SystemStatusPage` 根据 query 状态显示“正在连接”“连接异常”“运行正常”,没有数据时使用安全的默认服务名。
+29 -29
View File
@@ -1,7 +1,7 @@
---
version: alpha
name: Intercom-design-analysis
description: "An editorial customer-service marketing canvas built around a soft cream-white ground, charcoal type set in Saans (Intercom's proprietary geometric sans), and a single confident Fin Orange (#ff5600) reserved for the Fin AI brand. Cards live as floating white tiles with thin hairline borders and minimal radii (8–16px). Display headlines run Saans at weight 500 with measured negative tracking. The system reads as a careful, product-led publication: product screenshots dominate, ornament is rare, and the only place chromatic energy enters is the Fin Orange CTA."
description: "An editorial customer-service marketing canvas built around a soft cream-white ground, charcoal type set in Saans (Intercom's proprietary geometric sans), and a single confident Fin Orange (#ff5600) reserved for the Fin AI brand. Cards live as floating white tiles with thin hairline borders and a unified 6px radius. Display headlines run Saans at weight 500 with measured negative tracking. The system reads as a careful, product-led publication: product screenshots dominate, ornament is rare, and the only place chromatic energy enters is the Fin Orange CTA."
colors:
primary: "#111111"
@@ -111,14 +111,14 @@ typography:
letterSpacing: 0
rounded:
xs: 4px
xs: 6px
sm: 6px
md: 8px
lg: 12px
xl: 16px
xxl: 24px
pill: 9999px
full: 9999px
md: 6px
lg: 6px
xl: 6px
xxl: 6px
pill: 6px
full: 6px
spacing:
xxs: 4px
@@ -212,13 +212,13 @@ components:
backgroundColor: "{colors.canvas}"
textColor: "{colors.ink-muted}"
typography: "{typography.button}"
rounded: "{rounded.pill}"
rounded: "{rounded.md}"
padding: 8px 16px
pricing-tab-selected:
backgroundColor: "{colors.surface-1}"
textColor: "{colors.ink}"
typography: "{typography.button}"
rounded: "{rounded.pill}"
rounded: "{rounded.md}"
padding: 8px 16px
faq-row:
backgroundColor: "{colors.canvas}"
@@ -260,7 +260,7 @@ Display type is **Saans** — Intercom's proprietary geometric sans — set at w
The single chromatic accent is **Fin Orange** (`{colors.fin-orange}` #ff5600) — Intercom's AI-product brand color. It surfaces on the Fin product CTA, the Fin badge in pricing, and a few inline emphasis moments. It is NOT a system primary; the system primary is charcoal `{colors.ink}`. Intercom also maintains a small **report palette** (`{colors.report-blue}`, `{colors.report-green}`, `{colors.report-pink}`, `{colors.report-lime}`) used inside in-product analytics surfaces shown in mockups.
The page rhythm is heavy on **product mockups**: every section's payload is a high-fidelity screenshot of Intercom's product UI, framed in white cards with `{rounded.xl}` 16px corners. The marketing chrome is intentionally quiet so the product can be the protagonist.
The page rhythm is heavy on **product mockups**: every section's payload is a high-fidelity screenshot of Intercom's product UI, framed in white cards with a consistent 6px corner radius. The marketing chrome is intentionally quiet so the product can be the protagonist.
**Key Characteristics:**
- **Cream canvas** (`{colors.canvas}` #f5f1ec) is the brand's defining surface — neither white nor gray, deliberately warm.
@@ -269,14 +269,14 @@ The page rhythm is heavy on **product mockups**: every section's payload is a hi
- **Charcoal** `{colors.ink}` (#111111) is the system primary — buttons, headlines, body type all sit on charcoal.
- **Fin Orange** (`{colors.fin-orange}` #ff5600) is the AI product color — used on the Fin CTA and Fin badge, never decoratively.
- Display tracking pulls aggressively negative (-2.0px on 72px); body stays at 0.
- Card corners stay modest at `{rounded.lg}` 12px and `{rounded.xl}` 16px — never pill-rounded; never square.
- All component corners use the same 6px radius — never pill-rounded and never intentionally square unless a structural edge requires `rounded-none`.
## Colors
> Source pages: intercom.com (home), /pricing, /helpdesk, /customers, /helpdesk/inbox.
### Brand & Accent
- **Charcoal** ({colors.ink}): The system primary surface. Headlines, body type, primary CTA pill background — all charcoal.
- **Charcoal** ({colors.ink}): The system primary surface. Headlines, body type, and primary CTA background — all charcoal.
- **White** ({colors.on-primary}): Text on charcoal CTAs; canvas of floating cards.
- **Fin Orange** ({colors.fin-orange}): The AI-product accent. Used on the Fin CTA, Fin badge, and a small set of inline emphasis moments.
- **Report Orange** ({colors.report-orange}): A slightly different orange used inside the report / analytics palette for in-product mockups.
@@ -332,7 +332,7 @@ The same family carries the entire hierarchy. Hierarchy is carried by size + wei
| `{typography.body}` | 16px | 400 | 1.50 | 0 | Default body |
| `{typography.body-sm}` | 14px | 400 | 1.50 | 0 | Card body, footer |
| `{typography.caption}` | 12px | 400 | 1.40 | 0 | Captions, meta |
| `{typography.button}` | 15px | 500 | 1.20 | 0 | Pill / square button labels |
| `{typography.button}` | 15px | 500 | 1.20 | 0 | Button labels |
| `{typography.eyebrow}` | 14px | 500 | 1.30 | 0 | Section eyebrow (sentence case) |
| `{typography.mono}` | 13px | 400 | 1.50 | 0 | SaansMono for code in mockups |
@@ -355,7 +355,7 @@ If implementing without Saans, suitable substitutes include **Söhne** (paid), *
- **Base unit**: 8px.
- **Tokens (front matter)**: `{spacing.xxs}` 4px · `{spacing.xs}` 8px · `{spacing.sm}` 12px · `{spacing.md}` 16px · `{spacing.lg}` 24px · `{spacing.xl}` 32px · `{spacing.xxl}` 48px · `{spacing.section}` 96px.
- Card interior padding: `{spacing.lg}` 24px on pricing/feature cards; `{spacing.xl}` 32px on testimonial/discount cards; `{spacing.xxl}` 48px on CTA banners.
- Pill button padding: 10px vertical · 18px horizontal.
- Button padding: 10px vertical · 18px horizontal.
### Grid & Container
@@ -390,20 +390,20 @@ Intercom resists drop shadows. Depth is communicated by the white-on-cream surfa
| Token | Value | Use |
|---|---|---|
| `{rounded.xs}` | 4px | Small chips, badges |
| `{rounded.xs}` | 6px | Small chips, badges |
| `{rounded.sm}` | 6px | Inline tags |
| `{rounded.md}` | 8px | All buttons, form inputs |
| `{rounded.lg}` | 12px | Pricing cards, feature cards, FAQ rows |
| `{rounded.xl}` | 16px | Product mockup cards |
| `{rounded.xxl}` | 24px | Oversized CTA banners |
| `{rounded.pill}` | 9999px | Tab toggles |
| `{rounded.full}` | 9999px | Avatar circles |
| `{rounded.md}` | 6px | All buttons, form inputs |
| `{rounded.lg}` | 6px | Pricing cards, feature cards, FAQ rows |
| `{rounded.xl}` | 6px | Product mockup cards |
| `{rounded.xxl}` | 6px | Oversized CTA banners |
| `{rounded.pill}` | 6px | Tab toggles (legacy alias) |
| `{rounded.full}` | 6px | Avatar containers (legacy alias) |
### Photography & Illustration Geometry
- Product UI screenshots dominate the marketing surface; they sit in `{rounded.xl}` 16px tiles.
- Product UI screenshots dominate the marketing surface; they sit in 6px-radius tiles.
- Customer logo tiles render at small sizes (~24–32px logo height) on `{colors.canvas}` cream with no border.
- Avatar circles in testimonial cards use `{rounded.full}` at 40–48px sizes.
- Avatar containers in testimonial cards use the same 6px radius at 40–48px sizes.
## Components
@@ -424,8 +424,8 @@ Intercom resists drop shadows. Depth is communicated by the white-on-cream surfa
### Pricing Tabs
**`pricing-tab-default`** + **`pricing-tab-selected`** — Pill-toggle on `/pricing`.
- Default: `{colors.canvas}` background, `{colors.ink-muted}` text, rounded `{rounded.pill}`.
**`pricing-tab-default`** + **`pricing-tab-selected`** — Compact tab toggle on `/pricing`.
- Default: `{colors.canvas}` background, `{colors.ink-muted}` text, rounded `{rounded.md}` (6px).
- Selected: `{colors.surface-1}` white background, `{colors.ink}` text — selected = lift onto white.
### Cards & Containers
@@ -483,7 +483,7 @@ Intercom resists drop shadows. Depth is communicated by the white-on-cream surfa
- Use **`button-fin`** Fin Orange ONLY on Fin AI product CTAs and Fin badges.
- Pair Saans display at weight 500 with body at 400.
- Use product UI screenshots as the protagonist of every section.
- Use `{rounded.lg}` 12px for cards and `{rounded.xl}` 16px for product mockup tiles.
- Use the unified 6px radius for cards, controls, tags, avatars, and product mockup tiles.
- Apply negative tracking proportionally to display sizes.
### Don't
@@ -492,7 +492,7 @@ Intercom resists drop shadows. Depth is communicated by the white-on-cream surfa
- Don't use Fin Orange as a section background or as a generic primary CTA.
- Don't add drop shadows to floating cards.
- Don't introduce a second display family.
- Don't pill-round CTAs.
- Don't introduce radius values other than the unified 6px token (except structural `rounded-none`).
- Don't write all-caps tracked eyebrows.
- Don't promote the report palette colors to brand-level surfaces.
- Don't combine charcoal CTAs and Fin Orange CTAs in the same viewport.
@@ -512,7 +512,7 @@ Intercom resists drop shadows. Depth is communicated by the white-on-cream surfa
### Touch Targets
- CTAs hold ≥40px tap height across viewports.
- Pricing tab pills hold ≥40px tap height.
- Pricing tabs hold ≥40px tap height.
- Form inputs hold ≥44px tap target on touch.
### Collapsing Strategy
+1 -1
View File
@@ -91,7 +91,7 @@ function DesktopSidebar({ activePath }: { activePath: string }) {
function Brand() {
return (
<div className="flex min-h-10 items-center justify-center gap-2.5 px-0 lg:justify-start lg:px-1.5">
<span className="grid size-8 shrink-0 place-items-center rounded-lg bg-primary text-primary-foreground">
<span className="grid size-8 shrink-0 place-items-center rounded-md bg-primary text-primary-foreground">
<BarChart3 className="size-[17px]" aria-hidden="true" />
</span>
<div className="hidden min-w-0 lg:block">
@@ -191,12 +191,12 @@ export function ComponentsPreviewPage() {
</Button>
</div>
</div>
<div className="rounded-lg border border-dashed border-border bg-muted/30 p-3 text-sm text-muted-foreground">
<div className="rounded-md border border-dashed border-border bg-muted/30 p-3 text-sm text-muted-foreground">
交互提示:打开日期弹层后,可以使用方向键移动、Enter
选择、Escape 关闭;月份切换按钮与日期按钮都保留可见焦点。
</div>
</div>
<div className="rounded-xl border border-border bg-background p-2">
<div className="rounded-md border border-border bg-background p-2">
<Calendar
aria-label="日历组件示例"
defaultMonth={calendarDate}
@@ -248,7 +248,7 @@ export function ComponentsPreviewPage() {
title="Surface & Feedback"
>
<div className="space-y-3">
<div className="flex items-center justify-between rounded-lg border border-border bg-muted/30 px-3 py-2 text-sm">
<div className="flex items-center justify-between rounded-md border border-border bg-muted/30 px-3 py-2 text-sm">
<span>数据同步状态</span>
<Badge>正常</Badge>
</div>
@@ -39,7 +39,7 @@ export function FailedStocksDialog({
{failures.map((failure) => (
<div
key={`${failure.ts_code}-${failure.failure_type}`}
className="rounded-lg border bg-muted/30 p-3"
className="rounded-md border bg-muted/30 p-3"
>
<div className="flex flex-wrap items-baseline justify-between gap-2">
<div>
@@ -99,7 +99,7 @@ export function MarketDataOverviewCard({
<Metric label="成功股票数" value={String(update.successful_count)} />
</div>
<div className="grid gap-4 rounded-xl border bg-muted/20 p-4 sm:grid-cols-3">
<div className="grid gap-4 rounded-md border bg-muted/20 p-4 sm:grid-cols-3">
<Metric label="失败股票数" value={String(update.failed_count)} />
<Metric label="有效股票数" value={String(update.valid_count)} />
<div className="space-y-2 sm:col-span-1">
@@ -132,7 +132,7 @@ export function MarketDataOverviewCard({
</div>
{update.batch_errors.length > 0 ? (
<div className="rounded-lg border border-destructive/30 bg-destructive/5 p-3 text-sm">
<div className="rounded-md border border-destructive/30 bg-destructive/5 p-3 text-sm">
<p className="font-medium text-destructive">批次级错误</p>
<ul className="mt-1 space-y-1 text-muted-foreground">
{update.batch_errors.map((error) => (
@@ -38,7 +38,7 @@ export function ExecutionStatusDrawer({
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent
aria-label="选股执行状态"
className="top-0 right-0 left-auto flex h-[100svh] min-h-[100svh] w-[min(600px,100vw)] max-w-none translate-x-full translate-y-0 flex-col grid-cols-1 gap-0 rounded-l-xl rounded-r-none border-y-0 border-r-0 p-4 data-open:translate-x-0 data-closed:translate-x-full sm:max-w-none"
className="top-0 right-0 left-auto flex h-[100svh] min-h-[100svh] w-[min(600px,100vw)] max-w-none translate-x-full translate-y-0 flex-col grid-cols-1 gap-0 rounded-l-md rounded-r-none border-y-0 border-r-0 p-4 data-open:translate-x-0 data-closed:translate-x-full sm:max-w-none"
finalFocus={finalFocus}
id="selection-execution-status-drawer"
showCloseButton={false}
@@ -54,7 +54,7 @@ export function ExecutionStatusDrawer({
<div className="min-h-0 flex-1 overflow-y-auto py-4">
<section
aria-label="执行摘要"
className="mb-4 rounded-lg border border-border/70 bg-muted/20 p-3"
className="mb-4 rounded-md border border-border/70 bg-muted/20 p-3"
>
<h2 className="sr-only">执行摘要</h2>
<dl className="grid grid-cols-2 gap-x-4 gap-y-3 sm:grid-cols-3">
@@ -14,7 +14,7 @@ export function IncompleteEvaluationTable({
failures,
}: IncompleteEvaluationTableProps) {
return (
<div className="min-w-0 overflow-hidden rounded-lg border border-border/70">
<div className="min-w-0 overflow-hidden rounded-md border border-border/70">
<table className="w-full table-fixed border-collapse text-left text-xs">
<caption className="sr-only">未完成评估明细</caption>
<colgroup>
@@ -105,7 +105,7 @@ export function SelectionResultsWorkbench({
return (
<div className="flex min-h-0 min-w-0 flex-1 flex-col gap-2 overflow-visible md:grid md:grid-cols-[minmax(0,1fr)_260px] md:overflow-hidden lg:grid-cols-[minmax(0,1.55fr)_minmax(280px,0.72fr)]">
<section className="flex min-h-0 min-w-0 flex-1 flex-col overflow-visible rounded-lg border border-border/80 bg-card md:overflow-hidden">
<section className="flex min-h-0 min-w-0 flex-1 flex-col overflow-visible rounded-md border border-border/80 bg-card md:overflow-hidden">
<div className="flex shrink-0 flex-wrap items-center gap-1.5 border-b border-border/60 p-2.5">
<Input
aria-label="搜索命中信号"
@@ -19,7 +19,7 @@ export function SignalDetailPanel({ signal }: SignalDetailPanelProps) {
return (
<Card
aria-label="当前股票详情"
className="hidden min-h-0 overflow-auto rounded-lg border-border/80 bg-card p-3 md:flex md:flex-col md:justify-center"
className="hidden min-h-0 overflow-auto rounded-md border-border/80 bg-card p-3 md:flex md:flex-col md:justify-center"
>
<div className="space-y-2 text-center">
<Search
@@ -38,7 +38,7 @@ export function SignalDetailPanel({ signal }: SignalDetailPanelProps) {
return (
<aside
aria-label="当前股票详情"
className="hidden min-h-0 overflow-auto rounded-lg border border-border/80 bg-card p-3 md:block"
className="hidden min-h-0 overflow-auto rounded-md border border-border/80 bg-card p-3 md:block"
>
<p className="text-[10px] font-bold tracking-[0.08em] text-muted-foreground uppercase">
Selected signal
@@ -50,7 +50,7 @@ export function SystemStatusPage() {
</Button>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex items-center justify-between rounded-lg border bg-muted/40 p-4">
<div className="flex items-center justify-between rounded-md border bg-muted/40 p-4">
<div>
<p className="font-medium">后端服务</p>
<p className="text-sm text-muted-foreground">
+5 -5
View File
@@ -15,7 +15,7 @@ function Avatar({
data-slot="avatar"
data-size={size}
className={cn(
"group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten",
"group/avatar relative flex size-8 shrink-0 rounded-md select-none after:absolute after:inset-0 after:rounded-md after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten",
className,
)}
{...props}
@@ -28,7 +28,7 @@ function AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) {
<AvatarPrimitive.Image
data-slot="avatar-image"
className={cn(
"aspect-square size-full rounded-full object-cover",
"aspect-square size-full rounded-md object-cover",
className,
)}
{...props}
@@ -44,7 +44,7 @@ function AvatarFallback({
<AvatarPrimitive.Fallback
data-slot="avatar-fallback"
className={cn(
"flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs",
"flex size-full items-center justify-center rounded-md bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs",
className,
)}
{...props}
@@ -57,7 +57,7 @@ function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
<span
data-slot="avatar-badge"
className={cn(
"absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none",
"absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-md bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none",
"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
@@ -89,7 +89,7 @@ function AvatarGroupCount({
<div
data-slot="avatar-group-count"
className={cn(
"relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
"relative flex size-8 shrink-0 items-center justify-center rounded-md bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
className,
)}
{...props}
+1 -1
View File
@@ -4,7 +4,7 @@ import type { HTMLAttributes } from "react"
import { cn } from "@/shared/ui/utils"
const badgeVariants = cva(
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors",
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors",
{
variants: {
variant: {
+5 -6
View File
@@ -4,7 +4,7 @@ import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/shared/ui/utils"
const buttonVariants = cva(
"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
{
variants: {
variant: {
@@ -22,14 +22,13 @@ const buttonVariants = cva(
size: {
default:
"h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
xs: "h-6 gap-1 rounded-md px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
sm: "h-7 gap-1 rounded-md px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
icon: "size-8",
"icon-xs":
"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
"icon-sm":
"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
"size-6 rounded-md in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3",
"icon-sm": "size-7 rounded-md in-data-[slot=button-group]:rounded-md",
"icon-lg": "size-9",
},
},
+9 -12
View File
@@ -22,7 +22,7 @@ function Calendar({
return (
<DayPicker
className={cn(
"group/calendar w-fit bg-background p-3 [--cell-radius:var(--radius-md)] [--cell-size:2.25rem]",
"group/calendar w-fit bg-background p-3 [--cell-size:2.25rem]",
className,
)}
classNames={{
@@ -64,20 +64,20 @@ function Calendar({
month_grid: cn("w-full border-collapse", defaultClassNames.month_grid),
weekdays: cn("flex", defaultClassNames.weekdays),
weekday: cn(
"flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal text-muted-foreground select-none",
"flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none",
defaultClassNames.weekday,
),
week: cn("mt-2 flex w-full", defaultClassNames.week),
day: cn(
"group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none",
"group/day relative aspect-square h-full w-full rounded-md p-0 text-center select-none",
defaultClassNames.day,
),
day_button: cn(
"relative z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-(--cell-radius) data-[range-middle=true]:rounded-none data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70",
"relative z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-md data-[range-start=true]:rounded-md data-[range-middle=true]:rounded-none data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70",
defaultClassNames.day_button,
),
range_start: cn(
"day-range-start rounded-(--cell-radius) bg-muted",
"day-range-start rounded-md bg-muted",
defaultClassNames.range_start,
),
range_middle: cn(
@@ -85,15 +85,12 @@ function Calendar({
defaultClassNames.range_middle,
),
range_end: cn(
"day-range-end rounded-(--cell-radius) bg-muted",
"day-range-end rounded-md bg-muted",
defaultClassNames.range_end,
),
selected: cn(
"rounded-(--cell-radius) bg-muted",
defaultClassNames.selected,
),
selected: cn("rounded-md bg-muted", defaultClassNames.selected),
today: cn(
"rounded-(--cell-radius) bg-muted text-foreground data-[selected=true]:rounded-none",
"rounded-md bg-muted text-foreground data-[selected=true]:rounded-none",
defaultClassNames.today,
),
outside: cn(
@@ -165,7 +162,7 @@ function CalendarDayButton({
data-range-end={modifiers.range_end}
data-range-middle={modifiers.range_middle}
className={cn(
"relative z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-(--cell-radius) data-[range-middle=true]:rounded-none data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70",
"relative z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-md data-[range-start=true]:rounded-md data-[range-middle=true]:rounded-none data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70",
defaultClassNames.day_button,
className,
)}
+1 -1
View File
@@ -6,7 +6,7 @@ export function Card({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn(
"rounded-xl border bg-card text-card-foreground shadow",
"rounded-md border bg-card text-card-foreground shadow",
className,
)}
{...props}
+2 -2
View File
@@ -51,7 +51,7 @@ function DialogContent({
<DialogPrimitive.Popup
data-slot="dialog-content"
className={cn(
"fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-card p-4 text-sm text-card-foreground shadow-xl ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
"fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-md bg-card p-4 text-sm text-card-foreground shadow-xl ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
className,
)}
{...props}
@@ -99,7 +99,7 @@ function DialogFooter({
<div
data-slot="dialog-footer"
className={cn(
"-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end",
"-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-md border-t bg-muted/50 p-4 sm:flex-row sm:justify-end",
className,
)}
{...props}
+1 -1
View File
@@ -9,7 +9,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
type={type}
data-slot="input"
className={cn(
"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
"h-8 w-full min-w-0 rounded-md border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
className,
)}
{...props}
+1 -1
View File
@@ -37,7 +37,7 @@ function PopoverContent({
<PopoverPrimitive.Popup
data-slot="popover-content"
className={cn(
"z-50 w-72 origin-(--transform-origin) rounded-lg border border-border bg-card p-4 text-card-foreground shadow-lg ring-1 ring-foreground/10 outline-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
"z-50 w-72 origin-(--transform-origin) rounded-md border border-border bg-card p-4 text-card-foreground shadow-lg ring-1 ring-foreground/10 outline-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
className,
)}
{...props}
+1 -1
View File
@@ -29,7 +29,7 @@ function ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props) {
return (
<ProgressPrimitive.Track
className={cn(
"relative flex h-1 w-full items-center overflow-x-hidden rounded-full bg-muted",
"relative flex h-1 w-full items-center overflow-x-hidden rounded-md bg-muted",
className,
)}
data-slot="progress-track"
+2 -2
View File
@@ -15,7 +15,7 @@ function ScrollArea({
>
<ScrollAreaPrimitive.Viewport
data-slot="scroll-area-viewport"
className="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1"
className="size-full rounded-md transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1"
>
{children}
</ScrollAreaPrimitive.Viewport>
@@ -43,7 +43,7 @@ function ScrollBar({
>
<ScrollAreaPrimitive.Thumb
data-slot="scroll-area-thumb"
className="relative flex-1 rounded-full bg-border"
className="relative flex-1 rounded-md bg-border"
/>
</ScrollAreaPrimitive.Scrollbar>
)
+2 -2
View File
@@ -48,7 +48,7 @@ function SelectTrigger({
data-slot="select-trigger"
data-size={size}
className={cn(
"flex w-full items-center justify-between gap-2 rounded-lg border border-input bg-transparent px-2.5 text-sm whitespace-nowrap outline-none transition-colors focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 [&>span]:line-clamp-1 [&>svg]:pointer-events-none [&>svg]:size-4 [&>svg]:shrink-0",
"flex w-full items-center justify-between gap-2 rounded-md border border-input bg-transparent px-2.5 text-sm whitespace-nowrap outline-none transition-colors focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 [&>span]:line-clamp-1 [&>svg]:pointer-events-none [&>svg]:size-4 [&>svg]:shrink-0",
className,
)}
{...props}
@@ -105,7 +105,7 @@ function SelectContent({
data-slot="select-content"
data-align-trigger={alignItemWithTrigger}
className={cn(
"relative z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg border border-border bg-card text-card-foreground shadow-lg ring-1 ring-foreground/10 outline-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[align-trigger=true]:animate-none",
"relative z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md border border-border bg-card text-card-foreground shadow-lg ring-1 ring-foreground/10 outline-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[align-trigger=true]:animate-none",
className,
)}
{...props}
+4 -4
View File
@@ -23,10 +23,10 @@
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: var(--radius);
--radius-md: var(--radius);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--radius-xl: var(--radius);
}
:root {
@@ -50,7 +50,7 @@
--border: #d3cec6;
--input: #d3cec6;
--ring: #111111;
--radius: 0.75rem;
--radius: 6px;
}
.dark {