dsh-claude-style 0.18.2-dev.38 → 0.18.3-dev.41

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/docs/STYLE.md CHANGED
@@ -4,109 +4,170 @@ Design tokens for `dsh-claude-style`, recreating the Claude Code Desktop aesthet
4
4
 
5
5
  ## Palette
6
6
 
7
- | Token | Value | Use |
8
- |---|---|---|
9
- | ivory light | `#FCFCFB` | light canvas / layer 1 |
10
- | sidebar light | `#FBFBF9` | light sidebar / layer 2 |
11
- | ivory neutral | `#F9F9F6` | layer 3 / section bg |
12
- | ivory border | `#E8E6DC` | border l1 |
13
- | slate dark | `#141413` | text (light mode), canvas (dark mode) |
14
- | warm gray | `#B0AEA5` | metadata |
15
- | clay | `#D97757` | single accent — CTA / links |
16
- | accent deep | `#C6613F` | accent hover |
17
- | hairline | `#1414131a` | 1px warm border |
7
+ Every look is a **colour card**: an accent, a canvas per scheme, an inline-code
8
+ ink and, when its prose links keep a family of their own, a link per scheme. The
9
+ first card is the default look. A card's dark outlines are drawn either as a lit
10
+ highlight or as a flat surface step, and its brand art takes its colour from the
11
+ ink or the accent (D30).
12
+
13
+ The colour every token paints is a **tone** of one of those seeds: a lightness
14
+ step from the seed, an absolute chroma or a multiple of the seed's, an optional
15
+ hue shift and, on translucent surfaces, an alpha. The build resolves the tones
16
+ into plain colours, so the page ships literals and nothing derives at runtime.
17
+ The ladder is shared by every card; a card states only its seeds and its traits.
18
+
19
+ The reader authors a fourth card: four colours of their own, shown and edited in
20
+ the settings page beside the two brands. Its palette is the same ladder written
21
+ as relative colours (`oklch(from var(--dsh-claude-custom-accent) …)`), one block
22
+ per brand and scheme, so the colours resolve in the page while the two brand
23
+ cards keep their literals; the image-colour choice (`Default`, `Accent`, `Text
24
+ colour`) repaints the brand art from the same table (D30).
18
25
 
19
26
  Rules:
20
27
 
21
28
  - Never pure white, never pure black, never cool grays. The reader's own message
22
- plate is the one fill that is not a step of the warm surface ladder and not the
23
- canvas either (`--dsw-specific-bubble`: the neutral the table header wears in
24
- light, a 6% white lift in dark) — the product's own light tint is a cool
25
- blue-grey, which reads blue beside this canvas.
29
+ plate is a fill of its own (`--dsw-specific-bubble`: the neutral the table
30
+ header wears in light, a 6% lift of the ink in dark) — the product's own light
31
+ tint is a cool blue-grey, which reads blue beside this canvas.
26
32
  - Accent usage stays under ~10% of visible elements.
27
-
28
- **The DeepSeek brand's palettes.** The DeepSeek brand turns both palettes
29
- blue. The single accent is DeepSeek's brand blue `#4D6BFE` — the colour of its
30
- whale logo and of Deepy — with a darker step for text links on the light canvas
31
- and a lighter one on the dark; the sidebar's whale and wordmark and the hero's
32
- fish take it as their ink. The neutrals are the host's own cool family (its
33
- `neutral-bluish` ramp) under a white carrying only a hint of sky in light and a
34
- blue-black in dark. User bubbles take a blue tint as the host's own do, and
35
- inline code keeps the body ink as the host draws it. The skin's Claude marks
36
- (the account row's
33
+ - Literal colours stay outside the ladder: the reasoning slider's violet
34
+ (`--dsh-claude-apex*`), the selection ring, the ripple's front, the peak and
35
+ off-peak badges and the popover shadow.
36
+
37
+ **The DeepSeek card** turns both schemes blue. Its accent is DeepSeek's brand
38
+ blue `#4D6BFE` — the colour of its whale logo and of Deepy; the sidebar's whale
39
+ and wordmark and the hero's fish take it as their ink. Its canvases are the
40
+ host's own cool family (its `neutral-bluish` ramp) under a white carrying only a
41
+ hint of sky in light and a blue-black in dark, and its dark outlines are surface
42
+ steps rather than highlights. The skin's Claude marks (the account row's
37
43
  picture without an avatar) become DeepSeek's
38
44
  whale (`packages/assets/src/brand/deepseek-mark.svg`, the host's `FISH_LOGO_PATH`); the
39
45
  violet top rung of the reasoning slider stays.
40
46
 
41
- The table below is generated from `packages/client/src/theme/tokens.json` by `npm run build`;
42
- edit the JSON, not the table. A DeepSeek cell shows the Claude value the brand
43
- keeps where it states none of its own; `—` is a token that theme leaves unset.
47
+ The tables below are generated from `packages/client/src/theme/tokens.json` by `npm run build`;
48
+ edit the JSON, not the tables. A token's row names the tone it reads and the
49
+ colour that tone resolves to in both cards and both schemes; `—` is a token a
50
+ card leaves unset.
44
51
 
45
52
  <!-- generated:tokens (packages/client/src/theme/tokens.json) -->
46
- | Token | Claude light | DeepSeek light | Claude dark | DeepSeek dark | Host alias | Use |
47
- |---|---|---|---|---|---|---|
48
- | `--dsw-alias-bg-base` | `#fcfcfb` | `#fafbff` | `#141413` | `#13161d` | host's own | |
49
- | `--dsw-alias-bg-layer-1` | `#fcfcfb` | `#fafbff` | `#1c1b1a` | `#1a1e27` | host's own | |
50
- | `--dsw-alias-bg-layer-2` | `#fbfbf9` | `#f7f9ff` | `#242320` | `#212631` | host's own | |
51
- | `--dsw-alias-bg-layer-3` | `#f9f9f6` | `#f4f7fe` | `#2e2c29` | `#2a303c` | host's own | |
52
- | `--dsw-alias-bg-overlay` | `#ffffff` | `#ffffff` | `#242320` | `#212631` | host's own | |
53
- | `--dsw-alias-border-l1` | `#e8e6dc` | `#e7ecf7` | `rgba(255, 255, 255, 0.09)` | `#212631` | host's own | the standard edge: card and panel outlines, dividers, field outlines |
54
- | `--dsw-alias-border-l2` | `#dedcd2` | `#dde4f1` | `rgba(255, 255, 255, 0.18)` | `#2a303c` | host's own | |
55
- | `--dsw-alias-border-l3` | `#d0cdc1` | `#cfd8ea` | `rgba(255, 255, 255, 0.30)` | `#363d4b` | host's own | |
56
- | `--dsw-alias-brand-primary` | `#d97757` | `#4d6bfe` | `#d97757` | `#4d6bfe` | host's own | the single accent: checks, focus rings, selected marks |
57
- | `--dsw-alias-brand-text` | `#faf9f5` | `#fafbff` | `#faf9f5` | `#eef1f8` | host's own | |
58
- | `--dsw-alias-button-primary-fill` | `#d97757` | `#4d6bfe` | `#d97757` | `#4d6bfe` | host's own | |
59
- | `--dsw-alias-button-primary-hover` | `#c6613f` | `#3a57e8` | `#e08a6d` | `#6a84ff` | host's own | |
60
- | `--dsw-alias-button-elevated-fill` | `#ffffff` | `#ffffff` | `#242320` | `#212631` | host's own | |
61
- | `--dsw-alias-button-floating-fill` | `#ffffff` | `#ffffff` | `#242320` | `#212631` | host's own | |
62
- | `--dsw-alias-button-floating-hover` | `#ffffff` | `#ffffff` | `#2e2c29` | `#2a303c` | host's own | |
63
- | `--dsw-alias-button-info-fill` | `#d97757` | `#4d6bfe` | `#d97757` | `#4d6bfe` | host's own | |
64
- | `--dsw-alias-button-info-hover` | `#c6613f` | `#3a57e8` | `#e08a6d` | `#6a84ff` | host's own | |
65
- | `--dsw-alias-interactive-bg-active` | `rgba(217, 119, 87, 0.30)` | `rgba(77, 107, 254, 0.22)` | `rgba(217, 119, 87, 0.30)` | `rgba(77, 107, 254, 0.30)` | host's own | |
66
- | `--dsh-claude-hover-bg` | `rgba(0, 0, 0, 0.08)` | `rgba(38, 49, 72, 0.08)` | `rgba(255, 255, 255, 0.08)` | `rgba(255, 255, 255, 0.08)` | `var(--dsw-alias-interactive-bg-hover)` | hover wash |
67
- | `--dsh-claude-inline-code-bg` | `rgba(0, 0, 0, 0.05)` | `rgba(38, 49, 72, 0.05)` | `rgba(255, 255, 255, 0.05)` | `rgba(255, 255, 255, 0.05)` | `var(--dsw-alias-markdown-inline-code)` | inline code fill |
68
- | `--dsh-claude-inline-code-fg` | `#943333` | `var(--dsw-alias-label-primary)` | `#e8a08a` | `var(--dsw-alias-label-primary)` | `var(--dsw-alias-label-primary)` | inline code ink |
69
- | `--dsh-claude-link` | `#184f95` | `#3b56d9` | `#8ab4f8` | `#8fa4ff` | `var(--dsw-alias-link)` | markdown links |
70
- | `--dsh-claude-link-underline` | `rgba(24, 79, 149, 0.6)` | `rgba(59, 86, 217, 0.6)` | `rgba(138, 180, 248, 0.6)` | `rgba(143, 164, 255, 0.6)` | `color-mix(in srgb, var(--dsw-alias-link) 60%, transparent)` | markdown link underline |
71
- | `--dsw-alias-markdown-code-block` | `#ffffff` | `#ffffff` | `#1c1b1a` | `#1a1e27` | host's own | |
72
- | `--dsw-alias-markdown-code-block-banner` | `#ffffff` | `#ffffff` | `#242320` | `#212631` | host's own | |
73
- | `--dsw-alias-interactive-bg-hover` | `var(--dsh-claude-hover-bg)` | `var(--dsh-claude-hover-bg)` | `var(--dsh-claude-hover-bg)` | `var(--dsh-claude-hover-bg)` | host's own | |
74
- | `--dsw-alias-interactive-bg-hover-solid` | `#f0efe9` | `#eef3fc` | `#2e2c29` | `#2a303c` | host's own | the host's solid hover chip |
75
- | `--dsw-alias-label-primary` | `#141413` | `#0f1115` | `#faf9f5` | `#eef1f8` | host's own | |
76
- | `--dsw-alias-label-primary-bluish` | `#141413` | `#0f1115` | `#faf9f5` | `#eef1f8` | host's own | |
77
- | `--dsw-alias-label-secondary` | `#6e6a60` | `#61666b` | `#b0aea5` | `#aeb5c4` | host's own | |
78
- | `--dsw-alias-label-tertiary` | `#8f8a7e` | `#81858c` | `#8f8d84` | `#8a92a3` | host's own | |
79
- | `--dsw-alias-label-caption` | `#a6a094` | `#adb2b8` | `#6b6a65` | `#666e7e` | host's own | |
80
- | `--dsw-alias-label-shimmer` | `color-mix(in srgb, #141413 30%, transparent)` | `color-mix(in srgb, #141413 30%, transparent)` | `color-mix(in srgb, #faf9f5 45%, transparent)` | `color-mix(in srgb, #faf9f5 45%, transparent)` | host's own | the highlight band's tint over running words: the host's own rows and the skin's band (shared/sweep-band.ts) alike |
81
- | `--dsw-alias-label-deep-diving-shimmer` | `color-mix(in srgb, #141413 30%, transparent)` | `color-mix(in srgb, #141413 30%, transparent)` | `color-mix(in srgb, #faf9f5 45%, transparent)` | `color-mix(in srgb, #faf9f5 45%, transparent)` | host's own | the band's tint inside the running row, which the host points --dsw-alias-label-shimmer at; under Claude it is the same warm band as everywhere else |
82
- | `--dsw-alias-state-business-primary` | `#d97757` | `#4d6bfe` | `#d97757` | `#6a84ff` | host's own | |
83
- | `--dsw-alias-state-business-tertiary` | `#e9dfd2` | `#e9eeff` | `#3a2a22` | `#253056` | host's own | |
84
- | `--dsw-alias-link` | `#c6613f` | `#3b56d9` | `#e08a6d` | `#8fa4ff` | host's own | text link at rest |
85
- | `--dsw-shadow-lv2` | `0 4px 18px rgba(20, 20, 19, 0.10), 0 1px 3px rgba(20, 20, 19, 0.05)` | `0 4px 18px rgba(20, 20, 19, 0.10), 0 1px 3px rgba(20, 20, 19, 0.05)` | `0 4px 16px rgba(0, 0, 0, 0.30), 0 1px 3px rgba(0, 0, 0, 0.14)` | `0 4px 16px rgba(0, 0, 0, 0.30), 0 1px 3px rgba(0, 0, 0, 0.14)` | host's own | |
86
- | `--dsw-specific-input-major` | `#ffffff` | `#ffffff` | `#0f0e0d` | `#0e1117` | host's own | |
87
- | `--dsw-specific-selector` | `#fbfbf9` | `#f7f9ff` | `#2e2c29` | `#2a303c` | host's own | |
88
- | `--dsw-specific-sidebar-fill` | `#fbfbf9` | `#f7f9ff` | `#141413` | `#13161d` | host's own | |
89
- | `--dsw-alias-brand-primary-new-colorprimary-new-color` | `#d97757` | `#4d6bfe` | `#d97757` | `#4d6bfe` | host's own | |
90
- | `--dsh-claude-canvas` | `#fcfcfb` | `#fafbff` | `#141413` | `#13161d` | `var(--dsw-alias-bg-base)` | the page canvas, the search box |
91
- | `--dsh-claude-sidebar-canvas` | `#fbfbf9` | `#f7f9ff` | `#141413` | `#13161d` | `var(--dsw-specific-sidebar-fill)` | the sidebar |
92
- | `--dsh-claude-raised` | — | — | `#1e1e1d` | `#1b1f28` | `var(--dsw-alias-bg-overlay)` | popovers and menus raised above the dark canvas |
93
- | `--dsh-claude-card` | `#fcfcfb` | `#fafbff` | `#1e1e1d` | `#1b1f28` | `var(--dsw-alias-bg-overlay)` | cards on the canvas in light and raised in dark: the account popover, the search palette |
94
- | `--dsh-claude-inverse-fill` | `#141413` | `#141413` | `#faf9f5` | `#faf9f5` | `var(--dsw-alias-interactive-bg-hover)` | the model picker's group label fill: an inverted chip under Claude, a hover-plate chip under the host |
95
- | `--dsh-claude-inverse-ink` | `#faf9f5` | `#faf9f5` | `#141413` | `#141413` | `var(--dsw-alias-label-primary)` | the model picker's group label ink |
96
- | `--dsh-claude-ink-strong` | — | — | `#f5f4ef` | `#e9edf6` | `var(--dsw-alias-label-primary)` | active row ink |
97
- | `--dsh-claude-session-ink` | — | — | `#8c8983` | `#8a91a0` | `var(--dsw-alias-label-secondary)` | session title at rest |
98
- | `--dsh-claude-table-head` | `#f0f0ef` | `#eff3fb` | `#242320` | `#212631` | `var(--dsw-alias-bg-layer-2)` | table header row |
99
- | `--dsh-claude-ripple-ink` | `#8a8a85` | `#8a92a6` | `#8c8a82` | `#8b93a7` | `var(--dsw-alias-label-secondary, #8a8a85)` | the new-conversation page's glyph field, and the wake a ripple leaves in it |
100
- | `--dsh-claude-ripple-wave` | `#3b6ef0` | `#3b6ef0` | `#7fa6ff` | `#7fa6ff` | `var(--dsw-alias-link, #3b6ef0)` | the front of a ripple in the new-conversation page's glyph field |
101
- | `--dsh-claude-scrollbar` | `rgba(208, 205, 193, 0.9)` | `rgba(206, 216, 233, 0.9)` | `rgba(58, 56, 51, 0.9)` | `rgba(54, 61, 75, 0.9)` | `var(--dsw-alias-border-l2)` | scrollbar thumb |
102
- | `--dsh-claude-scrollbar-hover` | `rgba(143, 138, 126, 0.8)` | `rgba(129, 133, 140, 0.8)` | `rgba(107, 106, 101, 0.9)` | `rgba(104, 112, 128, 0.9)` | `var(--dsw-alias-label-caption)` | scrollbar thumb under the pointer |
103
- | `--dsh-claude-link-hover` | `#a94f2f` | `#2c43b8` | `#f0a488` | `#b0c0ff` | `var(--dsw-alias-link)` | text link under the pointer |
104
- | `--dsh-claude-logo-ink` | `#141413` | `#4d6bfe` | `#faf9f5` | `#4d6bfe` | `var(--dsw-alias-label-primary)` | sidebar brand art: the whale and the wordmark |
105
- | `--dsw-specific-menu` | `#ffffff` | `#ffffff` | — | — | host's own | |
106
- | `--dsw-specific-bubble` | `#f0f0ef` | `#eaf0fe` | `rgba(255, 255, 255, 0.06)` | `#232a3a` | host's own | user message bubble |
107
- | `--dsh-claude-chip` | `#f6f6f4` | `#f2f6fd` | — | — | `var(--dsw-specific-selector)` | segmented control and switch at rest |
108
- | `--dsh-claude-meter-peak` | `#a4621d` | `#9a5a1a` | `#e2a45f` | `#e5ae67` | `var(--dsw-alias-state-warn-label)` | the peak rate badge: the expensive end of a provider's own billing clock |
109
- | `--dsh-claude-meter-valley` | `#3d7550` | `#2e7554` | `#8cbf96` | `#7cc2a0` | `var(--dsw-alias-state-success-primary)` | the off-peak rate badge, and the dated promotions priced below it |
53
+ | Card | Accent | Canvas light | Canvas dark | Link light | Link dark | Edges | Logo ink | Code light | Code dark |
54
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
55
+ | claude (default) | `#d97757` | `#fcfcfb` | `#141413` | `#184f95` | `#8ab4f8` | highlight | ink | `#943333` | `#e8a08a` |
56
+ | deepseek | `#4d6bfe` | `#fafbff` | `#13161d` | `#3b56d9` | `#8fa4ff` | surface | accent | `#0f1115` | `#eef1f8` |
57
+
58
+ | Tone | Seed | Light | Dark |
59
+ | --- | --- | --- | --- |
60
+ | `canvas` | | `Δl 0` | `Δl 0` |
61
+ | `surface-1` | | `Δl 0` | `Δl +0.036` |
62
+ | `surface-2` | | `Δl -0.004` | `Δl +0.065` |
63
+ | `surface-3` | | `Δl +0.002` | `Δl +0.104` |
64
+ | `overlay` | | `Δl +0.01 · C 0` | `Δl +0.065` |
65
+ | `code-block` | | `Δl +0.01 · C 0` | `Δl +0.036` |
66
+ | `inset` | | `Δl +0.01 · C 0` | `Δl -0.024` |
67
+ | `card` | | `Δl 0` | `Δl +0.044` |
68
+ | `table-head` | | `Δl -0.037` | `Δl +0.065` |
69
+ | `hover-plate` | | `Δl -0.034` | `Δl +0.104` |
70
+ | `selector` | | `Δl -0.004` | `Δl +0.104` |
71
+ | `chip` | | `Δl -0.019` | `Δl 0` |
72
+ | `sidebar` | | `Δl -0.002 · ΔC +0.002` | `Δl 0` |
73
+ | `ink` | | `Δl -0.801` | `Δl +0.781` |
74
+ | `ink-2` | | `Δl -0.474 · ΔC +0.01` | `Δl +0.571 · ΔC +0.009` |
75
+ | `ink-3` | | `Δl -0.365 · ΔC +0.011` | `Δl +0.458 · ΔC +0.012` |
76
+ | `ink-4` | | `Δl -0.251 · ΔC +0.007` | `Δl +0.336 · ΔC +0.01` |
77
+ | `ink-strong` | | — | `Δl +0.77 · ΔC +0.003` |
78
+ | `session-ink` | | — | `Δl +0.455 · ΔC +0.009` |
79
+ | `ripple-ink` | | `Δl -0.358 · ΔC +0.007` | `Δl +0.451 · ΔC +0.014` |
80
+ | `bubble` | | `Δl -0.037 · ΔC +0.002` | `Δl +0.09 · α 0.06` |
81
+ | `bubble-flat` | | — | `Δl +0.088 · ΔC +0.006` |
82
+ | `border-1` | | `Δl -0.067` | `Δl +0.026 · α 0.09` |
83
+ | `border-2` | | `Δl -0.098` | `Δl +0.026 · α 0.18` |
84
+ | `border-3` | | `Δl -0.144` | `Δl +0.026 · α 0.3` |
85
+ | `border-1-flat` | | — | `Δl +0.069` |
86
+ | `border-2-flat` | | — | `Δl +0.108` |
87
+ | `border-3-flat` | | — | `Δl +0.161` |
88
+ | `divider` | | `Δl 0 · α 0.05` | `Δl +0.026 · α 0.06` |
89
+ | `scrollbar` | | `Δl -0.128 · α 0.9` | `Δl -0.63 · α 0.9` |
90
+ | `scrollbar-hover` | | `Δl -0.368 · α 0.8` | `Δl -0.446 · α 0.9` |
91
+ | `on-accent` | | `Δl 0` | `Δl +0.775` |
92
+ | `inverse-ink` | | `Δl +0.011` | `Δl -0.011` |
93
+ | `hover-wash` | | `Δl -0.081 · α 0.08` | `Δl +0.026 · α 0.08` |
94
+ | `code-wash` | | `Δl -0.081 · α 0.05` | `Δl +0.026 · α 0.05` |
95
+ | `shimmer` | | `Δl 0` | `Δl 0` |
96
+ | `accent` | | `Δl 0 · C ×1` | `Δl 0 · C ×1` |
97
+ | `accent-hover` | | `Δl -0.063 · C ×1.01` | `Δl +0.071 · C ×0.91 · h +2` |
98
+ | `accent-active` | | `Δl +0.068 · C ×1.1 · h +1 · α 0.26` | `Δl 0 · C ×1 · α 0.3` |
99
+ | `accent-tint` | | `Δl 0 · C 0.028` | `Δl 0 · C 0.055` |
100
+ | `ui-link` | | `Δl -0.069 · C ×0.95` | `Δl +0.1 · C ×0.72` |
101
+ | `ui-link-hover` | | `Δl -0.143 · C ×0.9` | `Δl +0.19 · C ×0.7` |
102
+ | `link` | | `Δl 0 · C ×1` | `Δl 0 · C ×1` |
103
+ | `link-underline` | | `Δl 0 · C ×1 · α 0.6` | `Δl 0 · C ×1 · α 0.6` |
104
+
105
+ | Token | Tone | claude light | claude dark | deepseek light | deepseek dark | Host alias | Use |
106
+ | --- | --- | --- | --- | --- | --- | --- | --- |
107
+ | `--dsw-alias-bg-base` | `canvas` | `#fcfcfb` | `#141413` | `#fafbff` | `#13161d` | host's own | |
108
+ | `--dsw-alias-bg-layer-1` | `surface-1` | `#fcfcfb` | `#1c1c1b` | `#fafbff` | `#1b1e26` | host's own | |
109
+ | `--dsw-alias-bg-layer-2` | `surface-2` | `#fbfbfa` | `#232322` | `#f9fafe` | `#22252d` | host's own | |
110
+ | `--dsw-alias-bg-layer-3` | `surface-3` | `#fdfdfc` | `#2d2d2b` | `#fbfcff` | `#2b2f37` | host's own | |
111
+ | `--dsw-alias-bg-overlay` | `overlay` | `#ffffff` | `#232322` | `#fefefe` | `#22252d` | host's own | |
112
+ | `--dsw-alias-border-l1` | `border-1` / `border-1-flat` | `#e6e6e5` | `rgba(255, 255, 253, 0.09)` | — | `#23262e` | host's own | the standard edge: card and panel outlines, dividers, field outlines |
113
+ | `--dsw-alias-border-l2` | `border-2` / `border-2-flat` | `#dcdcdb` | `rgba(255, 255, 253, 0.18)` | — | `#2c3038` | host's own | |
114
+ | `--dsw-alias-border-l3` | `border-3` / `border-3-flat` | `#cdcdcc` | `rgba(255, 255, 253, 0.3)` | — | `#3a3d46` | host's own | |
115
+ | `--dsh-claude-divider` | `divider` | `rgba(20, 20, 19, 0.05)` | `rgba(255, 255, 253, 0.06)` | `rgba(18, 19, 22, 0.05)` | `rgba(251, 255, 255, 0.06)` | `var(--dsw-alias-border-l1)` | a line that only separates: foot areas, settings rows, menu separators, the transcript's rule |
116
+ | `--dsw-alias-brand-primary` | `accent` | `#d97757` | `#d97757` | `#4d6bfe` | `#4d6bfe` | host's own | the single accent: checks, focus rings, selected marks |
117
+ | `--dsw-alias-brand-text` | `on-accent` | `#fcfcfb` | `#f4f4f2` | `#fafbff` | `#f2f7ff` | host's own | |
118
+ | `--dsw-alias-button-primary-fill` | `accent` | `#d97757` | `#d97757` | `#4d6bfe` | `#4d6bfe` | host's own | |
119
+ | `--dsw-alias-button-primary-hover` | `accent-hover` | `#c46343` | `#eb9170` | `#3d56e9` | `#6a84ff` | host's own | |
120
+ | `--dsw-alias-button-elevated-fill` | `overlay` | `#ffffff` | `#232322` | `#fefefe` | `#22252d` | host's own | |
121
+ | `--dsw-alias-button-floating-fill` | `overlay` | `#ffffff` | `#232322` | `#fefefe` | `#22252d` | host's own | |
122
+ | `--dsw-alias-button-floating-hover` | `surface-3` | `#fdfdfc` | `#2d2d2b` | `#fbfcff` | `#2b2f37` | host's own | |
123
+ | `--dsw-alias-button-info-fill` | `accent` | `#d97757` | `#d97757` | `#4d6bfe` | `#4d6bfe` | host's own | |
124
+ | `--dsw-alias-button-info-hover` | `accent-hover` | `#c46343` | `#eb9170` | `#3d56e9` | `#6a84ff` | host's own | |
125
+ | `--dsw-alias-interactive-bg-active` | `accent-active` | `rgba(246, 136, 98, 0.26)` | `rgba(217, 119, 87, 0.3)` | `rgba(95, 124, 255, 0.26)` | `rgba(77, 107, 254, 0.3)` | host's own | |
126
+ | `--dsh-claude-hover-bg` | `hover-wash` | `rgba(4, 4, 4, 0.08)` | `rgba(255, 255, 253, 0.08)` | `rgba(3, 4, 6, 0.08)` | `rgba(251, 255, 255, 0.08)` | `var(--dsw-alias-interactive-bg-hover)` | hover wash |
127
+ | `--dsh-claude-field-ring` | literal | `#2a78d6` | `#2a78d6` | `#2a78d6` | `#2a78d6` | `var(--dsw-alias-brand-primary)` | the ring around a field the reader is renaming in: the session title's own editor, drawn from the selection blue |
128
+ | `--dsh-claude-inline-code-bg` | `code-wash` | `rgba(4, 4, 4, 0.05)` | `rgba(255, 255, 253, 0.05)` | `rgba(3, 4, 6, 0.05)` | `rgba(251, 255, 255, 0.05)` | `var(--dsw-alias-markdown-inline-code)` | inline code fill |
129
+ | `--dsh-claude-inline-code-fg` | card `code` | `#943333` | `#e8a08a` | `#0f1115` | `#eef1f8` | `var(--dsw-alias-label-primary)` | inline code ink |
130
+ | `--dsh-claude-link` | `link` | `#184f95` | `#8ab4f8` | `#3b56d9` | `#8fa4ff` | `var(--dsw-alias-link)` | markdown links |
131
+ | `--dsh-claude-link-underline` | `link-underline` | `rgba(24, 79, 149, 0.6)` | `rgba(138, 180, 248, 0.6)` | `rgba(59, 86, 217, 0.6)` | `rgba(143, 164, 255, 0.6)` | `color-mix(in srgb, var(--dsw-alias-link) 60%, transparent)` | markdown link underline |
132
+ | `--dsw-alias-markdown-code-block` | `code-block` | `#ffffff` | `#1c1c1b` | `#fefefe` | `#1b1e26` | host's own | |
133
+ | `--dsw-alias-markdown-code-block-banner` | `overlay` | `#ffffff` | `#232322` | `#fefefe` | `#22252d` | host's own | |
134
+ | `--dsw-alias-interactive-bg-hover` | `--dsh-claude-hover-bg` | `var(--dsh-claude-hover-bg)` | `var(--dsh-claude-hover-bg)` | `var(--dsh-claude-hover-bg)` | `var(--dsh-claude-hover-bg)` | host's own | |
135
+ | `--dsw-alias-interactive-bg-hover-solid` | `hover-plate` | `#f1f1f0` | `#2d2d2b` | `#eff0f4` | `#2b2f37` | host's own | the host's solid hover chip |
136
+ | `--dsw-alias-label-primary` | `ink` | `#141413` | `#f6f6f4` | `#121316` | `#f4f9ff` | host's own | |
137
+ | `--dsw-alias-label-primary-bluish` | `ink` | `#141413` | `#f6f6f4` | `#121316` | `#f4f9ff` | host's own | |
138
+ | `--dsw-alias-label-secondary` | `ink-2` | `#696861` | `#b2b2aa` | `#646770` | `#aeb5c4` | host's own | |
139
+ | `--dsw-alias-label-tertiary` | `ink-3` | `#898880` | `#908f86` | `#848791` | `#8a92a3` | host's own | |
140
+ | `--dsw-alias-label-caption` | `ink-4` | `#ababa5` | `#6b6b64` | `#a7aab2` | `#676e7d` | host's own | |
141
+ | `--dsw-alias-label-shimmer` | `shimmer` | `#141413` | `#f6f6f4` | `#121316` | `#f4f9ff` | host's own | the highlight band's tint over running words: the host's own rows and the skin's band (shared/sweep-band.ts) alike |
142
+ | `--dsw-alias-label-deep-diving-shimmer` | `shimmer` | `#141413` | `#f6f6f4` | `#121316` | `#f4f9ff` | host's own | the band's tint inside the running row, which the host points --dsw-alias-label-shimmer at; under Claude it is the same warm band as everywhere else |
143
+ | `--dsw-alias-state-business-primary` | `accent` | `#d97757` | `#d97757` | `#4d6bfe` | `#4d6bfe` | host's own | |
144
+ | `--dsw-alias-state-business-tertiary` | `accent-tint` | `#f6ded7` | `#48261b` | `#dce4f7` | `#252f4c` | host's own | |
145
+ | `--dsw-alias-link` | `ui-link` | `#bf6446` | `#eaa088` | `#3e57e0` | `#7594fd` | host's own | text link at rest |
146
+ | `--dsw-alias-shadow-lv2` | literal | `0 4px 18px rgba(20, 20, 19, 0.10), 0 1px 3px rgba(20, 20, 19, 0.05)` | `0 4px 16px rgba(0, 0, 0, 0.30), 0 1px 3px rgba(0, 0, 0, 0.14)` | `0 4px 18px rgba(20, 20, 19, 0.10), 0 1px 3px rgba(20, 20, 19, 0.05)` | `0 4px 16px rgba(0, 0, 0, 0.30), 0 1px 3px rgba(0, 0, 0, 0.14)` | host's own | |
147
+ | `--dsw-specific-input-major` | `inset` | `#ffffff` | `#0f0f0e` | `#fefefe` | `#0e1117` | host's own | |
148
+ | `--dsw-specific-selector` | `selector` | `#fbfbfa` | `#2d2d2b` | `#f9fafe` | `#2b2f37` | host's own | |
149
+ | `--dsw-specific-sidebar-fill` | `sidebar` | `#fbfbf9` | `#141413` | `#f9faff` | `#13161d` | host's own | |
150
+ | `--dsw-alias-brand-primary-new-colorprimary-new-color` | `accent` | `#d97757` | `#d97757` | `#4d6bfe` | `#4d6bfe` | host's own | |
151
+ | `--dsh-claude-canvas` | `canvas` | `#fcfcfb` | `#141413` | `#fafbff` | `#13161d` | `var(--dsw-alias-bg-base)` | the page canvas, the search box |
152
+ | `--dsh-claude-sidebar-canvas` | `sidebar` | `#fbfbf9` | `#141413` | `#f9faff` | `#13161d` | `var(--dsw-specific-sidebar-fill)` | the sidebar |
153
+ | `--dsh-claude-raised` | `card` | — | `#1e1e1d` | — | `#1d2028` | `var(--dsw-alias-bg-overlay)` | popovers and menus raised above the dark canvas |
154
+ | `--dsh-claude-card` | `card` | `#fcfcfb` | `#1e1e1d` | `#fafbff` | `#1d2028` | `var(--dsw-alias-bg-overlay)` | cards on the canvas in light and raised in dark: the account popover, the search palette |
155
+ | `--dsh-claude-inverse-fill` | `ink` | `#141413` | `#f6f6f4` | `#121316` | `#f4f9ff` | `var(--dsw-alias-interactive-bg-hover)` | the model picker's group label fill: an inverted chip under Claude, a hover-plate chip under the host |
156
+ | `--dsh-claude-inverse-ink` | `inverse-ink` | `#fffffe` | `#121211` | `#feffff` | `#11141a` | `var(--dsw-alias-label-primary)` | the model picker's group label ink |
157
+ | `--dsh-claude-ink-strong` | `ink-strong` | — | `#f2f2ee` | — | `#f0f5ff` | `var(--dsw-alias-label-primary)` | active row ink |
158
+ | `--dsh-claude-session-ink` | `session-ink` | — | `#8e8e87` | — | `#8a91a0` | `var(--dsw-alias-label-secondary)` | session title at rest |
159
+ | `--dsh-claude-table-head` | `table-head` | `#f0f0ef` | `#232322` | `#eeeff3` | `#22252d` | `var(--dsw-alias-bg-layer-2)` | table header row |
160
+ | `--dsh-claude-ripple-ink` | `ripple-ink` | `#8a8a85` | `#8e8d83` | `#878991` | `#888fa2` | `var(--dsw-alias-label-secondary, #8a8a85)` | the new-conversation page's glyph field, and the wake a ripple leaves in it |
161
+ | `--dsh-claude-ripple-wave` | literal | `#3b6ef0` | `#7fa6ff` | `#3b6ef0` | `#7fa6ff` | `var(--dsw-alias-link, #3b6ef0)` | the front of a ripple in the new-conversation page's glyph field |
162
+ | `--dsh-claude-scrollbar` | `scrollbar` | `rgba(210, 210, 209, 0.9)` | `rgba(57, 57, 55, 0.9)` | `rgba(208, 209, 213, 0.9)` | `rgba(55, 59, 64, 0.9)` | `var(--dsw-alias-border-l2)` | scrollbar thumb |
163
+ | `--dsh-claude-scrollbar-hover` | `scrollbar-hover` | `rgba(135, 135, 134, 0.8)` | `rgba(107, 107, 105, 0.9)` | `rgba(133, 134, 138, 0.8)` | `rgba(105, 109, 115, 0.9)` | `var(--dsw-alias-label-caption)` | scrollbar thumb under the pointer |
164
+ | `--dsh-claude-link-hover` | `ui-link-hover` | `#a35035` | `#ffbea6` | `#2e41c0` | `#91b1ff` | `var(--dsw-alias-link)` | text link under the pointer |
165
+ | `--dsh-claude-logo-ink` | card `logoInk` | `#141413` | `#f6f6f4` | `#4d6bfe` | `#4d6bfe` | `var(--dsw-alias-label-primary)` | sidebar brand art: the whale and the wordmark |
166
+ | `--dsw-specific-menu` | `overlay` | `#ffffff` | — | `#fefefe` | — | host's own | |
167
+ | `--dsw-specific-bubble` | `bubble` / `bubble-flat` | `#f0f0ed` | `rgba(255, 255, 253, 0.06)` | — | `#262b36` | host's own | user message bubble |
168
+ | `--dsh-claude-chip` | `chip` | `#f6f6f5` | — | `#f4f5f9` | — | `var(--dsw-specific-selector)` | segmented control and switch at rest |
169
+ | `--dsh-claude-meter-peak` | literal | `#a4621d` | `#e2a45f` | `#a4621d` | `#e2a45f` | `var(--dsw-alias-state-warn-label)` | the peak rate badge: the expensive end of a provider's own billing clock |
170
+ | `--dsh-claude-meter-valley` | literal | `#3d7550` | `#8cbf96` | `#3d7550` | `#8cbf96` | `var(--dsw-alias-state-success-primary)` | the off-peak rate badge, and the dated promotions priced below it |
110
171
  <!-- /generated:tokens -->
111
172
 
112
173
  **Host token bindings.** The skin supplies its palette through the host's own
@@ -115,7 +176,7 @@ has to be given all of them. A filled primary button is that case: the host take
115
176
  the fill from `--dsw-alias-brand-primary`, but the hover from a monochrome step
116
177
  of its own scale (light `#43454a`, dark `#ebeef2`) and the label from a
117
178
  foreground token the skin leaves alone. `--dsw-alias-button-primary-fill` and
118
- `--dsw-alias-button-primary-hover` therefore state both steps in each palette.
179
+ `--dsw-alias-button-primary-hover` therefore state both steps in each card.
119
180
  Two fills are palette-specific rather than carried over from the dark base:
120
181
  `--dsw-alias-interactive-bg-hover-solid` (a solid chip, lighter than the canvas
121
182
  in light) and `--dsw-alias-button-elevated-fill` (a surface above the canvas in
@@ -136,7 +197,7 @@ wallpaper plugin that clears the canvas and turns the overlays to glass.
136
197
  The skin's own surfaces read only its private tokens and host tokens. Under the
137
198
  host palette each private token is an alias of a host token (the token table's
138
199
  Host alias column), so those surfaces follow whoever paints the host's. A new
139
- private colour token gets its Claude values and its host alias in
200
+ private colour token gets its tone and its host alias in
140
201
  `packages/client/src/theme/tokens.json`; the build refuses a private token without an alias.
141
202
  Cards take the host's overlay layer rather than its canvas: a plugin that
142
203
  clears the canvas still gives its overlays a readable fill, and the shared
@@ -148,9 +209,35 @@ carries no serif), `--dsh-claude-font-code` to `--ds-font-family-code`.
148
209
 
149
210
  Two colours stay whoever paints: the reasoning slider's violet top rung
150
211
  (`--dsh-claude-apex*`) and the account-hold page, which reproduces a Claude
151
- screen. Translucent neutral hover tints and the usage panel's data colours stay
152
- literal; they read on any canvas. Every other colour that paints a surface, a
153
- text, a border or an accent reads a token.
212
+ screen. The effort trigger's ramp (`--dsh-claude-effort-*`) is the same kind of
213
+ colour — a copy of the reference effort slider's own blue-to-violet ladder, kept
214
+ apart from the brand's accent. Translucent neutral hover tints and the usage
215
+ panel's data colours stay literal; they read on any canvas. Every other colour
216
+ that paints a surface, a text, a border or an accent reads a token.
217
+
218
+ **The effort trigger's tone.** While the Composer tab's effort-accent row is on,
219
+ the effort level's text in the composer's seat box takes its colour from the rung
220
+ in force. Every thinking rung has a place on one ramp between two fixed colours —
221
+ the blue `--dsh-claude-effort-low` and the violet `--dsh-claude-effort-high`, the
222
+ ladder the reference effort slider draws — and the rung's place is its index over
223
+ the ladder's span, so a four-stop ladder reads blue, two steps between, then the
224
+ violet on the strongest level. The ramp is mixed in OKLCH, which keeps the steps
225
+ apart at every ladder length. It reads no brand token: a ramp derived from the
226
+ DeepSeek brand's blue accent left its three levels within a few steps of each
227
+ other, indistinguishable at 13px. The switch-off level and the model's own
228
+ default level have no strength the catalog names, so both keep the resting ink
229
+ (`--dsw-alias-label-secondary`). The row off leaves the resting ink on every
230
+ rung.
231
+
232
+ **The composer's seat.** The model's name and the effort level share one box in
233
+ the row, the way the host's own seat carries both texts: the box is the row's one
234
+ item, it stands against the row's right end and grows leftward, and both of its
235
+ cards hang from that right end. The box paints the hover plate — the two texts are
236
+ two hit areas of one control, not two chips side by side — and the text under the
237
+ pointer takes the stronger ink, except a level wearing the accent ramp, which keeps
238
+ its rung and lets the plate answer the pointer. Each text is as wide as the words
239
+ it shows, so a level's name changing width moves the box's left end and nothing
240
+ else.
154
241
 
155
242
  ## Windows titlebar · 桌面顶栏
156
243
 
@@ -218,11 +305,16 @@ and scrolls to its end.
218
305
  re-picked per surface. The light rungs stay the warm opaque ladder. A copy of a
219
306
  host control keeps that control's own stroke: the inline composer's 1.6px stop
220
307
  square.
221
- - Hairline: 0.5px, for the split between the sidebar and the conversation
222
- (`theme/chrome.css`, one device pixel on a retina display and the width the
223
- product itself states), the Markdown table frame and the trajectory chip
224
- (`theme/typography.css`, `features/chat-files`). Every other single-direction
225
- rule stays 1px.
308
+ - Separator: `--dsh-claude-divider`, a rung below the lightest border, drawn at
309
+ 0.5px on every line that only separates — the sidebar's foot area, the search
310
+ panel's foot, the context stats, the settings rows, a menu's separators, the
311
+ file block's IN/OUT line and the transcript's `hr` (one device pixel on a
312
+ retina display; elsewhere `0.5px` rasterises to one physical pixel). A card, a
313
+ field and a popover keep their 1px border in l1, so an outline always reads
314
+ heavier than a separator inside it. The split between the sidebar and the
315
+ conversation stays 0.5px of l1 (`theme/chrome.css`); the Markdown table frame
316
+ and the trajectory chip stay 0.5px of l2 (`theme/typography.css`,
317
+ `features/chat-files`).
226
318
  - Spacing: 4 px rhythm.
227
319
  - Bottom edge: the transcript never fades behind the composer by shadow. The
228
320
  composer seat paints an opaque `var(--dsw-alias-bg-base)` bar across its own
@@ -255,7 +347,7 @@ edit; the build refuses a time or a curve written anywhere else.
255
347
  - Travel: something moving along its own track (a fold's door, the reasoning
256
348
  slider).
257
349
  - The swap, its gap and the roll of a figure's digits come from the transitions
258
- this skin ports; `THIRD_PARTY_NOTICES.md` names each one.
350
+ this skin ports; `docs/THIRD_PARTY_NOTICES.md` names each one.
259
351
  - Loop periods are separate from durations: a sweep, a pulse, a blink, a breath.
260
352
  - Open: a menu growing out of its trigger, a dialog out of the centre, a
261
353
  settings page sliding in — the transitions.dev surfaces, settling on their own
@@ -277,9 +369,11 @@ edit the JSON, not the table.
277
369
  | `--dsh-claude-duration-instant` | `80ms` | the composer caret following the insertion point |
278
370
  | `--dsh-claude-duration-feedback` | `120ms` | a control answering hover, press or focus: its colour, background, border, shadow, or a small turn or slide of its own parts |
279
371
  | `--dsh-claude-duration-reveal` | `120ms` | content entering the chat area: an opened row's body, and each streamed piece of the answer |
280
- | `--dsh-claude-duration-enter` | `320ms` | one message the reader sends growing into its row, and the same growth on the Motion tab's card |
281
- | `--dsh-claude-duration-surface` | `150ms` | a floating surface or a group of controls appearing: popover cards, menus, panels, the search dialog, a toast, a strip fading in |
372
+ | `--dsh-claude-duration-enter` | `320ms` | one message the reader sends growing into its row, the same growth on the Motion tab's card, and a colour disc lifting out of its row and springing back |
373
+ | `--dsh-claude-duration-surface` | `150ms` | a floating surface or a group of controls appearing: popover cards, menus, panels, the search dialog, a toast, a strip fading in, a hint over what it names |
282
374
  | `--dsh-claude-duration-exit` | `120ms` | a surface leaving on the reader's dismissal: a menu or a dialog closing, the overtime badge leaving |
375
+ | `--dsh-claude-duration-hint-exit` | `50ms` | a hint leaving the moment the pointer leaves what it names |
376
+ | `--dsh-claude-duration-hint-delay` | `80ms` | how long the pointer rests on something before its hint starts to appear |
283
377
  | `--dsh-claude-duration-open` | `250ms` | a surface growing out of its anchor: a menu out of its trigger, a full-window dialog out of the centre, a settings page sliding in, the overtime badge sliding onto its line |
284
378
  | `--dsh-claude-duration-swap` | `150ms` | each half of a wording swap: the old words leaving, the new ones arriving |
285
379
  | `--dsh-claude-duration-swap-gap` | `50ms` | the offset the words arriving start after the words leaving, so the two halves of a wording swap travel together |
@@ -287,7 +381,7 @@ edit the JSON, not the table.
287
381
  | `--dsh-claude-duration-clear-text` | `400ms` | the two halves of clearing a field: the words leaving it, and the placeholder taking their place |
288
382
  | `--dsh-claude-duration-clear` | `1000ms` | one whole clear: the words leaving, the placeholder arriving, and the streak's rise, peak and fall |
289
383
  | `--dsh-claude-duration-roll` | `160ms` | a figure's characters rolling over to new digits |
290
- | `--dsh-claude-duration-move` | `200ms` | something travelling along its own track: a fold's door, the reasoning slider's knob and fill |
384
+ | `--dsh-claude-duration-move` | `200ms` | something travelling along its own track: a fold's door, the reasoning slider's knob and fill, a hint moving from one colour disc to the next |
291
385
  | `--dsh-claude-duration-count` | `220ms` | a session number counting to its new reading |
292
386
  | `--dsh-claude-duration-slide` | `240ms` | the segmented controls' sliding highlight, a sidebar icon's quarter turn, the wording box taking the width of the words arriving, and streamed content sliding up from the bottom edge |
293
387
  | `--dsh-claude-duration-fade` | `300ms` | a slow cross-fade: the theme flip, the titlebar tabs' hover reveal, the reasoning knob's glow, a placeholder handing its place to what it stood for |
@@ -319,25 +413,28 @@ edit the JSON, not the table.
319
413
  | `--dsh-claude-period-dot-bounce` | `500ms` | one bounce of the waiting line's loader dots under the Claude brand, and the period each dot's own start is measured against |
320
414
  | `--dsh-claude-period-dot-line` | `1250ms` | one round trip of the waiting line's loader dots along their own lines, the motion the dots take while the turn is not thinking |
321
415
  | `--dsh-claude-ease-standard` | `ease` | feedback and surfaces: the default curve |
322
- | `--dsh-claude-ease-out` | `ease-out` | something arriving and settling: a fold's door, content entering the chat area, the landing mark |
416
+ | `--dsh-claude-ease-out` | `ease-out` | something arriving and settling: a fold's door, content entering the chat area, the landing mark, a hint appearing and leaving |
323
417
  | `--dsh-claude-ease-enter` | `cubic-bezier(0.34, 1.3, 0.64, 1)` | a message the reader sends growing into its row: the slight overshoot as it takes its full size |
324
418
  | `--dsh-claude-ease-in-out` | `ease-in-out` | something that leaves and returns, or swaps in place: wording swaps, pulses, flashes |
325
419
  | `--dsh-claude-ease-glide` | `cubic-bezier(0.22, 0.61, 0.36, 1)` | travel along a track: the sliding highlight, the reasoning slider, the search dialog's entrance, the reasoning window's step, the wording box's width, the stream's slide |
326
420
  | `--dsh-claude-ease-roll` | `cubic-bezier(0.4, 0, 0.2, 1)` | digits rolling over: the file rows' tail and the process group header's counts |
327
421
  | `--dsh-claude-ease-spring` | `cubic-bezier(0.34, 1.45, 0.64, 1)` | a small overshoot as something lands: the overtime badge popping in, a switch's knob bouncing past its end |
328
- | `--dsh-claude-ease-settle` | `cubic-bezier(0.22, 1, 0.36, 1)` | a surface or a page settling into place out of its anchor: menus and dialogs opening and closing, a settings page sliding, the overtime badge sliding onto its line, the greeting's lines rising |
422
+ | `--dsh-claude-ease-recoil` | `cubic-bezier(0.34, 3.85, 0.64, 1)` | a lifted colour disc springing back into its row once the pointer leaves, overshooting well past its place before it rests |
423
+ | `--dsh-claude-ease-settle` | `cubic-bezier(0.22, 1, 0.36, 1)` | a surface or a page settling into place out of its anchor: menus and dialogs opening and closing, a settings page sliding, the overtime badge sliding onto its line, the greeting's lines rising, a hint travelling between colour discs, a colour disc lifting |
329
424
  | `--dsh-claude-ease-host-sweep` | `steps(48, end)` | the band across the waiting line's words and a running process group's header |
330
425
  | `--dsh-claude-ease-harmonic` | `cubic-bezier(0.37, 0, 0.63, 1)` | a loader dot walking its line from one end to the other, and its size between an end and the middle: a sine's simple harmonic, at rest at either end and fastest halfway |
331
426
  | `--dsh-claude-ease-damped-out` | `cubic-bezier(0.33, 1, 0.68, 1)` | a loader dot's fade in a hand-over that does most of its change early: a walking or swapping dot coming in, a bouncing one going out |
332
427
  | `--dsh-claude-ease-damped-in` | `cubic-bezier(0.32, 0, 0.67, 0)` | a loader dot's fade in a hand-over that does most of its change late: a walking or swapping dot going out, a bouncing one coming in |
333
- | `--dsh-claude-distance-nudge` | `4px` | the short offset a surface rises from, and a small row's wording swap travels |
428
+ | `--dsh-claude-distance-nudge` | `4px` | the short offset a surface rises from, a small row's wording swap travels, and the colour disc under the pointer lifts |
334
429
  | `--dsh-claude-distance-travel` | `8px` | the waiting line's wording swap, a settings page's slide, the overtime badge's sideways slide, and both directions of the waiting line's loader dots: the lift off their floor and the reach along their own lines |
335
430
  | `--dsh-claude-distance-rise` | `12px` | how far below its place a line of the home greeting starts, and the overtime badge's upward slide |
336
431
  | `--dsh-claude-blur-soft` | `2px` | the blur words and badges pass through while they swap or pop in, and a placeholder passes through as it hands its place over |
337
432
  | `--dsh-claude-blur-enter` | `3px` | the blur a settings page or a line of the home greeting passes through as it slides or rises in |
338
- | `--dsh-claude-scale-surface` | `0.98` | the scale a surface grows from as it rises |
433
+ | `--dsh-claude-scale-surface` | `0.98` | the scale a surface grows from as it rises, and a hint grows from as it appears |
339
434
  | `--dsh-claude-scale-dropdown` | `0.97` | the scale a menu grows from out of its trigger |
340
435
  | `--dsh-claude-scale-dropdown-exit` | `0.99` | the scale a menu shrinks to while it fades on closing |
436
+ | `--dsh-claude-scale-lift` | `1.05` | the scale the colour disc under the pointer grows to as it lifts |
437
+ | `--dsh-claude-scale-lift-falloff` | `0.45` | the share of its neighbour's lift a colour disc keeps, one disc further from the pointer |
341
438
  | `--dsh-claude-scale-dialog` | `0.96` | the scale a full-window dialog grows from and returns to |
342
439
  | `--dsh-claude-scale-dot-mid` | `0.55` | how small a loader dot is while it crosses the middle of its line; at either end it is the dot's own size, so the line motion never draws a dot larger than the bouncing one |
343
440
  | `--dsh-claude-duration-resize` | `300ms` | a surface taking a new size: the model picker's second level following the list a query leaves |
@@ -401,9 +498,12 @@ host's own crumb already carries the padding and the radius — with a tip under
401
498
  the segment naming the press, in the label ink on the canvas tone the usage
402
499
  panel's day tip uses. The segment carries the tip rather than the words because
403
500
  the host clips a crumb's overflow for its ellipsis. The press opens a field over
404
- the words at the header's own size and radius, standing in the page's own space
405
- so the reader's zoom keeps it on the title; a rename the host refuses keeps the
406
- field, ringed in the host's error tone.
501
+ the words' own line: canvas fill, a 1px ring in the selection blue, a 4px radius,
502
+ and 1px to either side of the words with 3px above and below them, so the ring
503
+ hugs the name the way Claude's own field does rather than laying a card over it.
504
+ The field stands in the page's own space, so the reader's zoom keeps it on the
505
+ title; a rename the host refuses keeps the field, ringed in the host's error
506
+ tone.
407
507
 
408
508
  ## Markdown material
409
509
 
@@ -486,13 +586,13 @@ the shell itself. What it carries is described under "Context popover" below.
486
586
  **Heading, separator, footer**
487
587
 
488
588
  - heading row: 11px / 16px at 600, `letter-spacing: .04em`, uppercase, `label-tertiary`, `padding: 6px 7px 2px`
489
- - separator: `0.5px` `var(--dsw-alias-border-l2)` — the host's own line on a menu
490
- surface (`Menu.module.css`) — `margin: 2px 4px`, drawn as a top border on a
491
- zero-height box. One rule in the shared shell covers every separator in a card,
492
- the host's own menu separators included, so the line is one thickness wherever
493
- it appears and does not follow the card's opening scale
494
- - pinned footer: `margin-top` / `padding-top` 4px, and the same `0.5px`
495
- `var(--dsw-alias-border-l2)` line above it
589
+ - separator: `0.5px` `var(--dsh-claude-divider)` — one rung below the lightest
590
+ border — `margin: 2px 4px`, drawn as a top border on a zero-height box. One
591
+ rule in the shared shell covers every separator in a card, the host's own menu
592
+ separators included, so the line is one thickness wherever it appears and does
593
+ not follow the card's opening scale
594
+ - pinned footer: `margin-top` / `padding-top` 4px, and the same `0.5px` divider
595
+ line above it
496
596
 
497
597
  **Host surfaces**
498
598
 
@@ -761,10 +861,11 @@ shows the wording swap as well as the paint.
761
861
  With the chat area's own follow on, the row is pinned while the conversation
762
862
  follows its tail, at the place that follow's glide comes to rest — the
763
863
  composer's own height, the fade band above it and the host's 16px transcript
764
- padding — the canvas painted behind it, since the transcript's tail would
765
- otherwise show through. The pin stands only while the host reports the tail (or
766
- the stream glide holds the position) and steps aside for the reader's own
767
- scrolling.
864
+ padding — with the canvas carried on down to the composer's top, since the
865
+ host's clip leaves a strip under the row where the line a stream slide brings
866
+ up would otherwise show below the line. The pin stands only while the host
867
+ reports the tail (or the stream glide holds the position) and steps aside for
868
+ the reader's own scrolling.
768
869
 
769
870
  ## Home layouts · 首页版面
770
871
 
@@ -78,7 +78,9 @@ The "Input clear with dissolve" transition (the search field at the top of the m
78
78
 
79
79
  The "Card resize" transition (the model picker's second level taking the height of the list a query leaves, `packages/client/src/features/model/sub-menu.ts` with the `dsh-claude-model-popover-sub` rule in its stylesheet) is ported as the width and height tween it is, with its duration as this package's `--dsh-claude-duration-resize` and its curve the settling one the other surface transitions already read. A height cannot be interpolated into `auto`, so the two ends are written as lengths around the rebuild and the height returns to the content once the travel lands. Its `prefers-reduced-motion` guard is answered by the skin's animation choice (D40).
80
80
 
81
- Source: <https://transitions.dev/detail.html?t=text-states-swap> · <https://transitions.dev/detail.html?t=reasoning-stream> · <https://transitions.dev/detail.html?t=menu-dropdown> · <https://transitions.dev/detail.html?t=modal-open-close> · <https://transitions.dev/detail.html?t=page-side-by-side> · <https://transitions.dev/detail.html?t=notification-badge> · <https://transitions.dev/detail.html?t=skeleton-loader-and-reveal> · <https://transitions.dev/detail.html?t=texts-reveal> · <https://transitions.dev/detail.html?t=toggle> · <https://transitions.dev/detail.html?t=pro-gradient-text> · <https://transitions.dev/detail.html?t=input-clear-dissolve> · <https://transitions.dev/detail.html?t=card-resize> · <https://github.com/Jakubantalik/transitions.dev>
81
+ The "Tooltip open/close" and "Avatar group hover" transitions (the colour cards' discs on the settings page, `packages/client/src/features/settings/settings-brand.ts` with the `dsh-claude-palette-hint` and `dsh-claude-palette-swatch` rules in `settings.css`) are ported together: one hint per row of discs that appears after a short rest, travels and resizes between discs while it shows and leaves at once, with its geometry written with transitions off while it is hidden; and the disc under the pointer lifting and growing while its neighbours lift by a falloff per step, rising on the settling curve and springing back on the snippet's overshooting one. Their delay, exit, scale, lift, falloff and curve are this package's motion tokens, and the `prefers-reduced-motion` guard is answered by the skin's animation choice (D40).
82
+
83
+ Source: <https://transitions.dev/detail.html?t=text-states-swap> · <https://transitions.dev/detail.html?t=reasoning-stream> · <https://transitions.dev/detail.html?t=menu-dropdown> · <https://transitions.dev/detail.html?t=modal-open-close> · <https://transitions.dev/detail.html?t=page-side-by-side> · <https://transitions.dev/detail.html?t=notification-badge> · <https://transitions.dev/detail.html?t=skeleton-loader-and-reveal> · <https://transitions.dev/detail.html?t=texts-reveal> · <https://transitions.dev/detail.html?t=toggle> · <https://transitions.dev/detail.html?t=pro-gradient-text> · <https://transitions.dev/detail.html?t=input-clear-dissolve> · <https://transitions.dev/detail.html?t=card-resize> · <https://transitions.dev/detail.html?t=tooltip-open-close> · <https://transitions.dev/detail.html?t=avatar-group-hover> · <https://github.com/Jakubantalik/transitions.dev>
82
84
 
83
85
  ```
84
86
  Transitions.dev License
Binary file
Binary file
Binary file
Binary file