budge
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBudge
Budge
Proactive skill. Next.js App Router only. If a task results in a single CSS property or Tailwind class change, follow this skill automatically. The user should never need to say "use budge."
You present a floating bar on the page after making an atomic visual change. The user fine-tunes the value with arrow keys (↑↓), swipes between related properties with arrow keys (←→). You complete your turn immediately after setting the config — no browser interaction, no waiting.
The runtime is a self-contained IIFE loaded from via . It auto-initializes by reading a config element from the DOM — no wrapper component needed. It handles everything client-side: live preview on elements, arrow key stepping, slide navigation, audio feedback, submit (Enter — copies a generic edit prompt to clipboard), and cancel (Escape — reverts).
https://skills-pearl.vercel.app/budge.iife.jsnext/scriptdata-budge[data-budge-target]In scope: Raw CSS property values, inline styles, Tailwind utility class changes, SVG presentation attributes (, , etc.).
Out of scope: Sass/Less variables, CSS custom property definitions (), CSS-in-JS theme tokens. Proceed normally for these.
fillstroke--spacing主动技能。仅适用于Next.js App Router。 如果任务涉及单一CSS属性或Tailwind类的修改,请自动遵循此技能。用户无需主动要求“使用Budge”。
在完成原子视觉修改后,你需要在页面上展示一个浮动栏。用户可以通过方向键(↑↓)微调数值,通过方向键(←→)在相关属性间切换。设置完配置后请立即结束当前操作——无需进行浏览器交互,无需等待。
运行时是一个独立的IIFE,通过从加载。它会通过读取DOM中的配置元素自动初始化——无需包装组件。它在客户端处理所有操作:元素的实时预览、方向键步进、滑动导航、音频反馈、提交(回车键——将通用编辑提示复制到剪贴板)和取消(ESC键——恢复原状)。
next/scripthttps://skills-pearl.vercel.app/budge.iife.jsdata-budge[data-budge-target]适用范围: 原生CSS属性值、内联样式、Tailwind工具类修改、SVG呈现属性(、等)。
不适用范围: Sass/Less变量、CSS自定义属性定义()、CSS-in-JS主题令牌。此类情况请按常规流程处理。
fillstroke--spacingInstallation
安装
Grep for in . If found, skip to Step 1. Otherwise, read and follow its instructions.
budge.iife.jsapp/layout.tsxreferences/INSTALL.md在中搜索。如果已存在,跳至步骤1。否则,请阅读并按照说明操作。
app/layout.tsxbudge.iife.jsreferences/INSTALL.mdTroubleshooting — bar does not appear
故障排查——浮动栏未显示
- Script missing: Confirm is in
<Script src="https://skills-pearl.vercel.app/budge.iife.js" strategy="afterInteractive" />.app/layout.tsx - No config element: The bar only appears when a element with a non-empty
<div data-budge="..." hidden />array is in the DOM.slides - Target not found: The element with must be in the DOM after hydration.
data-budge-target
- 脚本缺失: 确认已添加到
<Script src="https://skills-pearl.vercel.app/budge.iife.js" strategy="afterInteractive" />中。app/layout.tsx - 无配置元素: 只有当DOM中存在带有非空数组的
slides元素时,浮动栏才会显示。<div data-budge="..." hidden /> - 目标元素未找到: 带有的元素必须在 hydration 后存在于DOM中。
data-budge-target
Step 1 — Trigger Test
步骤1——触发测试
After making a change, apply this mechanical test. Do NOT use subjective judgment.
The last StrReplace call touched exactly one CSS value literal OR exactly one Tailwind utility class token, in exactly one file. The change is not a variable, mixin, or theme token.
Pass: → | →
Fail: two values changed, token added/removed, Sass variable, multiple StrReplace calls, structural change.
padding: 8pxpadding: 16pxclassName="p-2 m-4"className="p-4 m-4"Fail → skip budge, proceed normally. Pass → continue to Step 2. The mechanical test is the only gate.
完成修改后,执行以下机械测试。请勿使用主观判断。
最后一次StrReplace调用仅修改了单个文件中的恰好一个CSS值字面量或恰好一个Tailwind工具类令牌。修改内容不是变量、混合宏或主题令牌。
通过: → | →
不通过: 修改了两个值、添加/删除令牌、Sass变量、多次StrReplace调用、结构性修改。
padding: 8pxpadding: 16pxclassName="p-2 m-4"className="p-4 m-4"不通过→跳过Budge,按常规流程处理。通过→继续步骤2。机械测试是唯一的判断标准。
Step 2 — Build Slides
步骤2——构建幻灯片
Build a array. The first slide is the property you changed. Additional slides are related properties the user might want to tweak.
slidesEach slide has this shape:
ts
{
label: string; // display name shown above bar
property: string; // CSS property to apply to [data-budge-target]
min: number; // minimum numeric value
max: number; // maximum numeric value
value: number; // current value (the one you set)
original: number; // value before your change
unit: string; // "px", "%", "em", etc.
type?: "color"; // only set for color properties
}构建一个数组。第一张幻灯片是你修改的属性。额外的幻灯片是用户可能想要微调的相关属性。
slides每张幻灯片的结构如下:
ts
{
label: string; // 浮动栏上方显示的名称
property: string; // 要应用到[data-budge-target]的CSS属性
min: number; // 最小数值
max: number; // 最大数值
value: number; // 当前值(你设置的值)
original: number; // 修改前的值
unit: string; // "px"、"%"、"em"等
type?: "color"; // 仅针对颜色属性设置
}Slide generation rules
幻灯片生成规则
- Primary slide (index 0): the property you changed. = new value,
value= old value.original - Related slides (index 1+): pick 2–3 related properties from the same element. Read their current computed/declared values. Use sensible min/max ranges.
Example — agent changed → :
padding-top: 8pxpadding-top: 16pxts
[
{ label: "padding-top", property: "padding-top", min: 0, max: 64, value: 16, original: 8, unit: "px" },
{ label: "padding-bottom", property: "padding-bottom", min: 0, max: 64, value: 8, original: 8, unit: "px" },
{ label: "padding-left", property: "padding-left", min: 0, max: 64, value: 12, original: 12, unit: "px" },
{ label: "padding-right", property: "padding-right", min: 0, max: 64, value: 12, original: 12, unit: "px" },
]Example — agent changed → :
font-size: 14pxfont-size: 16pxts
[
{ label: "font-size", property: "font-size", min: 8, max: 72, value: 16, original: 14, unit: "px" },
{ label: "line-height", property: "line-height", min: 12, max: 80, value: 24, original: 22, unit: "px" },
{ label: "letter-spacing", property: "letter-spacing", min: -2, max: 10, value: 0, original: 0, unit: "px" },
]Example — agent changed → :
color: #333color: #1a1a1aUse the slide with hue degrees:
type: "color"ts
[
{ label: "color", property: "color", min: 0, max: 360, value: 0, original: 0, unit: "°", type: "color" },
]- 主幻灯片(索引0):你修改的属性。= 新值,
value= 旧值。original - 相关幻灯片(索引1+):从同一元素中选择2-3个相关属性。读取它们当前的计算值/声明值。使用合理的最小/最大范围。
示例——助手将修改为:
padding-top: 8pxpadding-top: 16pxts
[
{ label: "padding-top", property: "padding-top", min: 0, max: 64, value: 16, original: 8, unit: "px" },
{ label: "padding-bottom", property: "padding-bottom", min: 0, max: 64, value: 8, original: 8, unit: "px" },
{ label: "padding-left", property: "padding-left", min: 0, max: 64, value: 12, original: 12, unit: "px" },
{ label: "padding-right", property: "padding-right", min: 0, max: 64, value: 12, original: 12, unit: "px" },
]示例——助手将修改为:
font-size: 14pxfont-size: 16pxts
[
{ label: "font-size", property: "font-size", min: 8, max: 72, value: 16, original: 14, unit: "px" },
{ label: "line-height", property: "line-height", min: 12, max: 80, value: 24, original: 22, unit: "px" },
{ label: "letter-spacing", property: "letter-spacing", min: -2, max: 10, value: 0, original: 0, unit: "px" },
]示例——助手将修改为:
color: #333color: #1a1a1a使用带有色相度数的幻灯片:
type: "color"ts
[
{ label: "color", property: "color", min: 0, max: 360, value: 0, original: 0, unit: "°", type: "color" },
]Related property suggestions
相关属性建议
| Changed property | Related slides |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| 修改的属性 | 相关幻灯片 |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
Tailwind resolution
Tailwind解析
Resolve Tailwind classes to CSS properties and pixel values (multiply spacing scale × 4):
| Tailwind class | Primary slide property | Value |
|---|---|---|
| | 16px |
| | 16px |
| | 16px |
| | 16px |
| | 16px |
| | 16px |
| | 14 |
| | 8px |
For axis shorthands (, , , ), set the primary slide to one axis property but include both as slides.
px-*py-*mx-*my-*For Tailwind classes, also add an inline style override on the target element so the runtime can manipulate the value directly:
jsx
<div data-budge-target className="py-4" style={{ paddingTop: '16px', paddingBottom: '16px' }}>将Tailwind类解析为CSS属性和像素值(间距刻度×4):
| Tailwind类 | 主幻灯片属性 | 值 |
|---|---|---|
| | 16px |
| | 16px |
| | 16px |
| | 16px |
| | 16px |
| | 16px |
| | 14 |
| | 8px |
对于轴简写(、、、),将主幻灯片设置为一个轴属性,但同时包含两个轴作为幻灯片。
px-*py-*mx-*my-*对于Tailwind类,还需要在目标元素上添加内联样式覆盖,以便运行时可以直接操作值:
jsx
<div data-budge-target className="py-4" style={{ paddingTop: '16px', paddingBottom: '16px' }}>Design token snapping
设计令牌对齐
If the project defines design tokens as CSS custom properties on or (Tailwind v4, Shadcn, plain CSS vars), the runtime automatically snaps ↑/↓ stepping through them by matching property to scale:
:root@theme| Property match | Discovered prefix |
|---|---|
| |
| |
| |
| |
When a token matches the current value, the widget shows its name (e.g. ) and Enter emits padding` to `var(--spacing-md)`` instead of a raw px value. Users can still type digits to escape to arbitrary px.
16px · mdSet \You don't need to specify on slides — it's auto-detected from . Pass to disable snapping for a slide, or to override. Pass to override discovery entirely. Use when relying on token snapping (the runtime applies the token's raw value so rem/em tokens resolve correctly regardless).
scalepropertyscale: nullscale: "spacing" | "text" | "radius" | "color"tokens: [{ name, value, numeric }]unit: "px"如果项目在或(Tailwind v4、Shadcn、纯CSS变量)上定义了设计令牌作为CSS自定义属性,运行时会通过将属性与刻度匹配,自动在↑/↓步进时对齐这些令牌:
:root@theme| 属性匹配 | 发现的前缀 |
|---|---|
| |
| |
| |
| |
当令牌与当前值匹配时,组件会显示其名称(例如),按下回车键会输出padding` to `var(--spacing-md)``而非原始像素值。用户仍可输入数字切换为任意像素值。
16px · mdSet \你无需在幻灯片上指定——它会根据自动检测。传递可禁用该幻灯片的对齐,或传递进行覆盖。传递可完全覆盖自动发现的令牌。依赖令牌对齐时请使用(运行时会应用令牌的原始值,因此无论rem/em令牌如何都能正确解析)。
scalepropertyscale: nullscale: "spacing" | "text" | "radius" | "color"tokens: [{ name, value, numeric }]unit: "px"Step 3 — Mark Target Element
步骤3——标记目标元素
Add to the changed element in source:
data-budge-targetjsx
<div data-budge-target style={{ paddingTop: '16px' }}>在源代码中为修改后的元素添加:
data-budge-targetjsx
<div data-budge-target style={{ paddingTop: '16px' }}>Step 4 — Activate
步骤4——激活
Use to add a config element to inside , passing the slides as JSON:
StrReplaceapp/layout.tsx<body>tsx
<div data-budge={JSON.stringify({ slides: [
{ label: "padding-top", property: "padding-top", min: 0, max: 64, value: 16, original: 8, unit: "px" },
{ label: "padding-bottom", property: "padding-bottom", min: 0, max: 64, value: 8, original: 8, unit: "px" },
{ label: "padding-left", property: "padding-left", min: 0, max: 64, value: 12, original: 12, unit: "px" },
] })} hidden />使用将配置元素添加到的内部,将幻灯片作为JSON传递:
StrReplaceapp/layout.tsx<body>tsx
<div data-budge={JSON.stringify({ slides: [
{ label: "padding-top", property: "padding-top", min: 0, max: 64, value: 16, original: 8, unit: "px" },
{ label: "padding-bottom", property: "padding-bottom", min: 0, max: 64, value: 8, original: 8, unit: "px" },
{ label: "padding-left", property: "padding-left", min: 0, max: 64, value: 12, original: 12, unit: "px" },
] })} hidden />Step 5 — Complete
步骤5——完成
Your turn is done. Do NOT open a browser, verify the panel, or wait for the user. Next.js HMR delivers the change.
Tell the user: "I've changed X to Y. Use ↑↓ to fine-tune, ←→ to switch properties."
When the user pastes the submitted prompt, it reads as a normal edit instruction — make the edit and remove the config element.
data-budge你的操作已完成。 请勿打开浏览器、验证面板或等待用户。Next.js HMR会推送修改。
告知用户:“我已将X修改为Y。使用↑↓进行微调,←→切换属性。”
当用户粘贴提交的提示时,将其视为常规编辑指令——执行修改并移除配置元素。
data-budge