@zmzai/theme 0.9.5 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zmzai/theme",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "zmzai 全品牌设计系统 — Radix UI + framer-motion + Tailwind v4 + MiSans",
@@ -0,0 +1,61 @@
1
+ "use client";
2
+
3
+ import { cn } from "../../utils/cn";
4
+ import { Logo } from "../logo";
5
+ import { Wordmark } from "../wordmark";
6
+
7
+ /**
8
+ * BrandLockup — 全站统一的品牌锁标:云朵 Logo + ZMZAI wordmark + 子站标。
9
+ *
10
+ * 背景(2026-08-31):theme 有两套骨架,品牌区 API 不对称 ——
11
+ * Navbar 内置 Logo + Wordmark,AppShell 的 brand 只吃 {label, suffix} 文本。
12
+ * 结果走 Navbar 的站(Folio / Quill / Index / auth)有云朵标,
13
+ * 走 AppShell 的站(Tome / Plate / Margin)没有。抽成一处,谁都不许自造。
14
+ *
15
+ * 纪律(BRAND §7.7):
16
+ * · 云朵 Logo 只出现在品牌锁标里,不单独当装饰散落在页面各处
17
+ * · 子站标是站点对外的品牌名(书写系列),不是技术仓库名
18
+ *
19
+ * @example
20
+ * <BrandLockup sublabel="tome" /> // 白底(默认)
21
+ * <BrandLockup sublabel="auth" tone="dark" /> // 墨底叙事区
22
+ */
23
+ export interface BrandLockupProps {
24
+ /** 云朵标直径(px),默认 22 —— 全站统一,不要按场景私调 */
25
+ logoSize?: number;
26
+ /** wordmark 字号(px),默认 16 */
27
+ markSize?: number;
28
+ /** ZMZAI 后的子站标,如 "tome" / "quill" / "auth" */
29
+ sublabel?: string;
30
+ /** 墨底载体:云朵标反白、文字转暗底配色,默认 "light" */
31
+ tone?: "light" | "dark";
32
+ className?: string;
33
+ }
34
+
35
+ export function BrandLockup({
36
+ logoSize = 22,
37
+ markSize = 16,
38
+ sublabel,
39
+ tone = "light",
40
+ className,
41
+ }: BrandLockupProps) {
42
+ const dark = tone === "dark";
43
+ return (
44
+ <span
45
+ className={cn(
46
+ "inline-flex items-center gap-2 select-none",
47
+ dark && "text-dark-ink",
48
+ className,
49
+ )}
50
+ >
51
+ <Logo size={logoSize} inverted={dark} />
52
+ <Wordmark
53
+ size={markSize}
54
+ sublabel={sublabel}
55
+ // 墨底时压掉 Wordmark 子标自带的 text-ink-3(暗底上不可读)。
56
+ // 任意变体选择器特异性高于单类名,能可靠覆盖。
57
+ className={dark ? "[&>span]:text-dark-ink/45" : undefined}
58
+ />
59
+ </span>
60
+ );
61
+ }
@@ -0,0 +1,2 @@
1
+ // @zmzai/theme — Brand lockup barrel
2
+ export { BrandLockup, type BrandLockupProps } from "./BrandLockup";
@@ -1,3 +1,4 @@
1
1
  // @zmzai/theme — Brand assets barrel
2
2
  export * from "./logo";
3
3
  export * from "./wordmark";
4
+ export * from "./brand-lockup";
@@ -3,6 +3,8 @@
3
3
  import { useEffect, useMemo, useState } from "react";
4
4
  import type { ComponentType, ReactNode } from "react";
5
5
 
6
+ import { BrandLockup } from "../../brand/brand-lockup";
7
+
6
8
  import { Badge } from "../badge/Badge";
7
9
  import { Icon, type IconName } from "../icon/Icon";
8
10
  import { CommandPalette, type AppPaletteItem } from "./CommandPalette";
@@ -130,9 +132,11 @@ export function AppShell({
130
132
  }, [hasPalette]);
131
133
 
132
134
  const brandBlock = (
133
- <Link href={brand.href ?? "/"} className="flex items-baseline gap-1.5 px-2">
134
- <span className="text-sm font-semibold tracking-tight">{brand.label}</span>
135
- {brand.suffix ? <span className="font-mono text-[11px] text-ink-3">{brand.suffix}</span> : null}
135
+ <Link href={brand.href ?? "/"} className="flex flex-col gap-1 px-2">
136
+ {/* 品牌区统一走 BrandLockup(2026-08-31 抽出,与 Navbar 共用一份锁标)。
137
+ label 同时是顶栏兜底标题与子站标,两处语义一致。 */}
138
+ <BrandLockup sublabel={brand.label} />
139
+ {brand.suffix ? <span className="font-mono text-[10px] text-ink-3">{brand.suffix}</span> : null}
136
140
  </Link>
137
141
  );
138
142
 
@@ -2,8 +2,7 @@
2
2
 
3
3
  import { type ReactNode, useEffect, useState } from "react";
4
4
  import { cn } from "../../utils/cn";
5
- import { Logo } from "../../brand/logo";
6
- import { Wordmark } from "../../brand/wordmark";
5
+ import { BrandLockup } from "../../brand/brand-lockup";
7
6
  import { Icon } from "../icon/Icon";
8
7
 
9
8
  /**
@@ -66,12 +65,8 @@ export function Navbar({ sublabel, brand, children, actions, badge, brandHref, m
66
65
  return () => window.removeEventListener("keydown", onKey);
67
66
  }, [open]);
68
67
 
69
- const brandNode = brand ?? (
70
- <span className="inline-flex items-center gap-2">
71
- <Logo size={22} />
72
- <Wordmark size={16} sublabel={sublabel} />
73
- </span>
74
- );
68
+ // 品牌区统一走 BrandLockup(2026-08-31 抽出,与 AppShell 共用一份锁标)
69
+ const brandNode = brand ?? <BrandLockup sublabel={sublabel} />;
75
70
  const nav = children ? (
76
71
  <nav
77
72
  className="flex min-w-0 items-center gap-1 overflow-x-auto"
@@ -13,6 +13,15 @@
13
13
  * · page 一律 text-2xl + 内联图标,不再区分公开页与控制台
14
14
  * · 图标取 currentColor,不引入新色;hero 徽章用 accent 载体(墨底白图)
15
15
  * · 描述统一 text-sm text-ink-2 —— ink-3 只有 3.69:1,副文案不用它
16
+ *
17
+ * v0.9.5 追加 centered(居中 Hero,/quill 首页用)。
18
+ *
19
+ * v0.9.7 page 变体改版(用户定案 2026-08-31,与 BRAND 戒律 14 同步):
20
+ * · 眉标改 mono 小写间距体(原 sans semibold)—— 等宽小标是全站通用的小节语言
21
+ * · 标题从 text-2xl 提到 text-3xl,font-semibold → font-bold —— 衬线的视觉
22
+ * 体量比无衬线小,不放大反而显得比原来弱
23
+ * · 图标从 text-ink 降到 text-ink-2 —— 图标是辅助信息,不该跟标题同权重
24
+ * · 描述加 max-w-2xl + leading-7 —— 衬线大标题下的 sans 正文要更松才不挤
16
25
  */
17
26
 
18
27
  import type { ReactNode } from "react";
@@ -91,19 +100,19 @@ export function PageHeader({
91
100
  <header className={`flex flex-wrap items-end justify-between gap-3 ${className}`}>
92
101
  <div className="min-w-0">
93
102
  {eyebrow ? (
94
- <small className="mb-1 block text-xs font-semibold uppercase tracking-wide text-ink-3">
103
+ <small className="mb-1.5 block font-mono text-[11px] uppercase tracking-[0.16em] text-ink-3">
95
104
  {eyebrow}
96
105
  </small>
97
106
  ) : null}
98
- <div className="flex items-center gap-2">
99
- {icon ? <Icon name={icon} size={20} className="shrink-0 text-ink" /> : null}
100
- <h1
101
- className={`font-serif text-2xl font-semibold tracking-tight text-ink ${titleClassName}`}
102
- >
107
+ <div className="flex min-w-0 items-center gap-2.5">
108
+ {icon ? <Icon name={icon} size={20} strokeWidth={1.5} className="shrink-0 text-ink-2" /> : null}
109
+ <h1 className={`font-serif text-3xl font-bold leading-[1.2] tracking-tight text-ink ${titleClassName}`}>
103
110
  {title}
104
111
  </h1>
105
112
  </div>
106
- {description ? <p className="mt-2 text-sm leading-6 text-ink-2">{description}</p> : null}
113
+ {description ? (
114
+ <p className="mt-2.5 max-w-2xl text-sm leading-7 text-ink-2">{description}</p>
115
+ ) : null}
107
116
  </div>
108
117
  {actions ? <div className="flex flex-wrap items-center gap-2">{actions}</div> : null}
109
118
  </header>
@@ -24,6 +24,7 @@
24
24
  * v0.9.3 底色纯白化——暖纸退役,卡片层次交给 surface 灰阶与边框
25
25
  * v0.9.4 PageHeader 统一组件——内页 text-2xl 内联图标、落地页 44px 墨底徽章
26
26
  * v0.9.5 PageHeader 支持 centered(居中 Hero);Icon 支持 strokeWidth
27
+ * v0.9.6 标题行补 min-w-0,truncate 在详情页长标题下才生效
27
28
  */
28
29
 
29
30
  @theme {