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.json

Install 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`