tt-polish
Polish is a two-phase pass, not a builder. It assumes TUX token compliance is already mostly in place — if it isn't, run /tt-impeccable extract first.
Phase 1 — Visual Elevation: adds warmth, depth, and richness that survive token compliance but are not prescribed by the core spec. Phase 2 — Compliance Sweep: catches token drift, missing states, anti-patterns, and copy issues.
Context Check
- Read
.tt-impeccable.mdin project root if it exists — fidelity tier and design context are there. - If absent, infer tier from codebase: mobile-first 390px = Strict TUX-native; dark
#000000desktop = TT Style. - Only ask if the tier is genuinely ambiguous.
Note the fidelity tier: Phase 1 rules apply primarily to Strict TUX-native light-theme surfaces. Phase 2 applies to both tiers.
Phase 1: Visual Elevation
Load reference/polish-rules.md and apply all 13 rules systematically.
Rule summary (refer to the rules file for full CSS and constraints):
| # | If… (condition) | → Then (action) |
|---|---|---|
| 1 | Page has a prominent heading (font-size > 17px) | Left-align it, add a subtitle line below, place a radial-gradient glow at top — height = heading's top offset + 20px so gradient is fully transparent by the time the heading begins; color from Ambient Glow presets (rules file); skip on utility/settings screens |
| 2 | Largest font-size on page < 20px | Set one heading to 24–32px (scale to content density); compress smallest body text to 12px |
| 3 | Page horizontal margin < 20px, or element gaps feel tight | Set page padding to 20px; inter-group vertical gaps to 24–32px |
| 4 | Card or icon list cell present | Replace every icon with a contextual emoji; set background to ~5% tint of dominant hue using oklch() (keeps color vivid) |
| 5 | Card or cell border-radius < 12px | Upgrade: L1 nested → 14px, L2 overlay/sheet → 26px |
| 6 | 2–5 emoji list cells present | Shorten label text, foreground the emoji, reflow as a 2-column card grid |
| 7 | Same-type cards in a grid | Enforce a consistent internal layout system across all cards: same emoji size, same title position, same description line count, same padding — no card should look structurally different from its siblings |
| 8 | Divider lines present | Replace with fading-edge gradient; attach to scroll wrapper (not chrome elements) |
| 9 | ≥3 distinct non-neutral colors on screen | Switch CTA button to black (#000000) with white label |
| 10 | Icon sizes other than 24px or 16px present | Snap large icons → 24px, small icons → 16px; enforce one size per component |
| 11 | Solid non-neutral fill (red, blue, etc.) > 30px wide/tall with icon inside | Remove the fill container; promote the associated title to 24px/700 dominant typography |
| 12 | Entrance animations absent | Add: cards fadeUp staggered 40ms, sheets fadeScale 220ms, chips fadeIn staggered 30ms; disable translate/scale under prefers-reduced-motion |
| 13 | Group/section label is visually stronger than item titles inside it | Demote label to 13px/600/text-2; item titles stay at 15–17px/700/text-1-display — the label is wayfinding, not a headline |
Phase 1 rules apply to Strict TUX-native light-theme surfaces. For TT Style surfaces, Rules 2, 3, 5, 10, 11 still apply; Rules 1, 7, 12 are adapted (see rules file for TT Style notes).
Phase 2: Compliance Sweep
2a — Token Drift Scan
Read source files and search for:
border:,border-top:,border-bottom:,border-left:,border-right:— for each hit: (a) could a background color change replace it? (b) Is it compensating for wrong surface contrast? Flag P1/P2 as appropriate.:hoverrules containingborder-coloror adding aborder— convert tobackground/opacitychanges (P2)backdrop-filter— confirm glassmorphism is explicitly confirmed in context; if not, remove (P1)letter-spacingnon-zero on text below 72px — remove (P2)rgba(254,44,85,*)at any alpha on non-CTA/non-interactive elements — BAN 7 violation (P1)- Accent color (brand red, teal) on elements without interactive semantics (no onClick/href/role) — replace with neutral (P1)
- Hard-coded hex or rgba values not going through
var(--tux-*)— flag all (P2) - Spacing values not in the TUX 4px grid (4/8/12/16/20/24/32) — flag off-grid values (P2)
border-radiusvalues not in the TUX tables — flag (P2)box-shadowvalues that don't match the 6 TUX levels — flag (P2)- Font other than TikTok Sans / system-ui — flag (P1)
overflow: hiddenon text containers withline-heightbelow1.0em— add descender padding fix (P2)
2b — Interaction States
Confirm every interactive element has all applicable states:
- Default — resting appearance
- Active / pressed — opacity drop or background shift on touch
- Focus-visible — keyboard/accessibility ring; never
outline: nonewithout replacement - Disabled — visually de-emphasized;
pointer-events: none - Loading — if async: spinner, skeleton, or progress; element must not look tappable while loading
- Error — if element can fail: validation state visible
- Success — if action has meaningful completion: confirmation or state change
Touch target minimum: 44×44px on every tappable element.
2c — Entrance Animations (from Phase 1 Rule 12)
- All elements have entrance animations — no element snaps into existence at full opacity
- Cards/items use staggered
fadeUp; floats usefadeScale; chips use staggeredfadeIn -
prefers-reduced-motion: translate/scale animations disabled; opacity-only or none
Phase 1 Checklist (before presenting)
Gradients & Glow
- Page has heading > 17px → gradient applied; fades fully transparent before 220px
- Maximum one glow source per page
Typography
- Whole-page: largest text ≥ 24px, smallest ≤ 12px
- Within each module: at least one 700-weight dominant and one 400-weight/12px recessive element
- Adjacent tiers differ by ≥ 2 steps on the TUX scale
Spacing
- Page horizontal padding is 20px
- Inter-group vertical gaps are 24–32px
- Card internal padding is 20–24px
Cards & Emoji
- All SVG/system icons in cards and list cells replaced with contextual emoji
- Card/cell backgrounds use
oklch()tint at ~5% — not flat rgba() - Card label/heading color carries the card's hue
- 2–5 emoji list cells reflowed as 2-column card grid
- White-on-white: card gets tinted background
Fills & Color Restraint
- No solid non-neutral fill > 30px containing an icon — removed and replaced with dominant title
- CTA: ≥3 distinct non-neutral colors on screen → CTA is black
Surface & Structure
- Radius: L1 nested ≥ 14px; L2 overlay = 26px
- Same-type card grid: all cards share identical internal structure (emoji size, title position, description lines, padding)
Fading Edges
- Dividers replaced with fading-edge gradient attached to scroll wrapper
- Fade color matches scroll surface background
- Fade height ≥ 32px
Icons
- Icon sizes snapped to 24px (large) or 16px (small); one size per component
Typography Hierarchy
- Group/section labels are ≤13px/600/text-2 — weaker than item titles inside them
Animations
- Cards:
fadeUpstaggered 40ms per item - Sheets/modals:
fadeScale220ms - Chips:
fadeInstaggered 30ms -
prefers-reduced-motion: translate/scale disabled
Final Verification
- Use it yourself — interact with every state and flow
- Run
/tt-audit— confirm health score improved - Re-run
/tt-critique— verify anti-pattern verdict is clean
Polish is complete when the interface is indistinguishable from a screen inside the TikTok app — not because it has the right tokens, but because it has the right feel.