Skills
Teach your AI agent to build with mountainview-ui.
What is a skill?
A skill is a set of instructions an AI coding agent (like Claude Code) loads when a task matches it. The mountainview-ui skill teaches the agent how to set the library up correctly, which tokens and conventions to use, and what every component exports — so generated code looks like Material 3 on the first try.
What the agent learns
- The setup order: shadcn init, theme.json first, tw-animate-css, CSS imports.
- The token cheatsheet: color roles, the 15-step type scale, shape, elevation, and state layers.
- M3 conventions: state layers over color swaps, pill buttons, semantic elevation.
- Composition patterns: app shells, bottom navigation with a FAB, snackbar(), floating labels.
- The full component catalog with slugs, exports, and install commands.
Install with the shadcn CLI
The skill ships as a registry item. In a project, this places it under .claude/skills/ where Claude Code picks it up automatically:
npx shadcn@latest add https://mountainview-ui.baltoon.jp/r/skill.jsonInstall user-wide
To make the skill available in every project, copy it into your user-level skills directory:
npx shadcn@latest add https://mountainview-ui.baltoon.jp/r/skill.json
mkdir -p ~/.claude/skills && cp -r .claude/skills/mountainview-ui ~/.claude/skills/What's inside
Two files: SKILL.md (setup, tokens, conventions, patterns, pitfalls) and references/components.md (the generated catalog of all components).
SKILL.md
---
name: mountainview-ui
description: >
How to install and build UIs with mountainview-ui — the shadcn-style React
component library that faithfully implements Google's Material Design 3
(Material You) on Tailwind CSS v4 + Radix. Use this skill whenever the user
mentions mountainview-ui, wants Material 3 / Material You UI in React or
Next.js, asks for M3 components on the web (FABs, chips, navigation bars,
navigation drawers, snackbars, segmented buttons, floating-label text
fields, bottom sheets), or is adding components from the mountainview-ui
registry — even if they just say "make it feel like a Google app" without
naming the library.
---
# mountainview-ui
mountainview-ui distributes Material 3 React components the shadcn way: the
CLI copies the component **source** into the user's project
(`components/ui/`), where it can be edited freely. There is no runtime
package to depend on. Docs and live demos: https://mountainview-ui.baltoon.jp
## Setup (once per project)
Requirements: React 18+/Next.js and **Tailwind CSS v4** (the tokens use
`@theme`/`@utility`, which do not exist in v3).
```bash
# 1. shadcn plumbing, if the project has no components.json yet
npx shadcn@latest init
# 2. theme tokens + cn() helper — REQUIRED before any component
npx shadcn@latest add --overwrite https://mountainview-ui.baltoon.jp/r/theme.json
npm install tw-animate-css
```
Then import the theme in the global stylesheet, after Tailwind:
```css
@import "tailwindcss";
@import "tw-animate-css";
@import "../mountainview-ui-theme.css"; /* adjust the relative path */
```
Install theme.json FIRST: every component reads the M3 color roles, type
scale, shape, elevation, and state-layer utilities from it. Without the
theme, components render unstyled. theme.json also ships an extended
`lib/utils.ts` — see Pitfalls.
Add components afterwards, one URL per component:
```bash
npx shadcn@latest add https://mountainview-ui.baltoon.jp/r/button.json
```
The full catalog with slugs, exports, and install commands is in
[references/components.md](references/components.md).
## Token cheatsheet
Color roles (CSS vars, light + `.dark` values; use as Tailwind colors):
- Accents: `bg-primary text-on-primary`, `bg-primary-container
text-on-primary-container`, same pairs for `secondary` and `tertiary`,
plus `bg-error` / `bg-error-container`.
- Surfaces (low → high emphasis): `bg-surface`, `bg-surface-low`,
`bg-surface-container`, `bg-surface-high`, `bg-surface-highest`.
Content on them: `text-on-surface`, `text-on-surface-variant`.
- Lines: `border-outline` (strong), `border-outline-variant` (hairline).
- Inverse (snackbars): `bg-inverse-surface text-inverse-on-surface`,
`text-inverse-primary`.
Type scale — always prefer these utilities over raw `text-sm`/`font-bold`;
each carries the exact M3 size, line height, tracking, AND weight:
`text-display-l/m/s`, `text-headline-l/m/s`, `text-title-l/m/s`,
`text-body-l/m/s`, `text-label-l/m/s`. (`label-l` is the button size,
`body-m` the default reading size, `title-m` a card heading.)
Shape: `rounded-xs` 4px, `rounded-sm` 8px, `rounded-md` 12px (cards),
`rounded-lg` 16px, `rounded-xl` 28px (dialogs, sheets), `rounded-full`
(buttons, chips ends). Elevation: `shadow-[var(--shadow-elevation-1)]`
through elevation-5.
State layers: `state-on-surface`, `state-primary`, `state-on-primary`,
`state-on-secondary-container` — these implement the M3 spec's 8% hover /
12% press overlay on the right base color.
Dark mode is the `dark` class on `<html>`; every var swaps automatically.
Re-theming = overriding `--primary`, `--primary-container`, etc. (e.g. from
Material Theme Builder output). Never hardcode hex.
## M3 conventions the components follow
- **Interaction is a state layer, not a color swap.** Hover/press tint the
existing surface with 8%/12% of the content color. When building custom
interactive elements, use the `state-*` utilities instead of inventing
hover colors.
- **Buttons are full-round** (pill), 40dp tall, `text-label-l`. Emphasis
ladder: filled > tonal > elevated > outlined > text. One filled button per
region; pair it with text buttons in dialogs.
- **Active navigation is a pill indicator** (secondary-container behind the
icon), not a highlighted row: navigation-bar, navigation-rail, and
navigation-drawer all follow this.
- **Elevation is semantic.** Cards sit at elevation 1, menus at 2, FABs and
dialogs at 3. Don't stack heavy shadows for decoration.
- Disabled state is `opacity-[0.38]`, not a gray recolor.
## Composition patterns
Desktop app shell (drawer + content):
```tsx
<div className="flex h-dvh">
<NavigationDrawer>
<NavigationDrawerHeadline>Mail</NavigationDrawerHeadline>
<NavigationDrawerItem icon={<InboxIcon />} badge="24" active>Inbox</NavigationDrawerItem>
</NavigationDrawer>
<main className="min-w-0 flex-1 overflow-y-auto bg-surface">
<TopAppBar scrolled={isScrolled}>…</TopAppBar>
…
</main>
</div>
```
Mobile shell (bottom navigation + FAB): `NavigationBar` (Radix Tabs —
`NavigationBarContent` per tab, `NavigationBarList` last) with an absolutely
positioned `Fab` above it. Modal navigation on phones: `ModalNavigationDrawer
trigger={<IconButton…>}`.
Snackbars are imperative — render `<Snackbars />` once near the root, then
from anywhere:
```tsx
snackbar({ message: "Photo archived", actionLabel: "Undo", onAction: undo });
```
Text fields: pass `label` (floating label is built in — never add a separate
`<label>` above), `supportingText` for helper/error copy, `error` to flip to
error colors. `variant="outlined"` for dense forms, default filled for
standalone fields.
## Pitfalls
- `shadcn init` scaffolds a starter `components/ui/button.tsx`; when adding this
registry's `button`, answer yes to the overwrite prompt (or pass
`--overwrite`) so the starter doesn't shadow it. Install the theme with
`--overwrite` too, so its enhanced `lib/utils.ts` replaces the plain one.
- Installing a component before theme.json → unstyled output. Theme first.
- The theme ships `lib/utils.ts` with an **extended tailwind-merge** that
registers the M3 type-scale utilities as font-size classes. Don't replace
it with a stock `cn()` — if you do, `text-title-m text-on-surface` merges
wrongly and the size class is silently dropped.
- `tw-animate-css` must be installed and imported, or dialogs, sheets, menus
and snackbars appear without enter/exit animations.
- Components assume the `dark` class strategy. If the project uses
`prefers-color-scheme` only, add a small script that sets the class.references/components.md
# mountainview-ui component catalog
Install any component with:
```bash
npx shadcn@latest add https://mountainview-ui.baltoon.jp/r/<slug>.json
```
Import from `@/components/ui/<slug>`. Per-component docs with live demos:
`https://mountainview-ui.baltoon.jp/docs/components/<slug>`
## Table of contents
- [Actions](#actions) — button, chip, fab, icon-button, segmented-button
- [Selection & input](#selection-input) — checkbox, date-picker, radio-group, search-bar, slider, switch, text-field, time-picker
- [Containment & content](#containment-content) — badge, banner, card, carousel, divider, list, progress
- [Overlays](#overlays) — bottom-sheet, dialog, menu, side-sheet, snackbar, tooltip
- [Navigation](#navigation) — bottom-app-bar, navigation-bar, navigation-drawer, navigation-rail, tabs, top-app-bar
## Actions
### Button (`button`)
Filled, tonal, outlined, text, and elevated common buttons. Material 3 counterpart: Common buttons.
Exports: `Button`, `buttonVariants`
### Chip (`chip`)
Assist, filter, and input chips, 32dp with 8dp corners. Material 3 counterpart: Chips.
Exports: `Chip`, `chipVariants`
### FAB (`fab`)
Floating action button in four colors and four sizes, extended included. Material 3 counterpart: Floating action buttons.
Exports: `Fab`, `fabVariants`
### Icon Button (`icon-button`)
Standard, filled, tonal, and outlined icon buttons with toggle. Material 3 counterpart: Icon buttons.
Exports: `IconButton`, `iconButtonVariants`
### Segmented Button (`segmented-button`)
Outlined segments; selected fills with a check. Material 3 counterpart: Segmented buttons.
Exports: `SegmentedButton`, `SegmentedButtonItem`
## Selection & input
### Checkbox (`checkbox`)
18dp box with 2dp outline and primary fill. Material 3 counterpart: Checkbox.
Exports: `Checkbox`
### Date Picker (`date-picker`)
Docked calendar with today outline and filled selection. Material 3 counterpart: Date pickers.
Exports: `DatePicker`
### Radio Group (`radio-group`)
20dp radio rings with a primary dot. Material 3 counterpart: Radio button.
Exports: `RadioGroup`, `RadioGroupItem`
### Search Bar (`search-bar`)
Full-round search bar expanding into a suggestion view. Material 3 counterpart: Search.
Exports: `SearchBar`
### Slider (`slider`)
Tall active track, narrow handle, stop indicator. Material 3 counterpart: Sliders.
Exports: `Slider`
### Switch (`switch`)
52x32 track; the thumb grows and shows a check when on. Material 3 counterpart: Switch.
Exports: `Switch`
### Text Field (`text-field`)
Filled and outlined fields with the floating label. Material 3 counterpart: Text fields.
Exports: `TextField`
### Time Picker (`time-picker`)
Input-variant picker with 2-digit fields and AM/PM. Material 3 counterpart: Time pickers.
Exports: `TimePicker`
## Containment & content
### Badge (`badge`)
The 6dp error dot and numbered count badge. Material 3 counterpart: Badge.
Exports: `Badge`
### Banner (`banner`)
Inline contained banner with icon and text actions. Material 3 counterpart: Gmail-style banner.
Exports: `Banner`
### Card (`card`)
Elevated, filled, and outlined cards with 12dp corners. Material 3 counterpart: Cards.
Exports: `Card`, `CardContent`, `CardDescription`, `CardFooter`, `CardHeader`, `CardTitle`
### Carousel (`carousel`)
Multi-browse hero strip with rounded-xl snap items. Material 3 counterpart: Carousel.
Exports: `Carousel`, `CarouselItem`
### Divider (`divider`)
1dp outline-variant rule, full-width or inset. Material 3 counterpart: Divider.
Exports: `Divider`
### List (`list`)
One- to three-line list items with leading and trailing slots. Material 3 counterpart: Lists.
Exports: `List`, `ListDivider`, `ListItem`
### Progress (`progress`)
Linear indicator with stop dot, plus circular indeterminate. Material 3 counterpart: Progress indicators.
Exports: `CircularProgress`, `Progress`
## Overlays
### Bottom Sheet (`bottom-sheet`)
28dp-corner sheet with a drag handle on surface-container-low. Material 3 counterpart: Bottom sheets.
Exports: `BottomSheet`, `BottomSheetClose`, `BottomSheetContent`, `BottomSheetTitle`, `BottomSheetTrigger`
### Dialog (`dialog`)
Basic dialog: 28dp corners, headline, text-button actions. Material 3 counterpart: Dialogs.
Exports: `Dialog`, `DialogClose`, `DialogContent`, `DialogDescription`, `DialogFooter`, `DialogIcon`, `DialogTitle`, `DialogTrigger`
### Menu (`menu`)
Elevation-2 menu on surface-container with 48dp items. Material 3 counterpart: Menus.
Exports: `Menu`, `MenuCheckboxItem`, `MenuContent`, `MenuItem`, `MenuSeparator`, `MenuShortcut`, `MenuSub`, `MenuSubContent`, `MenuSubTrigger`, `MenuTrigger`
### Side Sheet (`side-sheet`)
400dp trailing-edge panel with title and close. Material 3 counterpart: Side sheets.
Exports: `SideSheet`, `SideSheetClose`, `SideSheetContent`, `SideSheetTrigger`
### Snackbar (`snackbar`)
Inverse-surface toast, bottom-left; call snackbar() anywhere. Material 3 counterpart: Snackbar.
Exports: `snackbar`, `Snackbars`
### Tooltip (`tooltip`)
Plain inverse-surface pill and rich container variants. Material 3 counterpart: Tooltips.
Exports: `Tooltip`, `TooltipContent`, `TooltipProvider`, `TooltipSubhead`, `TooltipTrigger`
## Navigation
### Bottom App Bar (`bottom-app-bar`)
80dp action bar with a trailing FAB slot. Material 3 counterpart: Bottom app bar.
Exports: `BottomAppBar`
### Navigation Bar (`navigation-bar`)
The 80dp bottom bar with pill active indicators. Material 3 counterpart: Navigation bar.
Exports: `NavigationBar`, `NavigationBarContent`, `NavigationBarItem`, `NavigationBarList`
### Navigation Drawer (`navigation-drawer`)
Standard and modal drawers with pill indicators. Material 3 counterpart: Navigation drawer.
Exports: `ModalNavigationDrawer`, `NavigationDrawer`, `NavigationDrawerHeadline`, `NavigationDrawerItem`
### Navigation Rail (`navigation-rail`)
The 80dp vertical rail with a FAB slot. Material 3 counterpart: Navigation rail.
Exports: `NavigationRail`, `NavigationRailItem`
### Tabs (`tabs`)
Primary tabs with the animated pill underline indicator. Material 3 counterpart: Tabs.
Exports: `Tabs`, `TabsContent`, `TabsList`, `TabsTrigger`
### Top App Bar (`top-app-bar`)
64dp small app bar with on-scroll tint. Material 3 counterpart: Top app bar.
Exports: `TopAppBar`, `TopAppBarTitle`