MIT License Zero Dependencies 30+ Components ⚡ Gaming Ready

Getting Started

@mariojgt/neo-css is a Neo-Brutalist design system with 30+ components, gaming utilities, and a Theme API. Works with React, Vue, Svelte, Next.js, Nuxt, Astro, or plain HTML. No build tool required to get started.

✦
Want to see it live first? Check the showcase page for interactive demos of every component.

Installation

Option A — CDN (no build tool)

Add one <link> to your HTML. That's it.

HTML
<link rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/@mariojgt/neo-css@latest/dist/neo.css">

Option B — npm / pnpm / yarn

Shell
# npm
npm install @mariojgt/neo-css

# pnpm
pnpm add @mariojgt/neo-css

# yarn
yarn add @mariojgt/neo-css

Then import the stylesheet in your entry file:

JS / TS
import '@mariojgt/neo-css/dist/neo.css'

Sub-bundles

Import only what you need to keep bundles small:

JS
import '@mariojgt/neo-css/dist/tokens.css'     // CSS variables only
import '@mariojgt/neo-css/dist/components.css' // all component classes
import '@mariojgt/neo-css/dist/animations.css' // keyframes only

Quick Start — Plain HTML

A complete working page in under 20 lines:

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/@mariojgt/neo-css@latest/dist/neo.css">
</head>
<body class="neo-noise" style="padding:2rem;background:var(--neo-body-bg)">

  <button class="neo-btn neo-btn-primary">Primary</button>
  <button class="neo-btn neo-btn-accent">Accent</button>
  <button class="neo-btn neo-btn-ghost">Ghost</button>

  <div class="neo-card" style="max-width:320px;padding:1.5rem;margin-top:1.5rem">
    <h2 style="margin-bottom:.5rem">Hello Neo</h2>
    <p class="neo-text-muted">Bold borders. Hard shadows. Zero apologies.</p>
  </div>

</body>
</html>

Framework Setup

⚛️ React (Vite)

  1. Install the package
    Shell
    npm install @mariojgt/neo-css
  2. Import in your entry file
    main.jsx
    import '@mariojgt/neo-css/dist/neo.css'
    import { createRoot } from 'react-dom/client'
    import App from './App'
    
    createRoot(document.getElementById('root')).render(<App />)
  3. Use classes in any component
    App.jsx
    export default function App() {
      return (
        <div className="neo-card" style={{'{'}}padding: '1.5rem'{'}'}>
          <button className="neo-btn neo-btn-primary">Click me</button>
        </div>
      )
    }

▲ Next.js (App Router)

app/layout.tsx
import '@mariojgt/neo-css/dist/neo.css'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body className="neo-noise">{children}</body>
    </html>
  )
}

💚 Vue 3

main.js
import { createApp } from 'vue'
import '@mariojgt/neo-css/dist/neo.css'
import App from './App.vue'

createApp(App).mount('#app')

💚 Nuxt 3

nuxt.config.ts
export default defineNuxtConfig({
  css: ['@mariojgt/neo-css/dist/neo.css'],
})

🔥 Svelte / SvelteKit

src/routes/+layout.svelte
<script>
  import '@mariojgt/neo-css/dist/neo.css'
</script>

<slot />

🚀 Astro

src/layouts/Base.astro
---
import '@mariojgt/neo-css/dist/neo.css'
---
<html lang="en">
  <body class="neo-noise">
    <slot />
  </body>
</html>

Tailwind CSS Preset

Use the built-in Tailwind preset to get all Neo design tokens as Tailwind utilities — no CSS import needed.

tailwind.config.js
module.exports = {
  presets: [require('@mariojgt/neo-css/tailwind-preset')],
  content: ['./src/**/*.{html,js,ts,jsx,tsx,vue,svelte}'],
}

The preset exposes:

  • Color utilities: bg-brand, text-brand, border-accent, bg-surface, text-muted…
  • Shadow utilities: shadow-neo, shadow-neo-sm, shadow-neo-lg, shadow-neo-xl
  • border-3 width utility
  • All Neo animation keyframes as animate-neo-*

Design Tokens

All values are CSS custom properties on :root. Override any token after the import to customise the theme.

CSS
/* After importing neo.css, override any token: */
:root {
  /* Brand */
  --neo-brand:          #0d9668;
  --neo-brand-light:    #2bb885;
  --neo-brand-dark:     #047857;

  /* Surfaces (dark by default) */
  --neo-body-bg:          #080d19;
  --neo-surface:          #0c1222;
  --neo-surface-light:    #131d33;
  --neo-surface-lighter:  #1a2742;

  /* Accent & Borders */
  --neo-accent:       #e6930a;
  --neo-border-color: #3a506e;
  --neo-border:       3px solid var(--neo-border-color);
  --neo-radius:       0.375rem;

  /* Shadows */
  --neo-shadow:    5px 5px 0 #000;
  --neo-shadow-sm: 4px 4px 0 #000;
  --neo-shadow-lg: 6px 6px 0 #000;
  --neo-shadow-xl: 8px 8px 0 #000;

  /* Typography */
  --neo-font-sans: ui-sans-serif, system-ui, sans-serif;
  --neo-font-mono: ui-monospace, Consolas, monospace;
}

Runtime Theming

Switch themes at runtime by calling setNeoTheme() — no page reload required. Persisted in sessionStorage.

JS
// Built-in themes
setNeoTheme('emerald')   // default green
setNeoTheme('violet')    // purple brand
setNeoTheme('crimson')   // red brand

Or define your own by setting CSS variables in a class and calling document.documentElement.className = 'my-theme'.


All Components

Buttons Cards Tags / Badges Alerts Forms / Inputs Table Toggle Tabs Divider Hero Modal ✦ Accordion ✦ Tooltip ✦ Skeleton ✦ Avatar ✦ Kbd Badges ✦ Command Palette ✦ Leaderboard ✦ Rarity Cards ✦ Toast Camera Shake Glitch Text XP / HP / MP Bars Combo Counter Particle Burst Typewriter Charge Button Scanlines
ℹ
Live demos for every component live on the showcase page. HTML snippets are in the README.

Buttons

HTML
<button class="neo-btn neo-btn-primary">Primary</button>
<button class="neo-btn neo-btn-accent">Accent</button>
<button class="neo-btn neo-btn-ghost">Ghost</button>
<button class="neo-btn neo-btn-danger">Danger</button>

<!-- Sizes -->
<button class="neo-btn neo-btn-primary neo-btn-sm">Small</button>
<button class="neo-btn neo-btn-primary neo-btn-lg">Large</button>

<!-- Disabled -->
<button class="neo-btn neo-btn-primary" disabled>Disabled</button>

Cards

HTML
<!-- Basic card (hover lifts) -->
<div class="neo-card" style="padding:1.5rem">Content</div>

<!-- Brand card (green top border) -->
<div class="neo-card-brand" style="padding:1.5rem">Content</div>

<!-- Stat card -->
<div class="neo-stat-card">
  <p class="neo-text-muted">Total Users</p>
  <p style="font-size:2rem;font-weight:900">12,480</p>
</div>

Accordion

HTML + JS
<div class="neo-accordion">
  <div class="neo-accordion-item open">
    <button class="neo-accordion-trigger" onclick="neoAccordion(this)">
      Question <span class="neo-accordion-chevron">▼</span>
    </button>
    <div class="neo-accordion-body">Answer text.</div>
  </div>
</div>

<script>
function neoAccordion(btn) {
  const item = btn.closest('.neo-accordion-item')
  const isOpen = item.classList.contains('open')
  item.closest('.neo-accordion')
    .querySelectorAll('.neo-accordion-item.open')
    .forEach(el => el.classList.remove('open'))
  if (!isOpen) item.classList.add('open')
}
</script>

Tooltip — pure CSS, zero JS

HTML
<button class="neo-btn neo-btn-primary"
  data-tip="Creates a new project">
  New Project
</button>

<!-- Works on any element -->
<span class="neo-badge neo-badge-success"
  data-tip="Deployed 2 min ago">Live</span>

Skeleton Loader

HTML
<!-- Sizes -->
<div class="neo-skeleton neo-skeleton-thumb"></div>  <!-- image area -->
<div class="neo-skeleton neo-skeleton-title"></div>  <!-- heading -->
<div class="neo-skeleton neo-skeleton-text"></div>   <!-- body line -->
<div class="neo-skeleton neo-skeleton-avatar"></div> <!-- circle -->
<div class="neo-skeleton neo-skeleton-btn"></div>   <!-- button -->

Avatar

HTML
<!-- Sizes: sm | md | lg | xl -->
<div class="neo-avatar neo-avatar-md">MJ</div>
<div class="neo-avatar neo-avatar-md neo-avatar-brand neo-avatar-online">AB</div>

<!-- Group (overlapping) -->
<div class="neo-avatar-group">
  <div class="neo-avatar neo-avatar-md">A</div>
  <div class="neo-avatar neo-avatar-md">B>C</div>
  <div class="neo-avatar neo-avatar-md">+3</div>
</div>

Keyboard Badges

HTML
Press <span class="neo-kbd">⌘ K</span> to search.
Save with <span class="neo-kbd">⌃ S</span>.
Dismiss with <span class="neo-kbd">Esc</span>.

Gaming Utilities

⚡
Gaming utilities require the small JS helper functions from neo.js. Copy them from the showcase source or the GitHub repo.
neoShake() — camera shake toggleGlitch() — glitch text neoAchievement() — toast neoComboHit() — combo counter neoParticles() — burst neoFlash() — screen flash neoTypewriter() — typewriter startCharge() — charge button XP / HP / MP bars Scanlines overlay Leaderboard ✦ Rarity item cards ✦

MIT License · GitHub · Showcase · llms.txt