# Arcade Night

Neon pixel-adjacent game launcher: Silkscreen headings, Chakra Petch UI, a dark purple cabinet canvas with magenta and cyan glow edges. Built for game stores, launchers, esports and leaderboard pages.

> 由 freedesignmd-library 提交 ac4258d5449a3c280aed4b1ac737684ce7646ede 的结构化规则转换；不是上游原有 Markdown。

## 设计原则

Arcade Night is a cabinet in a dark room. The canvas is near-black purple, panels are stepped in two lighter purples, and the two neon colors, magenta for action and cyan for information, light only the edges: borders, focus rings and underlines. Silkscreen is the pixel voice for headings and scores; Chakra Petch carries every readable sentence so the retro feel never costs legibility. Corners are chamfered or square, never round, and the 2px glow edge on the active tile is the single recurring motif. Light mode is the daytime arcade, lavender floor, ink purple type and the same two hues darkened for contrast.

## 标志性设计

- Neon edge, not neon fill: 1px colored borders with a 12px same-hue glow on active and focused elements
- Silkscreen pixel headings at 40px and 56px; body in Chakra Petch so paragraphs stay readable
- Chamfered corners via 0 radius and a 6px clipped corner on cards and primary buttons
- Scores and timers in Silkscreen with zero-padded digits (007,420) and a subtle CRT scanline overlay at 4%
- Magenta means act (Play, Buy), cyan means info (rank, level, ping); never swap them

## 浅色配色

| 角色 | 值 |
| --- | --- |
| background | `#f1edff` |
| foreground | `#1b1033` |
| card | `#ffffff` |
| cardForeground | `#1b1033` |
| muted | `#e4dcfb` |
| mutedForeground | `#58497e` |
| primary | `#c0118e` |
| primaryForeground | `#ffffff` |
| secondary | `#d9f4f8` |
| secondaryForeground | `#0b3f4a` |
| accent | `#d0f3f7` |
| accentForeground | `#0a4452` |
| border | `rgba(27,16,51,0.18)` |
| input | `rgba(27,16,51,0.4)` |
| ring | `#006f84` |
| destructive | `#c42a33` |
| destructiveForeground | `#ffffff` |
| success | `#0c7a3e` |
| successForeground | `#ffffff` |
| warning | `#ffc21a` |
| warningForeground | `#2a1d00` |

## 深色配色

| 角色 | 值 |
| --- | --- |
| background | `#0a0618` |
| foreground | `#f0eaff` |
| card | `#140d2c` |
| cardForeground | `#f0eaff` |
| muted | `#1e1540` |
| mutedForeground | `#a99ccf` |
| primary | `#ff3fd0` |
| primaryForeground | `#14041f` |
| secondary | `#1a2a4a` |
| secondaryForeground | `#bdf6ff` |
| accent | `#0e3a4a` |
| accentForeground | `#7af3ff` |
| border | `rgba(122,243,255,0.2)` |
| input | `rgba(122,243,255,0.4)` |
| ring | `#2de6ff` |
| destructive | `#ff5a6e` |
| destructiveForeground | `#20040a` |
| success | `#43f08a` |
| successForeground | `#03200f` |
| warning | `#ffd23a` |
| warningForeground | `#2a1d00` |

## 字体

```json
{
  "display": "Silkscreen",
  "body": "Chakra Petch",
  "mono": "Share Tech Mono",
  "googleFontsUrl": "https://fonts.googleapis.com/css2?family=Silkscreen:wght@400;700&family=Chakra+Petch:wght@400;500;600&family=Share+Tech+Mono&display=swap",
  "fallbacks": {
    "display": "ui-monospace, SFMono-Regular, Menlo, monospace",
    "body": "ui-sans-serif, system-ui, -apple-system, sans-serif",
    "mono": "ui-monospace, SFMono-Regular, Menlo, monospace"
  }
}
```

## 排版

```json
{
  "display": {
    "font": "display",
    "size": 56,
    "leading": 1.1,
    "weight": 700,
    "tracking": "0.01em",
    "uppercase": true
  },
  "h1": {
    "font": "display",
    "size": 40,
    "leading": 1.15,
    "weight": 700,
    "tracking": "0.01em",
    "uppercase": true
  },
  "h2": {
    "font": "display",
    "size": 24,
    "leading": 1.25,
    "weight": 400,
    "tracking": "0.02em",
    "uppercase": true
  },
  "h3": {
    "font": "body",
    "size": 20,
    "leading": 1.3,
    "weight": 600,
    "tracking": "0.02em"
  },
  "body": {
    "font": "body",
    "size": 16,
    "leading": 1.55,
    "weight": 400,
    "tracking": "0.01em"
  },
  "small": {
    "font": "body",
    "size": 14,
    "leading": 1.5,
    "weight": 400,
    "tracking": "0.01em"
  },
  "label": {
    "font": "body",
    "size": 12,
    "leading": 1.3,
    "weight": 600,
    "tracking": "0.12em",
    "uppercase": true
  },
  "mono": {
    "font": "mono",
    "size": 14,
    "leading": 1.5,
    "weight": 400,
    "tracking": "0.02em"
  }
}
```

## 间距

```json
[
  4,
  8,
  12,
  16,
  24,
  32,
  48,
  64,
  96,
  128
]
```

## 布局

```json
{
  "maxWidth": 1240,
  "columns": 12,
  "gutter": 20,
  "sectionY": 88,
  "sectionYMobile": 52,
  "measure": "60ch",
  "notes": [
    "Launcher shell: 88px icon rail, a 12-column tile grid, and a 360px friends panel that collapses below 1100px.",
    "Game tiles are 3:4 posters with a 2px neon edge on hover; the featured game spans 8 columns.",
    "Leaderboards use 44px rows with rank in cyan Silkscreen and the player name in Chakra Petch."
  ]
}
```

## 圆角

```json
{
  "sm": "0",
  "md": "2px",
  "lg": "4px",
  "xl": "8px",
  "full": "9999px"
}
```

## 动效

```json
{
  "duration": {
    "instant": 60,
    "fast": 120,
    "base": 200,
    "slow": 400
  },
  "easing": {
    "standard": "cubic-bezier(0.4, 0, 0.2, 1)",
    "out": "steps(6, end)",
    "in": "cubic-bezier(0.6, 0, 1, 1)"
  },
  "reveal": {
    "distance": 8,
    "stagger": 50
  },
  "signature": {
    "name": "Insert coin",
    "description": "Glow edges power on in steps: borders flicker once (opacity 0.6 to 1) over `base`, and tiles lift 8px with a stepped `out` curve like frames of a sprite. Page loads show a stepped progress bar instead of a spinner."
  }
}
```

## 图像

```json
"Key art is the imagery: vertical game posters, character renders and screenshots on the dark canvas, with a 2px neon edge on hover and a 4% scanline overlay. Banners may use pixel-art dithering and low-resolution sprites scaled with nearest-neighbor. Avoid photography of people holding controllers."
```

## 图标

```json
"20px pixel-grid icons drawn on a 10x10 grid with square caps, 2px stroke: joystick, coin, trophy, heart, lightning bolt. Active state fills the glyph in cyan; action glyphs are magenta."
```

## 组件规则

```json
{
  "button": {
    "base": "display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 44px; padding: 0 22px; font-family: var(--font-display); font-size: 14px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; border-radius: 0; border: 2px solid transparent; white-space: nowrap; cursor: pointer; text-decoration: none; transition: background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard), transform var(--duration-fast) var(--ease-standard); clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 8px 100%, 0 calc(100% - 8px))",
    "primary": {
      "rest": "background: var(--primary); color: var(--primary-foreground)",
      "hover": "background: color-mix(in oklab, var(--primary) 85%, white); filter: drop-shadow(0 0 8px var(--primary))",
      "active": "background: color-mix(in oklab, var(--primary) 80%, black); transform: translateY(2px)"
    },
    "secondary": {
      "rest": "background: var(--secondary); color: var(--secondary-foreground)",
      "hover": "background: var(--accent); color: var(--accent-foreground)",
      "active": "background: var(--muted)"
    },
    "outline": {
      "rest": "background: transparent; color: var(--primary); border-color: var(--primary)",
      "hover": "background: color-mix(in oklab, var(--primary) 16%, transparent); filter: drop-shadow(0 0 6px var(--primary))",
      "active": "background: color-mix(in oklab, var(--primary) 28%, transparent)"
    },
    "ghost": {
      "rest": "background: transparent; color: var(--muted-foreground)",
      "hover": "background: var(--accent); color: var(--accent-foreground)",
      "active": "background: var(--secondary)"
    },
    "focus": "outline: 2px solid var(--ring); outline-offset: 3px",
    "disabled": "opacity: 0.4; cursor: not-allowed; filter: none"
  },
  "input": {
    "rest": "display: block; width: 100%; height: 44px; padding: 0 14px; font-family: var(--font-sans); font-size: 15px; color: var(--foreground); background: var(--card); border: 1px solid var(--input); border-radius: 0; outline: none; transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard)",
    "placeholder": "color: var(--muted-foreground); opacity: 1",
    "hover": "border-color: var(--ring)",
    "focus": "border-color: var(--ring); box-shadow: 0 0 0 1px var(--ring), 0 0 14px -2px var(--ring)",
    "invalid": "border-color: var(--destructive); box-shadow: 0 0 0 3px color-mix(in oklab, var(--destructive) 22%, transparent)",
    "disabled": "opacity: 0.5; cursor: not-allowed; background: var(--muted)"
  },
  "card": {
    "rest": "background: var(--card); color: var(--card-foreground); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-sm); padding: 20px; transition: border-color var(--duration-base) var(--ease-out), box-shadow var(--duration-base) var(--ease-out), transform var(--duration-base) var(--ease-out), background-color var(--duration-base) var(--ease-out)",
    "hover": "border-color: var(--primary); box-shadow: var(--shadow-md); transform: translateY(-4px)"
  },
  "badge": {
    "base": "--tone: var(--primary); --tone-foreground: var(--primary-foreground); display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px; border-radius: var(--radius-sm); font-family: var(--font-sans); font-size: 11px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; line-height: 1; white-space: nowrap",
    "solid": "background: var(--tone); color: var(--tone-foreground); border: 1px solid var(--tone)",
    "soft": "background: color-mix(in oklab, var(--tone) 22%, var(--card)); color: var(--foreground); border: 1px solid color-mix(in oklab, var(--tone) 38%, transparent)",
    "outline": "background: transparent; color: var(--foreground); border: 1px solid var(--border)"
  },
  "nav": {
    "bar": "display: flex; align-items: center; gap: 4px; height: 60px; padding: 0 24px; background: color-mix(in oklab, var(--background) 88%, transparent); backdrop-filter: blur(10px) saturate(160%); -webkit-backdrop-filter: blur(10px) saturate(160%); border-bottom: 1px solid var(--border)",
    "link": "padding: 6px 2px; margin: 0 10px; border-bottom: 2px solid transparent; border-radius: var(--radius-sm); font-family: var(--font-sans); font-size: 13px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted-foreground); text-decoration: none; transition: color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard)",
    "linkHover": "color: var(--foreground); border-bottom-color: var(--border)",
    "linkActive": "color: var(--foreground); border-bottom-color: var(--primary)"
  },
  "table": {
    "table": "width: 100%; border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums",
    "th": "text-align: left; height: 40px; padding: 0 16px; font-family: var(--font-sans); font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; background: var(--muted); color: var(--muted-foreground); border-bottom: 1px solid var(--border)",
    "td": "height: 44px; padding: 0 16px; border-bottom: 1px solid var(--border); color: var(--foreground); transition: background-color var(--duration-fast) var(--ease-standard)",
    "rowHover": "background: var(--accent); color: var(--accent-foreground)"
  },
  "dialog": {
    "overlay": "position: fixed; inset: 0; background: rgba(5,2,14,0.78); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); display: grid; place-items: center; padding: 24px",
    "panel": "width: min(520px, 100%); background: var(--card); color: var(--card-foreground); border: 1px solid var(--primary); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); padding: 28px"
  },
  "tabs": {
    "list": "display: flex; gap: 24px; border-bottom: 1px solid var(--border)",
    "tab": "height: 40px; padding: 0; margin-bottom: -1px; background: none; border: 0; border-bottom: 2px solid transparent; color: var(--muted-foreground); cursor: pointer; font-family: var(--font-sans); font-size: 13px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; transition: color var(--duration-base) var(--ease-standard), background-color var(--duration-base) var(--ease-standard), border-color var(--duration-base) var(--ease-standard), box-shadow var(--duration-base) var(--ease-standard)",
    "tabHover": "color: var(--foreground)",
    "tabActive": "color: var(--foreground); border-bottom-color: var(--primary)"
  },
  "link": {
    "rest": "color: var(--ring); text-decoration: underline; text-decoration-color: color-mix(in oklab, var(--ring) 50%, transparent); text-decoration-thickness: 1px; text-underline-offset: 3px; transition: color var(--duration-fast) var(--ease-standard), text-decoration-color var(--duration-fast) var(--ease-standard)",
    "hover": "text-decoration-color: var(--ring)"
  }
}
```

## 推荐做法

- Use magenta `primary` for actions (Play, Buy, Join) and cyan `ring` for information (rank, level, ping)
- Set headings, scores and timers in Silkscreen uppercase; keep every sentence in Chakra Petch
- Light only the edges: a 1px neon border plus a same-hue glow on active and focused elements
- Keep corners square or chamfered at 8px; round only avatars and status dots
- Zero-pad scores and ranks (007,420) and align them in mono

## 避免做法

- Don't set paragraphs in Silkscreen; it is a pixel face for short strings only
- Don't fill large areas with neon; the surface stays dark purple
- Don't put the scanline overlay over text blocks or forms
- Don't use more than one glowing element per row of tiles
- Don't mix magenta and cyan on the same control

## 来源

https://github.com/tammo1007/freedesignmd-library/blob/ac4258d5449a3c280aed4b1ac737684ce7646ede/design-systems/arcade-night.ts

源码按上游 MIT 许可分发，详见随附 LICENSE。
