
Tweaks
- 248 installs
- 83.7k repo stars
- Updated August 5, 2026
- nexu-io/open-design
tweaks is a UI design skill that applies targeted spacing, color, typography, and component polish for developers refining interfaces before release without a full redesign.
About
tweaks is a nexu-io/open-design skill for incremental UI refinement when a screen is structurally sound but spacing, color, typography, or component details feel off before release. The skill guides small layout adjustments, token-aligned color fixes, type scale corrections, and component edge polish rather than wholesale information-architecture changes. Developers reach for tweaks after feature-complete pages need a design pass that is faster than a redesign sprint. It fits design-system-backed React or web apps where margin, padding, contrast, and hierarchy tweaks unlock production readiness. The module assumes existing components and pages; it optimizes visual quality and consistency in place. Pair tweaks with broader open-design skills when the problem is polish, not new flows or brand exploration.
- visual polish
- spacing fixes
- typography tweaks
- pre-ship refinement
- component adjustments
Tweaks by the numbers
- 248 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #875 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/nexu-io/open-design --skill tweaksAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 248 |
|---|---|
| repo stars | ★ 83.7k |
| Last updated | August 5, 2026 |
| Repository | nexu-io/open-design ↗ |
How do you polish UI spacing and typography before release?
Apply targeted visual and layout tweaks—spacing, color, typography, component polish—to refine UI before release without full redesigns.
Who is it for?
Frontend developers with feature-complete UIs who need fast spacing, color, typography, and component polish before release.
Skip if: Greenfield products needing full information architecture, new design systems, or brand identity exploration from scratch.
When should I use this skill?
An existing UI screen needs targeted spacing, color, typography, or component polish refinements before shipping.
What you get
Updated spacing, color, typography, and component polish specs applied to existing screens without redesign.
- spacing and typography tweak spec
- component polish checklist
Files
Tweaks Skill · 参数化变体面板
Wrap any HTML artifact with a side panel of live controls that rewrite CSS custom properties in real time and persist to localStorage. Inspired by the huashu-design tweak pattern.
What you produce
A single self-contained HTML file with two layers:
1. Stage — the original artifact (landing page / deck / dashboard) re-keyed so all visual decisions read from CSS custom properties: --accent, --scale, --density, --mode, --motion. 2. Panel — a fixed sidebar (or drawer on small viewports) with form controls bound to those custom properties via a tiny vanilla-JS bridge. Persists every change to localStorage keyed by the artifact identifier.
The user can:
- Open the artifact and see the stage rendered with their saved
preferences (or sensible defaults).
- Adjust accent / scale / density / mode / motion in the panel and
watch the stage update instantly — no rerender.
- Press <kbd>T</kbd> to hide / reveal the panel; <kbd>R</kbd> to
reset to defaults.
- Refresh the page — every choice is persisted.
When to use
- The user generated something they like 80% of, and wants to dial
in the last 20% themselves.
- You're presenting a design system / brand and want the audience to
feel the variants live (instead of you re-running the agent).
- You're shipping a stand-alone demo (e.g. a portfolio piece) and
want viewers to play.
When not to use
- One-shot artifacts that won't be iterated on (e.g. a runbook —
parameters don't help).
- When the artifact's value is in fixed ratios (e.g. an infographic
with carefully balanced data viz — knobs would degrade it).
The 5 standard knobs
Pick a subset that suits the artifact. Don't ship all 5 if only 2
matter — clutter is a regression.
1. --accent — Accent color
A select with 5–8 curated swatches (don't ship a free color picker — the user will pick a bad color and blame you).
const ACCENT_PRESETS = [
{ id: 'rust', val: '#c96442', label: 'Rust' },
{ id: 'cobalt', val: '#2c4d8e', label: 'Cobalt' },
{ id: 'sage', val: '#4a7a3f', label: 'Sage' },
{ id: 'plum', val: '#7a3f6a', label: 'Plum' },
{ id: 'graphite',val: '#3a3a3a', label: 'Graphite' },
];The artifact uses var(--accent) everywhere it had a hard-coded accent before. Border / link / pull-quote rule / CTA all flip together.
2. --scale — Type scale (0.85 / 1.0 / 1.15)
Three settings: Compact (0.85), Normal (1.0), Generous (1.15). All font-size declarations multiply by var(--scale) via calc(... * var(--scale)).
Don't go beyond ±15% — beyond that the layout breaks (column flow, breakpoints, line counts).
3. --density — Layout density (Tight / Normal / Roomy)
Three settings that swap the spacing scale: Tight (0.75) / Normal (1.0) / Roomy (1.4). All padding / gap / margin declarations multiply by var(--density).
This is the highest-impact knob — it's also the most fragile, so every layout-critical container must declare its base spacing in custom properties before you wrap.
4. --mode — Light / Dark
A 2-state toggle. Sets data-mode="light" vs "dark" on the <html> element and the artifact's :root selector responds with two color sets.
If the artifact already has a media-query-based dark mode, replace it with the data-attr version — the user's choice should win over their OS.
5. --motion — Off / Subtle / Lively
Three settings. Maps to a CSS variable --motion-mult that scales all transition-duration / animation-duration declarations:
- Off —
0s(also disables WebGL canvases / decorative animation). - Subtle —
1.0(the artifact's authored timing). - Lively —
1.6(slower transitions, more visible motion).
Respect prefers-reduced-motion: default to Off if the user has that set, regardless of stored preference.
Host integration contract (REQUIRED)
The Open Design viewer toolbar has a Tweaks toggle that drives panel visibility from outside the iframe. For the toggle to bind to your panel, your artifact must speak one of these two protocols (pick one; don't mix). The toolbar enables itself the moment it sees either signal.
Protocol A — postMessage (recommended for agent-generated artifacts)
Use this when the panel mounts via JS (React, vanilla, anything dynamic).
Artifact → host:
- On mount, post
{ type: '__edit_mode_available', visible?: boolean }to
window.parent. Tells the toolbar a panel exists; the optional visible reports the panel's initial state so the toolbar toggle starts in sync. Omit visible for the common "panel is already on screen" case (the host treats a missing field as true so the legacy zero-arg message keeps working). Pass visible: false to declare a default-closed panel.
- When the user closes the panel locally (× button, Esc, etc.), post
{ type: '__edit_mode_dismissed' }. Toolbar flips to "off".
Host → artifact:
{ type: '__activate_edit_mode' }— open the panel (setOpen(true)).{ type: '__deactivate_edit_mode' }— close the panel (setOpen(false)).
Minimal listener:
window.addEventListener('message', (e) => {
const t = e?.data?.type;
if (t === '__activate_edit_mode') setOpen(true);
else if (t === '__deactivate_edit_mode') setOpen(false);
});
// Or, for a default-closed panel:
// window.parent.postMessage({ type: '__edit_mode_available', visible: open }, '*');
window.parent.postMessage({ type: '__edit_mode_available' }, '*');
// in your close handler:
const dismiss = () => {
setOpen(false);
window.parent.postMessage({ type: '__edit_mode_dismissed' }, '*');
};Panel may default to open or closed — the host syncs its toggle to whichever state the artifact reports.
Protocol B — class-based (used by assets/wrap.html)
Use this only when you wrap the template verbatim. The artifact ships a .tw-panel element and toggles a .tw-hidden class for visibility. The viewer's iframe bridge (in apps/web/src/runtime/srcdoc.ts) hides the panel on initial paint, watches the class via MutationObserver, and relays state both directions. No JS required in the artifact beyond what the template already includes.
Selectors are fixed: .tw-panel (the panel root) and .tw-hidden (the hidden state). If you rename either, the bridge can't find it.
Anti-pattern
Don't invent a third protocol or rename either set of identifiers. The toolbar toggle only binds to A or B. Custom panels with custom classes and no postMessage will leave the toolbar greyed out.
Implementation primitives
Read assets/wrap.html — it ships the panel + bridge as an inert template. Your job is to:
1. Take the user's existing artifact HTML. 2. Lift its accent / mode / spacing / scale into custom properties (search for hard-coded #hex / Npx / Nrem and convert). 3. Paste the contents into the marked region of wrap.html. 4. Edit assets/wrap.html's KNOBS array to keep only the knobs you decided are relevant to this artifact. Don't ship 5 if 2 matter. 5. Patch the STORAGE_KEY to a unique slug (tweaks-<artifact-slug>).
The bridge in wrap.html:
- Loads
localStorage[STORAGE_KEY]JSON on first paint. - Applies values as
document.documentElement.style.setProperty('--accent', ...). - Listens to every form control's
changeevent and writes back. - Exposes <kbd>T</kbd> (toggle panel) and <kbd>R</kbd> (reset).
Workflow
Step 1 — Acquire the artifact
Same options as the critique skill:
1. Project file (index.html in the project folder). 2. Pasted HTML in the chat. 3. Generated by you in this turn.
Step 2 — Decide which knobs apply
Read the artifact's CSS first. For each knob, decide yes / no:
--accent— yes if the artifact has 1 accent color used ≥ 3 times.--scale— yes if the artifact is type-driven (article, deck,
pricing page).
--density— yes if the artifact has consistent gap / padding
rhythm (deck, dashboard, landing). No for runbooks (already dense).
--mode— yes if the artifact has authored dark mode tokens, or
you're willing to derive them.
--motion— yes if the artifact has any transition / animation
worth scaling. No for static reports / critique reports.
Default: 3 knobs is the sweet spot. Five is too busy, one is not worth a panel.
Step 3 — Lift hard-coded values into custom properties
Open assets/wrap.html's <style> block — copy its custom-property naming scheme (--accent, --scale, etc.). In the user's artifact, find every place those concerns live and rewrite:
color: #c96442→color: var(--accent)font-size: 18px→font-size: calc(18px * var(--scale))padding: 24px 32px→padding: calc(24px * var(--density)) calc(32px * var(--density))transition: opacity 200ms→transition: opacity calc(200ms * var(--motion-mult))
If the artifact uses clamp() or vw already, multiply the outer value by the custom property — don't tear apart clamp(...).
Step 4 — Paste into the wrap
Copy the artifact's <style> and <body> into the marked regions of wrap.html. Keep the panel + bridge intact.
Step 5 — Test the loop
Open the result, click each knob at least once, refresh the page, confirm the choice persists. If a knob breaks the layout — remove it, don't ship it.
Output contract
<artifact identifier="tweaks-<artifact-slug>" type="text/html" title="<Artifact Title> · Tweaks">
<!doctype html>
<html>...</html>
</artifact>One sentence before the artifact ("Wrapped X with a 3-knob tweak panel — accent / scale / mode."). Stop after </artifact>.
Hard rules
- Don't ship a free color picker — only curated swatches. Users
pick bad colors when given freedom; saving them from that is the whole point.
- Persist by artifact identifier —
tweaks-<slug>, not a global
key. Two artifacts open in two tabs must not share state.
- Respect `prefers-reduced-motion` — default to Off for motion
if the user has that set, override only on explicit click.
- Single-file — no external CSS / JS / fonts beyond the artifact's
existing imports. Inline the panel + bridge.
- Panel hidden by default on viewports < 720px — slide-in drawer
via a "T" button at top-right.
- Don't ship more than 5 knobs. Three is the sweet spot.
<!doctype html>
<html lang="en" data-mode="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>[ARTIFACT TITLE] · Tweaks</title>
<style>
/* =========================================================
TWEAKS · WRAP TEMPLATE
=========================================================
This file is a skeleton. Workflow:
1. Replace [ARTIFACT TITLE] in <title>.
2. Update STORAGE_KEY in the script (tweaks-<artifact-slug>).
3. Decide which knobs apply (1-5 from KNOBS_LIBRARY).
4. Paste artifact CSS into the [ARTIFACT_STYLE] region.
5. Paste artifact body into the [ARTIFACT_BODY] region.
6. Lift hard-coded #hex / Npx / Nrem values to custom
properties so the knobs actually move.
========================================================= */
:root {
/* ---------- Knob defaults (overridden by JS bridge) ---------- */
--accent: #c96442;
--scale: 1;
--density: 1;
--motion-mult: 1;
/* ---------- Light theme tokens ---------- */
--bg: #f6f4ef;
--paper: #ffffff;
--ink: #1a1a1c;
--muted: #6b6964;
--rule: #e2dfd7;
}
[data-mode="dark"] {
--bg: #0e0d0c;
--paper: #181715;
--ink: #f4f1ea;
--muted: #8a857a;
--rule: #2a2723;
}
@media (prefers-reduced-motion: reduce) {
:root { --motion-mult: 0; }
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; min-height: 100%; }
body {
background: var(--bg);
color: var(--ink);
font-family: 'Inter', -apple-system, system-ui, sans-serif;
font-size: calc(16px * var(--scale));
line-height: 1.55;
transition: background calc(220ms * var(--motion-mult)) ease,
color calc(220ms * var(--motion-mult)) ease;
}
/* =========================================================
[ARTIFACT_STYLE] — paste artifact-specific CSS here
========================================================= */
/* =========================================================
PANEL · fixed sidebar with knobs
========================================================= */
.tw-panel {
position: fixed;
top: 16px;
right: 16px;
z-index: 100;
width: 280px;
max-width: calc(100vw - 32px);
background: var(--paper);
border: 1px solid var(--rule);
border-radius: 8px;
box-shadow: 0 8px 32px rgba(0,0,0,0.08);
font-family: 'Inter', system-ui, sans-serif;
transition: transform calc(220ms * var(--motion-mult)) cubic-bezier(.2,.8,.2,1),
opacity calc(220ms * var(--motion-mult)) ease;
}
[data-mode="dark"] .tw-panel { box-shadow: 0 8px 32px rgba(0,0,0,0.4); }
.tw-panel.tw-hidden {
transform: translateX(calc(100% + 32px));
opacity: 0;
pointer-events: none;
}
.tw-head {
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 18px;
border-bottom: 1px solid var(--rule);
}
.tw-head .ttl {
font-family: 'IBM Plex Mono', ui-monospace, monospace;
font-size: 10px;
letter-spacing: 0.24em;
text-transform: uppercase;
color: var(--muted);
}
.tw-head .toggle {
background: transparent;
border: 1px solid var(--rule);
color: var(--muted);
width: 24px;
height: 24px;
border-radius: 4px;
cursor: pointer;
font-family: 'IBM Plex Mono', monospace;
font-size: 11px;
padding: 0;
}
.tw-head .toggle:hover { color: var(--ink); }
.tw-body { padding: 14px 18px 18px; }
.tw-row { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.tw-row:last-child { margin-bottom: 0; }
.tw-row .lbl {
font-family: 'IBM Plex Mono', monospace;
font-size: 10px;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--muted);
}
/* Segmented control */
.tw-seg {
display: flex;
border: 1px solid var(--rule);
border-radius: 5px;
overflow: hidden;
background: var(--bg);
}
.tw-seg button {
flex: 1;
padding: 7px 8px;
background: transparent;
border: 0;
border-left: 1px solid var(--rule);
cursor: pointer;
font-family: 'Inter', system-ui, sans-serif;
font-size: 12px;
font-weight: 500;
color: var(--muted);
transition: color calc(180ms * var(--motion-mult)) ease,
background calc(180ms * var(--motion-mult)) ease;
}
.tw-seg button:first-child { border-left: 0; }
.tw-seg button:hover { color: var(--ink); }
.tw-seg button[aria-pressed="true"] {
background: var(--paper);
color: var(--ink);
box-shadow: inset 0 -2px 0 var(--accent);
}
/* Swatch grid */
.tw-swatches { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
.tw-swatch {
width: 100%;
aspect-ratio: 1;
border: 2px solid transparent;
border-radius: 5px;
cursor: pointer;
padding: 0;
transition: transform calc(160ms * var(--motion-mult)) ease,
border-color calc(160ms * var(--motion-mult)) ease;
}
.tw-swatch:hover { transform: scale(1.06); }
.tw-swatch[aria-pressed="true"] { border-color: var(--ink); }
/* Mini toolbar in panel footer */
.tw-foot {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 18px;
border-top: 1px solid var(--rule);
font-family: 'IBM Plex Mono', monospace;
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
}
.tw-foot button {
background: transparent;
border: 0;
color: var(--muted);
cursor: pointer;
padding: 0;
font-family: inherit;
font-size: inherit;
letter-spacing: inherit;
text-transform: inherit;
}
.tw-foot button:hover { color: var(--ink); }
kbd {
font-family: 'IBM Plex Mono', monospace;
font-size: 9px;
padding: 2px 5px;
border: 1px solid var(--rule);
border-radius: 3px;
color: var(--ink);
}
/* When panel is hidden, expose a "T" button at top-right */
.tw-restore {
position: fixed;
top: 16px;
right: 16px;
z-index: 100;
width: 36px;
height: 36px;
border-radius: 50%;
border: 1px solid var(--rule);
background: var(--paper);
color: var(--ink);
font-family: 'IBM Plex Mono', monospace;
font-size: 13px;
font-weight: 500;
cursor: pointer;
display: none;
align-items: center;
justify-content: center;
transition: transform calc(180ms * var(--motion-mult)) ease;
}
.tw-restore:hover { transform: scale(1.06); }
.tw-restore.tw-show { display: flex; }
@media (max-width: 720px) {
.tw-panel { left: 16px; right: 16px; width: auto; }
}
</style>
</head>
<body>
<!-- =========================================================
[ARTIFACT_BODY] — paste artifact-specific markup here
========================================================= -->
<!-- =========================================================
PANEL — knob controls (drop the rows you don't ship)
========================================================= -->
<aside class="tw-panel" id="tw-panel" aria-label="Tweak panel">
<header class="tw-head">
<span class="ttl">Tweaks</span>
<button class="toggle" id="tw-close" aria-label="Hide panel" title="Hide (T)">×</button>
</header>
<div class="tw-body">
<!-- Accent -->
<div class="tw-row">
<span class="lbl">Accent</span>
<div class="tw-swatches" id="tw-accent" role="radiogroup" aria-label="Accent color"></div>
</div>
<!-- Mode -->
<div class="tw-row">
<span class="lbl">Mode</span>
<div class="tw-seg" id="tw-mode" role="radiogroup" aria-label="Color mode">
<button data-val="light" aria-pressed="true">Light</button>
<button data-val="dark" aria-pressed="false">Dark</button>
</div>
</div>
<!-- Scale -->
<div class="tw-row">
<span class="lbl">Type scale</span>
<div class="tw-seg" id="tw-scale" role="radiogroup" aria-label="Type scale">
<button data-val="0.85" aria-pressed="false">Compact</button>
<button data-val="1" aria-pressed="true">Normal</button>
<button data-val="1.15" aria-pressed="false">Generous</button>
</div>
</div>
<!-- Density -->
<div class="tw-row">
<span class="lbl">Density</span>
<div class="tw-seg" id="tw-density" role="radiogroup" aria-label="Density">
<button data-val="0.75" aria-pressed="false">Tight</button>
<button data-val="1" aria-pressed="true">Normal</button>
<button data-val="1.4" aria-pressed="false">Roomy</button>
</div>
</div>
<!-- Motion -->
<div class="tw-row">
<span class="lbl">Motion</span>
<div class="tw-seg" id="tw-motion" role="radiogroup" aria-label="Motion">
<button data-val="0" aria-pressed="false">Off</button>
<button data-val="1" aria-pressed="true">Subtle</button>
<button data-val="1.6" aria-pressed="false">Lively</button>
</div>
</div>
</div>
<footer class="tw-foot">
<span><kbd>T</kbd> hide · <kbd>R</kbd> reset</span>
<button id="tw-reset" type="button">Reset</button>
</footer>
</aside>
<button class="tw-restore" id="tw-restore" aria-label="Show panel" title="Show panel (T)">T</button>
<script>
// =========================================================
// BRIDGE — binds knobs ↔ CSS custom props ↔ localStorage
// =========================================================
// CHANGE THIS to a unique slug per artifact you wrap.
const STORAGE_KEY = 'tweaks-default';
const ACCENT_PRESETS = [
{ id: 'rust', val: '#c96442' },
{ id: 'cobalt', val: '#2c4d8e' },
{ id: 'sage', val: '#4a7a3f' },
{ id: 'plum', val: '#7a3f6a' },
{ id: 'graphite', val: '#3a3a3a' },
];
const DEFAULTS = {
accent: ACCENT_PRESETS[0].val,
mode: 'light',
scale: 1,
density: 1,
motion: matchMedia('(prefers-reduced-motion: reduce)').matches ? 0 : 1,
};
function load() {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return { ...DEFAULTS };
return { ...DEFAULTS, ...JSON.parse(raw) };
} catch { return { ...DEFAULTS }; }
}
function save(state) {
try { localStorage.setItem(STORAGE_KEY, JSON.stringify(state)); }
catch {}
}
function applyState(s) {
const root = document.documentElement;
root.style.setProperty('--accent', s.accent);
root.style.setProperty('--scale', s.scale);
root.style.setProperty('--density', s.density);
root.style.setProperty('--motion-mult', s.motion);
root.setAttribute('data-mode', s.mode);
// Reflect to UI
paintAccent(s.accent);
paintSeg('tw-mode', s.mode);
paintSeg('tw-scale', String(s.scale));
paintSeg('tw-density', String(s.density));
paintSeg('tw-motion', String(s.motion));
}
function paintAccent(val) {
const host = document.getElementById('tw-accent');
if (!host) return;
host.querySelectorAll('button').forEach((b) =>
b.setAttribute('aria-pressed', b.dataset.val === val ? 'true' : 'false'),
);
}
function paintSeg(id, val) {
const host = document.getElementById(id);
if (!host) return;
host.querySelectorAll('button').forEach((b) =>
b.setAttribute('aria-pressed', b.dataset.val === val ? 'true' : 'false'),
);
}
function buildAccent(state) {
const host = document.getElementById('tw-accent');
if (!host) return;
host.innerHTML = '';
for (const p of ACCENT_PRESETS) {
const b = document.createElement('button');
b.type = 'button';
b.className = 'tw-swatch';
b.dataset.val = p.val;
b.setAttribute('aria-label', p.id);
b.style.background = p.val;
b.addEventListener('click', () => {
state.accent = p.val;
save(state); applyState(state);
});
host.appendChild(b);
}
}
function bindSeg(id, key, parser) {
const host = document.getElementById(id);
if (!host) return;
host.addEventListener('click', (e) => {
const btn = e.target.closest('button[data-val]');
if (!btn) return;
state[key] = parser ? parser(btn.dataset.val) : btn.dataset.val;
save(state); applyState(state);
});
}
const state = load();
buildAccent(state);
bindSeg('tw-mode', 'mode');
bindSeg('tw-scale', 'scale', parseFloat);
bindSeg('tw-density', 'density', parseFloat);
bindSeg('tw-motion', 'motion', parseFloat);
applyState(state);
// ---- Panel show/hide ----
const panel = document.getElementById('tw-panel');
const restore = document.getElementById('tw-restore');
function setPanelVisible(v) {
panel.classList.toggle('tw-hidden', !v);
restore.classList.toggle('tw-show', !v);
}
document.getElementById('tw-close').addEventListener('click', () => setPanelVisible(false));
restore.addEventListener('click', () => setPanelVisible(true));
// ---- Reset ----
document.getElementById('tw-reset').addEventListener('click', () => {
Object.assign(state, DEFAULTS);
save(state); applyState(state);
});
// ---- Keyboard shortcuts ----
addEventListener('keydown', (e) => {
if (e.metaKey || e.ctrlKey || e.altKey) return;
if (e.target.matches('input, textarea, select, [contenteditable]')) return;
if (e.key === 't' || e.key === 'T') {
e.preventDefault();
setPanelVisible(panel.classList.contains('tw-hidden'));
} else if (e.key === 'r' || e.key === 'R') {
e.preventDefault();
Object.assign(state, DEFAULTS);
save(state); applyState(state);
}
});
</script>
</body>
</html>
<!doctype html>
<html lang="en" data-mode="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Filebase · Tweaks demo</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Source+Serif+4:opsz,wght@8..60,400;8..60,600;8..60,700&family=IBM+Plex+Mono:wght@400;500;600&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
:root {
--accent: #c96442;
--scale: 1;
--density: 1;
--motion-mult: 1;
--bg: #f6f4ef;
--paper: #ffffff;
--ink: #1a1a1c;
--muted: #6b6964;
--rule: #e2dfd7;
--serif: 'Source Serif 4', Georgia, serif;
--sans: 'Inter', -apple-system, system-ui, sans-serif;
--mono: 'IBM Plex Mono', ui-monospace, monospace;
}
[data-mode="dark"] {
--bg: #0e0d0c;
--paper: #181715;
--ink: #f4f1ea;
--muted: #8a857a;
--rule: #2a2723;
}
@media (prefers-reduced-motion: reduce) {
:root { --motion-mult: 0; }
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; min-height: 100%; }
body {
background: var(--bg);
color: var(--ink);
font-family: var(--sans);
font-size: calc(16px * var(--scale));
line-height: 1.55;
transition: background calc(220ms * var(--motion-mult)) ease,
color calc(220ms * var(--motion-mult)) ease;
}
/* ============ Layout ============ */
.wrap {
max-width: 1200px;
margin: 0 auto;
padding: calc(28px * var(--density)) calc(40px * var(--density));
}
/* ============ Header / nav ============ */
.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: calc(20px * var(--density)) 0;
gap: calc(32px * var(--density));
border-bottom: 1px solid var(--rule);
}
.brand {
display: flex;
align-items: center;
gap: 10px;
font-family: var(--serif);
font-weight: 700;
font-size: calc(20px * var(--scale));
letter-spacing: -0.01em;
}
.brand-mark {
width: 28px; height: 28px;
border-radius: 6px;
background: var(--accent);
transition: background calc(220ms * var(--motion-mult)) ease;
}
.nav-links {
display: flex;
gap: calc(28px * var(--density));
font-size: calc(14px * var(--scale));
color: var(--muted);
}
.nav-links a {
color: inherit;
text-decoration: none;
transition: color calc(180ms * var(--motion-mult)) ease;
}
.nav-links a:hover { color: var(--ink); }
.cta {
display: inline-block;
padding: calc(10px * var(--density)) calc(18px * var(--density));
background: var(--accent);
color: #fff;
border-radius: 6px;
font-size: calc(13px * var(--scale));
font-weight: 600;
letter-spacing: 0.02em;
text-decoration: none;
transition: background calc(220ms * var(--motion-mult)) ease,
transform calc(220ms * var(--motion-mult)) ease;
}
.cta:hover { transform: translateY(-1px); }
/* ============ Hero ============ */
.hero {
padding: calc(96px * var(--density)) 0 calc(80px * var(--density));
display: grid;
grid-template-columns: 1.4fr 1fr;
gap: calc(64px * var(--density));
align-items: center;
}
@media (max-width: 880px) {
.hero { grid-template-columns: 1fr; }
}
.eyebrow {
font-family: var(--mono);
font-size: calc(11px * var(--scale));
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: calc(22px * var(--density));
transition: color calc(220ms * var(--motion-mult)) ease;
}
.h1 {
font-family: var(--serif);
font-weight: 700;
font-size: calc(58px * var(--scale));
line-height: 1.04;
letter-spacing: -0.02em;
margin: 0 0 calc(22px * var(--density));
}
.h1 em {
font-style: italic;
color: var(--accent);
font-weight: 600;
transition: color calc(220ms * var(--motion-mult)) ease;
}
.lede {
font-size: calc(19px * var(--scale));
color: var(--muted);
max-width: 38ch;
margin: 0 0 calc(36px * var(--density));
line-height: 1.5;
}
.row { display: flex; gap: calc(14px * var(--density)); align-items: center; flex-wrap: wrap; }
.secondary {
font-size: calc(13px * var(--scale));
color: var(--muted);
font-family: var(--mono);
letter-spacing: 0.18em;
text-transform: uppercase;
}
/* Hero card preview */
.hero-card {
background: var(--paper);
border: 1px solid var(--rule);
border-radius: 10px;
padding: calc(20px * var(--density));
box-shadow: 0 12px 40px rgba(0,0,0,0.06);
font-family: var(--mono);
font-size: calc(12px * var(--scale));
transition: background calc(220ms * var(--motion-mult)) ease,
border-color calc(220ms * var(--motion-mult)) ease;
}
[data-mode="dark"] .hero-card { box-shadow: 0 12px 40px rgba(0,0,0,0.4); }
.hero-card .label {
color: var(--muted);
letter-spacing: 0.2em;
text-transform: uppercase;
margin-bottom: calc(12px * var(--density));
font-size: calc(10px * var(--scale));
}
.hero-card pre {
margin: 0;
padding: calc(14px * var(--density));
background: var(--bg);
border-radius: 6px;
color: var(--ink);
font-family: var(--mono);
font-size: calc(12px * var(--scale));
line-height: 1.55;
overflow-x: auto;
}
.hero-card .k { color: var(--accent); }
.hero-card .c { color: var(--muted); }
.hero-card .ok { color: #4a7a3f; }
[data-mode="dark"] .hero-card .ok { color: #8db876; }
/* ============ Stats strip ============ */
.stats {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: calc(32px * var(--density));
padding: calc(48px * var(--density)) 0;
border-top: 1px solid var(--rule);
border-bottom: 1px solid var(--rule);
}
@media (max-width: 720px) {
.stats { grid-template-columns: repeat(2, 1fr); }
}
.stat {
display: flex;
flex-direction: column;
gap: calc(6px * var(--density));
}
.stat .num {
font-family: var(--serif);
font-weight: 700;
font-size: calc(40px * var(--scale));
line-height: 1;
letter-spacing: -0.02em;
color: var(--accent);
transition: color calc(220ms * var(--motion-mult)) ease;
}
.stat .lbl {
font-size: calc(13px * var(--scale));
color: var(--muted);
max-width: 22ch;
line-height: 1.45;
}
/* ============ Features grid ============ */
.features {
padding: calc(80px * var(--density)) 0 calc(40px * var(--density));
}
.section-title {
font-family: var(--serif);
font-weight: 600;
font-size: calc(34px * var(--scale));
letter-spacing: -0.015em;
margin: 0 0 calc(48px * var(--density));
max-width: 22ch;
}
.feat-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: calc(28px * var(--density));
}
@media (max-width: 880px) {
.feat-grid { grid-template-columns: 1fr; }
}
.feat {
padding: calc(28px * var(--density));
background: var(--paper);
border: 1px solid var(--rule);
border-radius: 10px;
transition: background calc(220ms * var(--motion-mult)) ease,
border-color calc(220ms * var(--motion-mult)) ease,
transform calc(220ms * var(--motion-mult)) ease;
}
.feat:hover { transform: translateY(-2px); }
.feat .ico {
width: 36px; height: 36px;
border-radius: 8px;
background: color-mix(in oklch, var(--accent) 18%, transparent);
color: var(--accent);
display: grid;
place-items: center;
font-family: var(--serif);
font-weight: 700;
font-size: calc(15px * var(--scale));
margin-bottom: calc(20px * var(--density));
}
.feat h3 {
font-family: var(--serif);
font-weight: 600;
font-size: calc(20px * var(--scale));
margin: 0 0 calc(8px * var(--density));
letter-spacing: -0.01em;
}
.feat p {
color: var(--muted);
font-size: calc(15px * var(--scale));
line-height: 1.55;
margin: 0;
}
/* ============ CTA banner ============ */
.banner {
margin: calc(60px * var(--density)) 0 calc(40px * var(--density));
padding: calc(56px * var(--density)) calc(48px * var(--density));
background: var(--ink);
color: var(--bg);
border-radius: 14px;
display: grid;
grid-template-columns: 1fr auto;
gap: calc(40px * var(--density));
align-items: center;
transition: background calc(220ms * var(--motion-mult)) ease,
color calc(220ms * var(--motion-mult)) ease;
}
@media (max-width: 720px) {
.banner { grid-template-columns: 1fr; }
}
.banner h2 {
font-family: var(--serif);
font-weight: 600;
font-size: calc(32px * var(--scale));
letter-spacing: -0.015em;
line-height: 1.15;
margin: 0 0 calc(8px * var(--density));
max-width: 22ch;
}
.banner p {
color: rgba(244,241,234,0.68);
font-size: calc(15px * var(--scale));
margin: 0;
}
[data-mode="dark"] .banner p { color: rgba(26,26,28,0.68); }
.ft {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 16px;
padding: calc(28px * var(--density)) 0;
border-top: 1px solid var(--rule);
font-family: var(--mono);
font-size: calc(11px * var(--scale));
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
}
/* =========================================================
PANEL · same primitives as assets/wrap.html
========================================================= */
.tw-panel {
position: fixed;
top: 16px;
right: 16px;
z-index: 100;
width: 280px;
max-width: calc(100vw - 32px);
background: var(--paper);
border: 1px solid var(--rule);
border-radius: 8px;
box-shadow: 0 8px 32px rgba(0,0,0,0.08);
font-family: var(--sans);
transition: transform calc(220ms * var(--motion-mult)) cubic-bezier(.2,.8,.2,1),
opacity calc(220ms * var(--motion-mult)) ease,
background calc(220ms * var(--motion-mult)) ease;
}
[data-mode="dark"] .tw-panel { box-shadow: 0 8px 32px rgba(0,0,0,0.4); }
.tw-panel.tw-hidden {
transform: translateX(calc(100% + 32px));
opacity: 0;
pointer-events: none;
}
.tw-head {
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 18px;
border-bottom: 1px solid var(--rule);
}
.tw-head .ttl {
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.24em;
text-transform: uppercase;
color: var(--muted);
}
.tw-head .toggle {
background: transparent;
border: 1px solid var(--rule);
color: var(--muted);
width: 24px; height: 24px;
border-radius: 4px;
cursor: pointer;
font-family: var(--mono);
font-size: 11px;
padding: 0;
}
.tw-head .toggle:hover { color: var(--ink); }
.tw-body { padding: 14px 18px 18px; }
.tw-row { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.tw-row:last-child { margin-bottom: 0; }
.tw-row .lbl {
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--muted);
}
.tw-seg {
display: flex;
border: 1px solid var(--rule);
border-radius: 5px;
overflow: hidden;
background: var(--bg);
}
.tw-seg button {
flex: 1;
padding: 7px 8px;
background: transparent;
border: 0;
border-left: 1px solid var(--rule);
cursor: pointer;
font-family: var(--sans);
font-size: 12px;
font-weight: 500;
color: var(--muted);
transition: color calc(180ms * var(--motion-mult)) ease,
background calc(180ms * var(--motion-mult)) ease;
}
.tw-seg button:first-child { border-left: 0; }
.tw-seg button:hover { color: var(--ink); }
.tw-seg button[aria-pressed='true'] {
background: var(--paper);
color: var(--ink);
box-shadow: inset 0 -2px 0 var(--accent);
}
.tw-swatches { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
.tw-swatch {
width: 100%; aspect-ratio: 1;
border: 2px solid transparent;
border-radius: 5px;
cursor: pointer;
padding: 0;
transition: transform calc(160ms * var(--motion-mult)) ease,
border-color calc(160ms * var(--motion-mult)) ease;
}
.tw-swatch:hover { transform: scale(1.06); }
.tw-swatch[aria-pressed='true'] { border-color: var(--ink); }
.tw-foot {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 18px;
border-top: 1px solid var(--rule);
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
}
.tw-foot button {
background: transparent;
border: 0;
color: var(--muted);
cursor: pointer;
padding: 0;
font: inherit;
letter-spacing: inherit;
text-transform: inherit;
}
.tw-foot button:hover { color: var(--ink); }
kbd {
font-family: var(--mono);
font-size: 9px;
padding: 2px 5px;
border: 1px solid var(--rule);
border-radius: 3px;
color: var(--ink);
}
.tw-restore {
position: fixed;
top: 16px; right: 16px;
z-index: 100;
width: 36px; height: 36px;
border-radius: 50%;
border: 1px solid var(--rule);
background: var(--paper);
color: var(--ink);
font-family: var(--mono);
font-size: 13px;
font-weight: 500;
cursor: pointer;
display: none;
align-items: center;
justify-content: center;
transition: transform calc(180ms * var(--motion-mult)) ease;
}
.tw-restore:hover { transform: scale(1.06); }
.tw-restore.tw-show { display: flex; }
@media (max-width: 720px) {
.tw-panel { left: 16px; right: 16px; width: auto; }
}
</style>
</head>
<body>
<div class="wrap">
<!-- Nav -->
<nav class="nav">
<div class="brand">
<span class="brand-mark" aria-hidden="true"></span>
<span>Filebase</span>
</div>
<div class="nav-links">
<a href="#">Product</a>
<a href="#">Pricing</a>
<a href="#">Docs</a>
<a href="#">Changelog</a>
<a href="#">Customers</a>
</div>
<a class="cta" href="#">Start free</a>
</nav>
<!-- Hero -->
<header class="hero">
<div>
<div class="eyebrow">Series B · 2026</div>
<h1 class="h1">The bandwidth bill is the <em>bug</em>.</h1>
<p class="lede">A sync engine that ships only what changed. 38× less data over the wire on real customer workloads.</p>
<div class="row">
<a class="cta" href="#">Start free</a>
<span class="secondary">no card required</span>
</div>
</div>
<div class="hero-card">
<div class="label">filebase sync — typical run</div>
<pre><span class="c">// hourly cron · feature/render-pass branch</span>
$ filebase sync --watch
<span class="k">→</span> diff: <span class="ok">12.4 MB</span> <span class="c">(of 4.7 GB)</span>
<span class="k">→</span> upload: <span class="ok">8.2 MB</span> <span class="c">(deduplicated)</span>
<span class="k">→</span> latency: <span class="ok">340 ms</span> <span class="c">p99</span>
<span class="ok">✓ done in 2.1s</span></pre>
</div>
</header>
<!-- Stats -->
<section class="stats">
<div class="stat">
<div class="num">38×</div>
<div class="lbl">less data moved over the wire vs naive sync</div>
</div>
<div class="stat">
<div class="num">3,184</div>
<div class="lbl">paying teams across post-production, design, ML</div>
</div>
<div class="stat">
<div class="num">99.99%</div>
<div class="lbl">uptime over the last 12 rolling months</div>
</div>
<div class="stat">
<div class="num">$2.1M</div>
<div class="lbl">aggregate egress savings reported by Q1 cohort</div>
</div>
</section>
<!-- Features -->
<section class="features">
<h2 class="section-title">Three reasons teams switch in the first month.</h2>
<div class="feat-grid">
<article class="feat">
<div class="ico" aria-hidden="true">∂</div>
<h3>Block-level diffs</h3>
<p>Edit one frame in a 4 GB Final Cut project; sync 12 MB. The diff doesn't care how big your file is — it cares what changed.</p>
</article>
<article class="feat">
<div class="ico" aria-hidden="true">≈</div>
<h3>Cross-region dedup</h3>
<p>Your team in Berlin uploads a checkpoint your team in Tokyo already pushed. We notice. Nothing transfers.</p>
</article>
<article class="feat">
<div class="ico" aria-hidden="true">∇</div>
<h3>Drop-in for S3 / GCS</h3>
<p>Wire one env var, change zero application code. Existing buckets, existing IAM, new bandwidth bill.</p>
</article>
</div>
</section>
<!-- CTA banner -->
<section class="banner">
<div>
<h2>Pay for storage. Stop paying for movement.</h2>
<p>Start free, no card required. Production teams in 14 days or fewer.</p>
</div>
<a class="cta" href="#" style="background: var(--accent); color: #fff;">Book a demo</a>
</section>
<footer class="ft">
<span>© 2026 Filebase, Inc.</span>
<span>Privacy · Terms · Status</span>
<span>built with the OD tweaks skill</span>
</footer>
</div>
<!-- ============ Tweak panel ============ -->
<aside class="tw-panel" id="tw-panel" aria-label="Tweak panel">
<header class="tw-head">
<span class="ttl">Tweaks · Filebase</span>
<button class="toggle" id="tw-close" aria-label="Hide panel" title="Hide (T)">×</button>
</header>
<div class="tw-body">
<div class="tw-row">
<span class="lbl">Accent</span>
<div class="tw-swatches" id="tw-accent" role="radiogroup" aria-label="Accent color"></div>
</div>
<div class="tw-row">
<span class="lbl">Mode</span>
<div class="tw-seg" id="tw-mode" role="radiogroup" aria-label="Color mode">
<button data-val="light" aria-pressed="true">Light</button>
<button data-val="dark" aria-pressed="false">Dark</button>
</div>
</div>
<div class="tw-row">
<span class="lbl">Type scale</span>
<div class="tw-seg" id="tw-scale" role="radiogroup" aria-label="Type scale">
<button data-val="0.85" aria-pressed="false">Compact</button>
<button data-val="1" aria-pressed="true">Normal</button>
<button data-val="1.15" aria-pressed="false">Generous</button>
</div>
</div>
<div class="tw-row">
<span class="lbl">Density</span>
<div class="tw-seg" id="tw-density" role="radiogroup" aria-label="Density">
<button data-val="0.75" aria-pressed="false">Tight</button>
<button data-val="1" aria-pressed="true">Normal</button>
<button data-val="1.4" aria-pressed="false">Roomy</button>
</div>
</div>
<div class="tw-row">
<span class="lbl">Motion</span>
<div class="tw-seg" id="tw-motion" role="radiogroup" aria-label="Motion">
<button data-val="0" aria-pressed="false">Off</button>
<button data-val="1" aria-pressed="true">Subtle</button>
<button data-val="1.6" aria-pressed="false">Lively</button>
</div>
</div>
</div>
<footer class="tw-foot">
<span><kbd>T</kbd> hide · <kbd>R</kbd> reset</span>
<button id="tw-reset" type="button">Reset</button>
</footer>
</aside>
<button class="tw-restore" id="tw-restore" aria-label="Show panel" title="Show panel (T)">T</button>
<script>
const STORAGE_KEY = 'tweaks-filebase-example';
const ACCENT_PRESETS = [
{ id: 'rust', val: '#c96442' },
{ id: 'cobalt', val: '#2c4d8e' },
{ id: 'sage', val: '#4a7a3f' },
{ id: 'plum', val: '#7a3f6a' },
{ id: 'graphite', val: '#3a3a3a' },
];
const DEFAULTS = {
accent: ACCENT_PRESETS[0].val,
mode: 'light',
scale: 1,
density: 1,
motion: matchMedia('(prefers-reduced-motion: reduce)').matches ? 0 : 1,
};
function load() {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return { ...DEFAULTS };
return { ...DEFAULTS, ...JSON.parse(raw) };
} catch { return { ...DEFAULTS }; }
}
function save(s) {
try { localStorage.setItem(STORAGE_KEY, JSON.stringify(s)); } catch {}
}
function applyState(s) {
const r = document.documentElement;
r.style.setProperty('--accent', s.accent);
r.style.setProperty('--scale', s.scale);
r.style.setProperty('--density', s.density);
r.style.setProperty('--motion-mult', s.motion);
r.setAttribute('data-mode', s.mode);
paintAccent(s.accent);
paintSeg('tw-mode', s.mode);
paintSeg('tw-scale', String(s.scale));
paintSeg('tw-density', String(s.density));
paintSeg('tw-motion', String(s.motion));
}
function paintAccent(val) {
document.querySelectorAll('#tw-accent button').forEach((b) =>
b.setAttribute('aria-pressed', b.dataset.val === val ? 'true' : 'false'),
);
}
function paintSeg(id, val) {
document.querySelectorAll('#' + id + ' button').forEach((b) =>
b.setAttribute('aria-pressed', b.dataset.val === val ? 'true' : 'false'),
);
}
function buildAccent(state) {
const host = document.getElementById('tw-accent');
host.innerHTML = '';
for (const p of ACCENT_PRESETS) {
const b = document.createElement('button');
b.type = 'button';
b.className = 'tw-swatch';
b.dataset.val = p.val;
b.setAttribute('aria-label', p.id);
b.style.background = p.val;
b.addEventListener('click', () => {
state.accent = p.val;
save(state); applyState(state);
});
host.appendChild(b);
}
}
function bindSeg(id, key, parser) {
document.getElementById(id).addEventListener('click', (e) => {
const btn = e.target.closest('button[data-val]');
if (!btn) return;
state[key] = parser ? parser(btn.dataset.val) : btn.dataset.val;
save(state); applyState(state);
});
}
const state = load();
buildAccent(state);
bindSeg('tw-mode', 'mode');
bindSeg('tw-scale', 'scale', parseFloat);
bindSeg('tw-density', 'density', parseFloat);
bindSeg('tw-motion', 'motion', parseFloat);
applyState(state);
const panel = document.getElementById('tw-panel');
const restore = document.getElementById('tw-restore');
function setPanelVisible(v) {
panel.classList.toggle('tw-hidden', !v);
restore.classList.toggle('tw-show', !v);
}
document.getElementById('tw-close').addEventListener('click', () => setPanelVisible(false));
restore.addEventListener('click', () => setPanelVisible(true));
document.getElementById('tw-reset').addEventListener('click', () => {
Object.assign(state, DEFAULTS);
save(state); applyState(state);
});
addEventListener('keydown', (e) => {
if (e.metaKey || e.ctrlKey || e.altKey) return;
if (e.target.matches('input, textarea, select, [contenteditable]')) return;
if (e.key === 't' || e.key === 'T') {
e.preventDefault();
setPanelVisible(panel.classList.contains('tw-hidden'));
} else if (e.key === 'r' || e.key === 'R') {
e.preventDefault();
Object.assign(state, DEFAULTS);
save(state); applyState(state);
}
});
</script>
</body>
</html>
Related skills
FAQ
What does the tweaks skill change?
tweaks applies targeted spacing, color, typography, and component polish on existing UI screens. The skill refines visual details in place rather than replacing information architecture or running a full redesign project.
When should developers use tweaks versus a redesign?
tweaks fits feature-complete interfaces that need margin, contrast, type scale, or component edge fixes before release. Full redesigns with new flows or brand exploration sit outside tweaks scope.