UI Design System — Umaguide
Game-UI aesthetic inspired by Umamusume Pretty Derby and GBF wiki. Glossy chrome surfaces, ribbon headers, beveled buttons, and warm lime-green as the brand anchor.
Design Philosophy
- Game-UI chrome, not generic web UI. Panels have glossy header bars with argyle diamond texture. Buttons bevel and press down. Badges have thick white outlines.
- Three accent colors. Green (primary/brand), Pink (events/community), Blue (database/tools). These propagate consistently through every component via
colorprops. - Dark mode shifts the palette but keeps the structure. Light mode uses vivid lime-green; dark mode uses muted olive-green. Every surface variable has a dark override.
- VitePress VP tokens are overridden sparingly. Page backgrounds, text, and dividers go through
--vp-c-*. Game-UI chrome goes through--uma-*. Keep these two namespaces separate.
Color Tokens
All defined in custom.css.
Brand Greens
| Token | Light | Dark | Use |
|---|---|---|---|
--uma-green | #65ba00 | #6a9e3a | Primary fills, borders |
--uma-green-light | #90d300 | #7aba40 | Hover borders, badges |
--uma-green-dark | #4e8f00 | — | Button shadow base |
--uma-green-deep | #3f8a00 | #8dd050 | Text labels on white |
--uma-green-bg-soft | #f4fbe9 | var(--vp-c-bg-soft) | Card hover fills |
--uma-green-bg-hover | #e8f7d0 | var(--vp-c-bg-elv) | Tab track background |
Pink Accent
| Token | Value |
|---|---|
--uma-pink | #ff3376 |
--uma-pink-light | #fd7ca5 |
--uma-pink-deep | #d61f5e |
Blue Accent
| Token | Value |
|---|---|
--uma-blue | #6b79e9 |
--uma-blue-light | #7ba9fa |
--uma-blue-deep | #4250c4 |
Semantic / Status
| Token | Value | Use |
|---|---|---|
--color-success | #008700 | Active state text |
--color-danger | #af0000 | Error / stamina |
--color-warning | #d75f00 | Power training |
--color-info | #005faf | Speed training |
Rarity Colors
| Token | Background | Text |
|---|---|---|
| SSR | #b8bcf0 | #444444 |
| SR | #e8c84d | #444444 |
| R | #bcbcbc | #444444 |
Skill Type Colors
All follow the pattern --skill-type-{name} (text) + --skill-type-{name}-bg (background tint).
debuff · overtake · style · distance · recovery · special · passive · vision
Training Stat Colors
--training-speed · --training-stamina · --training-power · --training-guts · --training-wit
Each has a -bg tint variant.
Typography
| Token | Stack |
|---|---|
--uma-font-display | Inter → Noto Sans JP → Hiragino Kaku Gothic ProN → system-ui |
--uma-font-rounded | same stack (reserved for bold UI labels, badges, buttons) |
--uma-font-body | same stack |
- Display/rounded font weight: 800 for headers and labels, 700 for body UI.
- Body font size: VitePress default (~16px).
letter-spacing: 0.02–0.04emon headers and buttons.text-shadowon all white-on-color text:0 1px 1px rgba(40,70,0,0.4)(green) / pink / blue variants.
Surface Tokens
Panels
--uma-panel-bg: #ffffff (dark: #21242b)
--uma-panel-border: #dbe8c6 (dark: #3a3f4a)
--uma-panel-radius: 18px
--uma-panel-shadow: 0 6px 18px rgba(54,74,18,0.12), 0 1px 0 rgba(255,255,255,0.85) insetPanel Headers (glossy ribbon)
--uma-header-grad: linear-gradient(180deg, #a2dd3f, #8ace1f 46%, #77c500)
--uma-header-gloss: diagonal highlight, 52%→70%→100%
--uma-tex-diamond: repeating 45°/-45° lattice, rgba(255,255,255,0.16) 2px on 11px
--uma-header-border: #5a9e00
--uma-header-text: var(--uma-cream) — #f2f3f7
--uma-header-radius: 9pxPink/blue panel header gradient variants exist as --uma-panel-{color}-grad / --uma-panel-{color}-border.
Buttons
--uma-btn-grad: linear-gradient(180deg, #9ad614, #74c400 52%, #65ba00)
--uma-btn-grad-hover: lighter shift
--uma-btn-border: #4e8f00
--uma-btn-shadow: 0 4px 0 #4e8f00, 0 7px 12px rgba(54,74,18,0.26)Pink / blue variants: --uma-btn-{color}-grad / --uma-btn-{color}-border / --uma-btn-{color}-shadow.
Components
UPanel
File: ui/UPanel.vue
The primary layout building block. White floating card with a glossy header bar.
Props:
| Prop | Type | Default | Notes |
|---|---|---|---|
title | string | — | Header text |
icon | string | — | Emoji/symbol prefix |
color | green | pink | blue | green | Header color |
collapsible | boolean | false | Adds a collapse toggle |
collapsed | boolean | false | Initial collapsed state |
flush | boolean | false | Removes body padding (for full-bleed children) |
Slots: default body · #header override · #actions (right-aligned in header)
Usage:
<UPanel title="Featured Guides" color="green">
<template #actions><a href="/guides/">View all →</a></template>
<!-- content -->
</UPanel>USectionHeader
File: ui/USectionHeader.vue
Game ribbon header. Two distinct shapes.
Props:
| Prop | Type | Default |
|---|---|---|
color | green | pink | blue | green |
shape | pennant | banner | pennant |
align | center | left | center (banner only) |
icon | string | — |
pennant— inline flag shape, pointed right + forked-tail left. Used for sub-section headings.banner— full-width bar with argyle texture + diagonal gloss. Used for section/page headers like "Browse".
<USectionHeader shape="banner" color="green">Browse</USectionHeader>
<USectionHeader shape="pennant" color="pink">Events</USectionHeader>UNavTile
File: ui/UNavTile.vue
GBF-style illustrated square icon tile for navigation grids. Lifts on hover.
Props: label · href · image? · color?: blue | green | pink
Sizing:
| Breakpoint | Tile | Frame |
|---|---|---|
| > 480px | 92px wide | 78×78px |
| ≤ 480px | 100% / max 72px | 60×60px |
| ≤ 360px | — | 48×48px |
Used in HomeLayout inside a repeat(5, 1fr) grid with justify-items: center. Always renders as 5 columns from 360px up to 1275px.
UButton
File: ui/UButton.vue
Glossy beveled button. Renders as <a> when href is given.
Props:
| Prop | Type | Default |
|---|---|---|
variant | green | pink | blue | ghost | green |
size | sm | md | lg | md |
href | string | — |
icon | string | — |
block | boolean | false |
disabled | boolean | false |
Visual: top-half gloss overlay, 3D bevel shadow, presses down 3px on :active. ghost variant is white fill with green border.
UBadge
File: ui/UBadge.vue
Chunky pill badge with thick white outline. Game-UI chip style.
Props: color?: green | pink | blue | gold | gray · outline?: boolean · icon?: string
- Solid: gradient fill, white text, white
1.5pxborder. outline: white fill, colored border + text. Gold outline uses#c8860atext.- Gold solid uses dark text (
#5a3d00) with light text-shadow.
UGradeBadge
File: ui/UGradeBadge.vue
Race-grade swallowtail ribbon flag. Straight left edge, forked V-notch on the right via clip-path.
Grade → Color mapping:
| Grade | Color |
|---|---|
| G1 | blue |
| G2 | pink |
| G3 | green |
| OP / EX | orange |
| Pre-OP | tan |
| Listed | purple |
Props: grade? (auto-resolves color+label) · label? (override text) · color? (override color)
UBannerItem
File: ui/UBannerItem.vue
Framed event/scout banner with a status footer. Used in Current Events panel.
Props:
| Prop | Type | Default |
|---|---|---|
image | string | required |
href | string | — |
status | active | upcoming | ended | active |
time | string | — |
label | string | — |
note | string | — |
layout | stack | row | stack |
links | {href, label, img?}[] | — |
stack: image on top, status below — for grid cells.row: image left, status right — for stacked lists.- Status colors: active = green pill, upcoming/ended = neutral pill.
UPortraitCard
File: ui/UPortraitCard.vue
Framed character portrait with a name plate. Matches the game's bordered portrait style.
Props: image · name? · subtitle? · href? · frame?: green | pink | blue | gold | auto
autoframe: samples the portrait image via canvas at load time, extracts the dominant non-skin color, and applies it as the frame gradient. Boosts blues/greens/cyans. Skips browns and skin tones.- Name plate is a rounded pill overlapping the frame bottom, white fill with colored border.
UCard
File: ui/UCard.vue
General-purpose content tile. Two layout variants.
Props: title · description? · href? · image? · icon? · color?: green | pink | blue · variant?: row | tile
row(default): 16:9 media on top, accent border strip, title + description below. Lifts on hover.tile: square icon tile, soft panel background, label below. Drop-shadow on image.
UNavMenu
File: ui/UNavMenu.vue
Top-level nav item. Direct link (no items) or dropdown trigger with a panel.
Props: label · href? · items?: {label, link, desc?}[]
- Opens on hover (pointer), toggles on click (touch).
- Panel has a pointer notch. Closes on outside click, Escape, or route change.
- Dropdown panel: white card,
border-radius: 12px, item rows with green hover tint.
UTabs
File: ui/UTabs.vue
Glossy pill tab selector. v-model holds the active value.
Props: tabs: {label, value, icon?}[] · modelValue: string
- Track: soft green pill container with inset shadow.
- Active tab: green gradient button, beveled shadow, white text.
- Inactive: transparent, muted text, green hover.
USelect
File: ui/USelect.vue
Themed dropdown select. v-model bound.
Props: modelValue · options: {value, label}[] · placeholder?
- Trigger: white pill with
2pxgreen border, rounded font, arrow rotates on open. - Menu: absolute positioned, max-height 200px with styled scrollbar, selected item fills green.
- Closes on outside click via
Teleport-ed backdrop.
UPromoBanner
File: ui/UPromoBanner.vue
Dark promotional banner with logo, eyebrow text, title, description, and a CTA button.
Props: title (required) · href? · external? · logo? · watermark? · eyebrow? · description? · cta? · accent?: blue | green | pink
- Dark background (
#0d1b2ebase, accent shifts the gradient). - Watermark image positioned behind content at
opacity: 0.07. - CTA arrow animates gap on hover.
- On mobile (≤640px): description hidden, logo shrinks to 40px.
Layout — Homepage
File: components/HomeLayout.vue
Structure
home-layout
├── home-bg (fixed atmospheric background image)
└── content-wrapper (flex row, centered)
├── div-sidebar (left rail ad, 160px, only > 1200px landscape)
├── board-shell (main content, max-width 1300px)
│ ├── portal-section (Browse header + nav tile grid)
│ ├── board-cols (two-column flex)
│ │ ├── board-main (HomeBannerReviews + UCurrentEvents)
│ │ └── board-side (Featured Guides, Promo, Esports, Timers, Community, Birthdays)
│ └── bottom-ad
└── div-sidebar (right rail ad)Nav Portal Grid
Always 5 columns across all mobile/tablet/desktop widths:
| Viewport | Columns | Gap | Padding |
|---|---|---|---|
| > 1275px | repeat(10, 1fr) — single row, icons compress as viewport narrows | 12px | 18px 20px |
| 481–1275px | repeat(5, 1fr) | 12px | 18px 20px |
| 481–720px | repeat(5, 1fr) | 8px | 12px |
| ≤ 480px | repeat(5, 1fr) | 5px | 8px |
justify-items: center keeps tiles centered in each column at all widths.
Two-Column Board
- Side-by-side (
flex-direction: row) above 920px. - Stacks vertically below 920px.
- Both columns
flex: 1 1 0— equal width.
Background
- Light: academy-green gradient overlay on
academy-bg.png. - Dark: dark overlay on
bg-dark.png. position: fixed— scrolls the content over the static bg.
Rail Ads
Shown only when innerWidth > 1200 AND landscape (height < width). 160×600px each side.
Interaction Patterns
| Pattern | Implementation |
|---|---|
| Card hover | translateY(-2px to -4px) + increased shadow + accent border-color |
| Button press | translateY(3px) + shadow collapses to 1px |
| Tile hover | translateY(-4px) scale(1.03) + accent border |
| Dropdown open | opacity + translateY(-4px) transition, 130ms |
| Tab switch | Instant background swap, no transition |
Responsive Breakpoints
| px | Changes |
|---|---|
| 1275 | Portal grid pins to repeat(5, 1fr) |
| 1200 | Rail ads appear (also requires landscape) |
| 920 | Board columns stack vertically |
| 720 | board-shell padding reduces to 12px |
| 640 | UPromoBanner hides description, shrinks logo |
| 600 | Guide row thumbnails shrink |
| 540 | UBannerItem row layout footer narrows |
| 480 | Portal grid gap reduces to 5px; nav tiles shrink to 60px frame |
| 360 | Nav tile frame shrinks to 48px |