Skip to content
alyn
runkids

Skillshare UI Website Style skill

Skillshare frontend design system for the React dashboard (ui/) and Docusaurus website (website/). Use this skill whenever you: build or modify a dashboard page or component in ui/src/, style or layout website pages or custom CSS in website/, create new React components for the dashboard, add pages to the dashboard, fix visual bugs in either frontend, or need to know which design tokens, ss-* classes, components, or

$npx skills add runkids/skillshare --skill skillshare-ui-website-style
View this skill on GitHubrunkids/skillshare/.skillshare/skills/skillshare-ui-website-style/SKILL.md
Pack stars
3,012
Pack installs
48
Alyn Score
55/99
Updated
7 h ago
License
MIT
– views – installs via Alyn

Install Skillshare UI Website Style

Pick your agent. Every command is ready to paste.

$npx skills add runkids/skillshare --skill skillshare-ui-website-style

The open skills CLI detects your agents (Claude Code, Cursor, Codex and 70+ more) and installs to the right folder. Add -g to install globally.

01

Install it

Run the command above, or upload the folder in Claude.

02

Ask naturally

Describe the task. Your agent loads skillshare-ui-website-style when the request matches its description.

03

Name it if needed

If it does not trigger, say “use the skillshare-ui-website-style skill”. In Codex, type $skillshare-ui-website-style.

The skill itself

SKILL.md

FolderGitHub

Enforce the skillshare design system across the two frontends. $ARGUMENTS is the file or area being worked on.

Before acting, run python3 scripts/ai-context.py frontend. That topic and the CSS/source files it identifies are the source of truth; this skill retains the component catalog and visual QA checklist.

Aspect UI Dashboard (ui/) Website (website/)
Stack React 19 + Vite + Tailwind CSS v4 Docusaurus 3 + custom CSS
Source of truth ui/src/components.css (tokens + ss-* classes), ui/src/index.css (Tailwind mapping) website/src/css/custom.css (docs), website/src/pages/*.module.css (homepage, features)
Looks Two styles, Clean and Playful, each in light and dark Docs: clean. Homepage: hand-drawn string board

This file names tokens and classes and says when to use them. It does not copy their values. Colours, radii, fonts and shadows change; read them from the CSS when you need one.


UI Dashboard (ui/)

Reference pages: ui/src/pages/TargetsPage.tsx (list page), ui/src/pages/HubPage.tsx (tabs), ui/src/pages/ResourcesPage.tsx (list + tiles + bulk toolbar).

Design rules and the reasoning behind them: references/STYLE_GUIDE.md.

Two styles, two modes

Style and mode are independent, so every screen has four looks.

Axis Values How it is set
Style Clean, Playful (default) html[data-theme="playful"]; attribute absent = Clean
Mode light, dark, system html.dark

Set by ui/src/context/ThemeContext.tsx, switched in ThemePopover.tsx. ?theme=clean|playful|dark|light in the URL forces one, which is handy for screenshots.

All four looks come from CSS variables alone. A page that uses only tokens and ss-* classes gets all four for free; a hardcoded colour, radius or shadow breaks three of them.

  • Clean: system font, 1px hairlines, soft shadows, ink-coloured primary button. Only layers that float over scrolling content are frosted glass (menus, .ss-hud, the stuck .ss-stickbar); the page, cards and sidebar stay solid.
  • Playful: Kalam headings, 2px ink borders, hard offset shadows, dashed separators, yellow primary, pastel accents, dot-grid background, sticky-note tiles.
  • Style-only markup: .ss-only-clean / .ss-only-playful (Dashboard shows a count strip in Clean and a pin board in Playful).

Design tokens

Defined per look at the top of ui/src/components.css. ui/src/index.css exposes them to Tailwind through @theme inline, so text-ink-2, bg-surface, border-line all follow the active look.

Group Tokens Use
Surfaces --bg --side --surface --sunken Page, sidebar, cards and inputs, recessed headers and footers
Text --ink --ink-2 --ink-3 Primary, secondary, tertiary and placeholder
Lines --line --line-2 --line-soft Frames, control borders, soft dividers
Borders --sep --frame --bw Whole border values: row separator, box frame, control border width
Action --pri --on-pri --accent --accent-bg --sel --sel-ink Primary button, links and focus, selected nav and menu items
Status --ok --warn --bad, each with -bg Text or dot colour, plus its tinted background
Kind --c-skill --c-agent --c-extra --c-mcp --c-plugin --c-target, each with -bg Resource-kind colour, used by .ss-cat
Pastels --pa --pb --pc --pd --pe Playful only. Never reference outside a [data-theme="playful"] rule
Type --f --fh --fm --h1 --h2 Body, heading (Kalam in Playful), mono, heading shorthands
Shape --r-ctl --r-btn --r-box --r-tag Controls, buttons (pill), boxes, tags
Shadow --sh-box --sh-btn --sh-float --sh-dialog Boxes, buttons, menus and toasts, dialogs
Motion --spring --spring-bounce linear() easings for springy transitions: --spring critically damped, --spring-bounce for a release that carried momentum. Defined on :root beside the components that use them
Glass --glass-menu --glass-bar --mat --mat-menu Clean only. Translucent fill and blur for menus and the sticky toolbar; prefers-reduced-transparency turns them solid

Tailwind names: bg side surface sunken ink ink-2 ink-3 line line-2 line-soft sel pri on-pri ok warn bad (with -bg) and link / link-bg for --accent.

Legacy names: pencil, pencil-light, paper, paper-warm, muted, muted-dark, success, warning, danger, blue, info, accent still resolve as aliases for markup not yet migrated. Do not use them in new code. When you touch a line that has one, replace it:

Legacy Use
text-pencil text-ink
text-pencil-light text-ink-2
text-muted-dark text-ink-3
bg-paper / bg-paper-warm bg-bg / bg-side
border-muted border-line
text-success / text-warning / text-danger text-ok / text-warn / text-bad
text-blue / text-info text-link

ui/src/design.ts (radius, shadows, palette) forwards to the same variables, for inline styles only.

The ss-* classes

All in @layer components in ui/src/components.css. List what exists today:

grep -o '\.ss-[a-z0-9-]*' ui/src/components.css | sort -u

State and variant are short modifier classes on the same element: .on (selected or checked), .sel (selected row or tile), .ok .warn .bad .inf (tone), .sm .lg (size).

Area Classes
Page .ss-wrap (1080px column, 28px gap), .ss-pgh + .ss-ph (header, via PageHeader), .ss-crumb, .ss-sec (section heading row; h2 inside, .more link on the right), .ss-h1 .ss-h2, .ss-hand (Kalam aside)
Shell .ss-side .ss-wm .ss-nvg .ss-nv .ss-sidefoot — Layout.tsx only
Buttons .ss-btn + .pri .ghost .dng + .sm .lg; .ss-ib (30px icon button); .ss-more (text link)
Forms .ss-fld (label + control + .hp help), .ss-inp (+ .area .err, .k key hint), .ss-chk (+ .rad), .ss-sw (switch; .on, .mix when only some are on), .ss-tgl (icon toggle), .ss-seg (+ .ic icon-only; give it ref={segSlide} from lib/segSlide so the Clean pill slides)
Navigation .ss-tabs, .ss-tabbar (tabs with controls on the right), .ss-pager, .ss-menu (+ .hv .dng, hr, .k)
Lists .ss-list (framed container), .ss-lh (column header), .ss-gh (group header), .ss-r (row; .link clickable, .sel, .fold; .nm name, .nm.m mono name), .ss-plain (rows without side padding), .ss-split (tree view box: .lp tree, .dv divider, .rp detail pane), .ss-tn (tree row; .sel, .in inside a selected folder, .off; indent with --d)
Boxes .ss-box (card, via Card), .ss-tiles + .ss-tile (grid; sticky notes in Playful), .ss-kv (dl key/value), .ss-setrow (settings row), .ss-counts (stat strip)
Status .ss-st (dot + text; .ok .warn .bad .off, .wrap for long messages), .ss-tag (mono label; .ok .warn .bad .inf), .ss-sev (audit severity; .c .h .md .l .n), .ss-cnt (count)
Icons .ss-cat (kind tile; .skill .agent .extra .mcp .plugin .target, tones, .sm), .ss-at (agent or tool logo; .lg), .ss-stack (overlapping logos)
Feedback .ss-note (+ .warn .bad .inf), .ss-empty (via EmptyState), .ss-prog, .ss-skel, .ss-toast, .ss-tip
Overlays .ss-scrim + .ss-dlg with .dh .db .df (via DialogShell), .ss-bulk (selection toolbar), .ss-hud (hint while the shortcut modifier is held), .ss-top
Content .ss-prose (rendered markdown), .ss-code (+ .ln .cur), .ss-pre, .ss-ed (editor)
Dashboard .ss-board .ss-pin .ss-pinnote .ss-squig — Playful pin board

Tailwind utilities are for layout inside these (flex, gap-*, min-w-0, w-[92px], truncate). Colour, border, radius and shadow come from ss-* classes or token utilities.

Cascade gotcha: the ss-* classes sit in @layer components, so a Tailwind utility on the same element always wins, whatever the selector specificity. Do not put mb-* on something .ss-wrap already spaces. To override an ss-* property from markup, use the Tailwind important prefix, as in className="ss-r link !min-h-[56px]".

Page structure

<div className="ss-wrap animate-page-in">
  <PageHeader title={t('x.title')} subtitle={t('x.subtitle')} actions={<>...</>} />

  {/* optional: tabs, or tabs with controls on the right */}
  <nav className="ss-tabs" aria-label={t('x.title')}>
    <button type="button" className={on ? 'on' : ''} aria-current={on}>...</button>
  </nav>

  {error && <div className="ss-note bad"><span className="flex-1">{error.message}</span></div>}

  {empty ? (
    <EmptyState icon={SomeIcon} title="..." description="..." action={...} />
  ) : (
    <div className="ss-list">
      <div className="ss-lh">{/* column labels; widths match the row cells */}</div>
      <Link to="..." className="ss-r link">
        <span className="ss-cat skill"><Puzzle size={16} /></span>
        <span className="nm m min-w-0 flex-1 truncate">name</span>
        <span className="w-[92px] shrink-0"><span className="ss-tag">merge</span></span>
        <span className="ss-st ok">synced</span>
      </Link>
    </div>
  )}

  {/* a second section */}
  <section>
    <div className="ss-sec"><h2>Title</h2><span className="ss-cnt">12</span></div>
    <div className="ss-list">...</div>
  </section>

  {/* dialogs last; DialogShell portals to body */}
</div>
  • .ss-wrap spaces its children with a 28px gap. Do not add space-y-* or margins between them.
  • A page that is one child of a wider layout, without .ss-wrap, still gets header spacing from .ss-pgh.
  • PageHeader has no icon (the icon prop is deprecated); do not pass it. Use backTo for a sub-page of a nav item, crumbs for deeper trails, mono when the title is a resource name.
  • A sub-page reached from a nav item keeps that item lit through also in the Layout.tsx nav definition (Skills stays active on /hubs).

Components

Shared components in ui/src/components/ wrap the ss-* classes. Use the component when one exists; write the class directly for things that have none (.ss-list rows, .ss-note, .ss-tabs, .ss-st, .ss-tag, .ss-kv).

Component Renders API
PageHeader .ss-pgh .ss-ph title, subtitle?, actions?, backTo?, crumbs?, mono?
Button .ss-btn variant="primary|secondary|danger|warning|ghost|link", size="xs|sm|md|lg", loading?
IconButton .ss-ib icon, label (required, becomes aria-label), size, variant="ghost|danger-outline"
Card .ss-box padding="none|sm|md", variant="default|outlined", hover?, overflow?, onClick?. tilt and skillCard do nothing
Badge .ss-tag variant="default|success|warning|danger|info", size, dot?
KindBadge .ss-tag kind="skill|agent"
EmptyState .ss-empty icon (LucideIcon), title, description?, action?
DialogShell .ss-scrim .ss-dlg open, onClose, maxWidth="sm".."7xl", padding, preventClose?, ariaLabel. Use padding="none" with .dh / .db / .df children for the standard header, body and footer
ConfirmDialog DialogShell open, onConfirm, onCancel, title, message, variant="default|danger", loading?, wide?
Input, Textarea .ss-fld .ss-inp label?, size="sm|md" + native props. Input.tsx re-exports Checkbox and Select
Select .ss-inp + .ss-menu label?, value, onChange, options[] (description?, triggerLabel?, detail?), size, prefix?, quiet (footer menu without a box), up, search (type-to-filter)
Checkbox .ss-chk label (required), checked, onChange, indeterminate?, hideLabel? for row selection
SegmentedControl .ss-seg value, onChange, options[] (count?, title? for icon-only), colorFn?
Pagination .ss-pager page, totalPages, onPageChange, rangeText?, pageSize?
Tooltip, TruncateTip .ss-tip content, side, delay, followCursor?
Spinner lucide Loader2 size="sm|md|lg"
Skeleton, PageSkeleton shimmer variant="text|card|circle"
useToast() .ss-toast toast(message, 'success'|'error'|'warning'|'info', { title? })
AgentIcon real agent logo For targets and agents. Do not substitute a generic lucide icon
CopyButton, CodeView, CodeEditor, MarkdownView .ss-code .ss-prose Code and markdown display

Feature folders (audit/, config/, git/, hub/, mcp/, plugins/, skill-editor/, sync/, targets/, tour/) hold page-specific pieces.

Icons

lucide-react only. 14–16px inline, 16px inside .ss-cat, 24px in EmptyState. Stroke width comes from --isw; do not set strokeWidth, except the check mark inside .ss-chk. One icon per concept across the app: check Layout.tsx and neighbouring pages before picking one.

Data fetching

const { data, error, isPending } = useQuery({
  queryKey: queryKeys.someKey,
  queryFn: () => api.someEndpoint(),
  staleTime: staleTimes.someCategory,
});
if (isPending) return <PageSkeleton />;

Keys in ui/src/lib/queryKeys.ts, client in ui/src/api/client.ts, useAppContext() gives { isProjectMode, projectRoot }. Every user-visible string goes through useT(); status, mode and kind labels (merge, linked, skill) stay in English.

Verifying a change

Run the dev server inside the devcontainer with the ui command, never on the host. There Vite listens on :45173 (make ui-dev on a host with Go uses :5173). Screenshot the page in all four looks, at desktop width only: ?theme=clean, ?theme=playful, then each in dark. Look at the screenshots before reporting done. Do not run prettier in ui/; it has no config and rewrites whole files.


Website (website/)

Two separate treatments share one palette in website/src/css/custom.css.

Area Files Look
Docs, navbar, footer src/css/custom.css Clean: pill buttons, solid 1px borders, soft shadows, plain underlined links, no dot grid
Homepage, feature map src/pages/index.tsx + index.module.css, features.tsx + features.module.css Hand-drawn string board: pinned notes, tape, string lines, wobbly radii, hard offset shadows, Kalam accents, slight rotation
  • Fonts: IBM Plex Sans body, Inter headings, JetBrains Mono code. Kalam appears on the homepage only.
  • Palette variables keep the --color-pencil / --color-paper / --color-postit names here. That is current for the website; only the dashboard moved to --ink / --bg.
  • --radius-wobbly* and the hard --shadow-* are defined globally but belong to the homepage modules. Do not apply them to docs chrome.
  • Dark mode swaps the blue primary for amber. Check both modes.
  • Docs chrome is styled by overriding Docusaurus classes (.button--primary, .menu__link--active, .admonition, .table-of-contents, .target-badge). Each block in custom.css has a titled banner comment; find the block, edit it there.
  • Homepage sections are local components in index.tsx (HeroSection, StringBoard, PinList, SyncTerminal, InstallTabs, FourMovesSection, FeatureMapTeaser, CtaSection), styled from the CSS module.
  • Mermaid diagrams use the global handDrawn config in docusaurus.config.ts: labels of one or two lines, <br/> for line breaks, and verify with a screenshot.
  • Docs are English only. ~ inside an HTML <code> in MDX must be written &#126;.

Anti-patterns

Don't Do instead
Hardcoded hex, radius, shadow or font in a page Token utility (text-ink-2) or ss-* class
Legacy names (text-pencil-light, border-muted, text-danger) in new code text-ink-2, border-line, text-bad
Root <div className="space-y-5"> .ss-wrap
Hand-rolled dashed separators .ss-r inside .ss-list, or border: var(--sep)
<details>, bare <ul> or <p role="alert"> for app content .ss-list rows, .ss-note bad
Playful pastels (--pa…--pe) in a shared rule Scope to :root[data-theme="playful"]
Tilted cards Nothing tilts in the dashboard. Rotation exists only on the website homepage
Dot and tag both carrying the same status One per element: .ss-st for state, .ss-tag for a label
Left colour stripes (border-l-*) .ss-st, .ss-tag or .ss-note
Emoji as icons lucide, or AgentIcon for real tools
Stat cards for one to three numbers Inline text, or .ss-cnt beside the heading
window.confirm() ConfirmDialog
Custom empty-state markup EmptyState
A small checkbox or icon as the only click target in a clickable row Keep the hit area at 24px or more; .ss-chk already does this with ::after
Dropdown inside a Card getting clipped overflow prop on Card
Wording that drifts from the CLI Use the CLI's terms: sync, target, collect, tracked, merge

Checklist

  • Root is .ss-wrap animate-page-in; PageHeader first, without icon
  • No hardcoded colours, radii or shadows; no legacy token names added
  • Shared components used where they exist; lists are .ss-list / .ss-r
  • Errors are .ss-note bad, empty states are EmptyState, destructive actions go through ConfirmDialog
  • Icon-only buttons have an accessible name; click targets are 24px or more
  • Strings go through useT(); new shortcuts are added to useGlobalShortcuts.ts
  • Screenshots checked in Clean and Playful, light and dark

Tips for Skillshare UI Website Style

  • • Start a fresh session after installing so your agent picks up the new skill.
  • • It bundles reference files. The agent reads them only when needed, so they cost no context until then.
  • • It is part of a pack with 10 skills. Install only the ones you need with --skill to keep triggers precise.
  • • If two skills overlap, mention the one you want by name.

Questions about Skillshare UI Website Style

What does the Skillshare UI Website Style skill do?

Skillshare frontend design system for the React dashboard (ui/) and Docusaurus website (website/). Use this skill whenever you: build or modify a dashboard page or component in ui/src/, style or layout website pages or custom CSS in website/, create new React components for the dashboard, add pages to the dashboard, fix visual bugs in either frontend, or need to know which design tokens, ss-* classes, components, or

How do I install Skillshare UI Website Style?

Run "npx skills add runkids/skillshare --skill skillshare-ui-website-style" in your project. The skills CLI installs it for Claude Code, Cursor, Codex and 70+ other agents. In Claude on the web, upload the skill folder as a ZIP under Customize > Skills.

Does Skillshare UI Website Style work in Cursor and Codex?

Yes. Skillshare UI Website Style uses the open SKILL.md format, so it works in Claude Code, Claude, Cursor, OpenAI Codex, Gemini CLI, GitHub Copilot and other agents that support agent skills.

Is Skillshare UI Website Style free?

Skillshare UI Website Style is open source on GitHub under the MIT license. It is free to install; check the license before commercial use.

Who made Skillshare UI Website Style?

Skillshare UI Website Style is published by runkids in the runkids/skillshare repository, together with 9 other skills.

Similar skills. From other creators.