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