ID:AG-0x02 · v2.3 · style.rogues.nexus System nominal

Anti-gravity

by any means.

アンチグラビティ

A neo-cyberpunk stylesheet for websites, dashboards and small tools. One file, no framework, no build step. Link it, add one class, and plain HTML picks up the look; the .ag-* classes on this page add the rest.

Every example below is live. Its label is the class that draws it; open Code under any example for markup you can copy. The theme and highlight controls in the bar restyle the whole page.

00 Getting started

Five minutes from a blank page to a working layout.

01

Link the stylesheet

Add this to the <head> of every page. The /v2/ file updates in place with fixes and new elements, and never with changes that break your markup.

<link rel="stylesheet" href="https://style.rogues.nexus/v2/anti-gravity.css">
02

Set the theme, the highlight and the body class

data-theme and data-accent go on <html>; class="ag" goes on <body> and switches the styles on.

<!doctype html>
<html lang="en" data-theme="dark" data-accent="signal">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Example Site</title>
  <link rel="stylesheet" href="https://style.rogues.nexus/v2/anti-gravity.css">
</head>
<body class="ag">
  <header class="ag-shell">
    <a class="ag-display" href="/">Example</a>
    <nav aria-label="Main">
      <ul class="ag-linkline">
        <li><a href="/" aria-current="page">Home</a></li>
        <li><a href="/projects/">Projects</a></li>
      </ul>
    </nav>
  </header>
  <main class="ag-shell">
    <article class="ag-prose">…</article>
  </main>
</body>
</html>
AttributeValuesNotes
data-themedark · lightLeave it off to follow the device setting.
data-accentsignal · neon · jensen · 2077 · hack · gibsonSignal red is the default. Use one per site.
class="ag"on <body>Without it nothing is styled, so the stylesheet can sit beside other CSS safely.
03

Write plain HTML, then add components

Headings, paragraphs, links, lists, quotes, tables, forms, details, dialog, progress and meter are styled with no classes. Wrap long text in .ag-prose, lay pages out with .ag-shell, .ag-grid, .ag-stack and .ag-row, and reach for the components below when you need them.

One rule to remember: a plain <button> or <code> is only styled automatically when it has no class. If you give one a class for scripting, add .ag-btn to the button as well.

04

Mark state for people and screen readers

The stylesheet draws state from accessibility attributes, so the look and what assistive tech announces always agree.

AttributeUse it onEffect
aria-current="page"Nav, link line, menu and pager linksHighlights the current page.
aria-pressedToggles, filter menus, button groupsFills the active item with the highlight.
aria-selectedTabsUnderlines the selected tab.
aria-disabled="true"Pager linksDims a step you can't take.
aria-labelIcon-only buttons, each <nav>Names things that have no visible text.
aria-hidden="true"Hazard tape, barcodes, metersHides decoration from screen readers.
05

Optional: a custom highlight, self-hosted fonts and a load check

A custom highlight needs three shades. The colour picker in the Colour section works them out for any colour you choose.

:root {
  --ag-accent-dark:  #7CFF4F;  /* on Void */
  --ag-accent-light: #4EA132;  /* on Bone: fills and large text, 3:1 or more */
  --ag-accent-deep:  #3E7F27;  /* small text on Bone, 4.5:1 or more */
}

Fonts load from Google Fonts through an @import at the top of the stylesheet. To keep visitors off Google, serve Michroma, Chakra Petch, Share Tech Mono, Audiowide and Noto Sans JP (900) yourself and remove that line in your own copy.

The stylesheet ends with a marker, so a page can tell whether the whole file arrived:

if (!getComputedStyle(document.documentElement).getPropertyValue('--ag-loaded').trim()) {
  console.warn('anti-gravity.css did not load completely');
}

01 Colour

Surfaces and text flip with the theme. The highlight is the only colour you swap; status tones stay fixed.

--ag-bg
--ag-plate
--ag-ink
--ag-secondary
--ag-muted
--ag-rule
--ag-idle
--ag-accent
--ag-accent-text
--ag-ok.ag-text-ok
--ag-warn.ag-text-warn
--ag-danger.ag-text-danger
--ag-info.ag-text-info
data-accent="signal | neon | jensen | 2077 | hack | gibson"

Set on <html>. One highlight per site. Signal, Neon and Jensen look the same on both grounds; Hack and Gibson darken on Bone; 2077 is yellow on Void and turns grey on Bone.

Custom highlight: --ag-accent-dark, -light, -deep

Pick a colour to preview it. The --ag-accent and --ag-accent-text readouts above show the shades to copy into the three variables (see step 05).

02 Type

Wide display type for headings and key data, Chakra Petch for reading, mono for codes and labels.

Headings need no classes. Use .ag-value for readouts, with the unit in .ag-unit, and .ag-label for the small grey text above them. Never set a headline that runs to two lines in the wide face; use h4. Taglines (.ag-slogan) are lowercase and end with a full stop. Use one katakana word (.ag-kana) per screen.

h1

Signal lost

h2

Built for the night shift

h3

Section heading

h4

Readable sub-heading in Chakra Petch

h5 · h6
Overline label
Small overline
.ag-display--xlOverride
.ag-value--xl .ag-unit940Mb/s
.ag-value--accent1.84TB
.ag-textBody copy for summaries and descriptions. Keep lines short and plain.
.ag-label · .ag-code
Uplink statusSTATUS: NON-COMPLIANT
.ag-slogan · .ag-kana
trust no firmware.シグナル
.ag-kana--inverse · --ink
アンチグラビティアンチグラビティ
.ag-glowGlow (dark only)
.ag-prose · --left · --center · --right · --full

Wrap articles and long text. Adds vertical rhythm and a 70-character measure; everything inside is plain HTML. The column sits left by default: --center and --right move it, and --full fills the space with a 16px gutter each side (a plate keeps its own padding). Change the measure with --ag-prose-width and the full-width gutter with --ag-prose-gutter.

Owning your stack

Self-hosting is a choice about who holds the keys. Links look like this, and you can mark a phrase, use an CSS, show old new text, or press Ctrl + K. Inline code reads as npm run build.

  • Unordered lists use a chevron marker
  • Nested lists keep the rhythm
    • Like this one
  1. Ordered lists count with zero padding
  2. Numbers sit in mono, in the highlight colour
The street finds its own uses for things. Overheard at a swap meet
Host
node-01
Uptime
41 days

03 Code & terminal

Code always sits on void, in both themes. Works with highlight.js and Prism class names, or hand-written .tk-* spans.

.ag-codeblock > .ag-codeblock__head + pre

Code always sits on Void. highlight.js and Prism output is coloured automatically; for hand-written snippets use .tk-key, .tk-str, .tk-num, .tk-fn, .tk-var and .tk-com. You wire up the copy button.

fetch_status.py
# List the services running in a region
import requests

API = "https://api.example.com/v1/status"
TIMEOUT = 10

def services(region):
    r = requests.get(API, params={"region": region}, timeout=TIMEOUT)
    return [s["name"] for s in r.json()["services"]]
pre (plain)

A plain <pre><code> gets the same block without the header.

$ systemctl status nginx
● nginx.service - Web server
   Active: active (running)
.ag-prompt + .ag-cursor

A terminal prompt line. Change the marker with --ag-prompt. The cursor stops blinking when the device asks for reduced motion.

ssh user@node-01

tail -f /var/log/app.log

.ag-log > .ag-log__line > .ag-log__level.ag-tone-*

Timestamped terminal lines. Levels take a tone: info, ok, warn or danger. Messages state facts plainly.

INFOConnected to api.example.com
OKSynced 148 records in 2.1 s
WARNRequest timed out, using cached copy
ERRDatabase unreachable on 192.0.2.40

05 Buttons, tags & toggles

Square edges, wide caps. Anything at rest in light mode sits in void with bone text; active takes the highlight.

.ag-btn · --accent · --primary · --danger · --ghost · --slant · :disabled · .is-loading

One --primary per view. Labels are verbs, one to three words. --slant needs its label in a child <span>; .is-loading shows a busy state.

--sm · --lg · --icon · .ag-btn-group

Sizes and shapes. Give every --icon button an aria-label. .ag-btn-group joins toggle buttons that use aria-pressed.

button (no class) · input[type=submit|reset]

Unclassed buttons and submit or reset inputs get the default look automatically.

.ag-tag · --outline · --text · --slant · .ag-tone-*

Filled in the highlight by default. A .ag-tone-* class makes it a status tag and adds its glyph automatically (✓ ! ✕ i). --outline, --text and --slant change the weight; --slant needs a child <span>.

Lead Online Degraded Breach Update Featured Hot Archive
.ag-status · --off · --pulse · .ag-tone-*

A square lamp and a word that states the condition. Tone it with .ag-tone-*, grey it with --off, blink it with --pulse. Danger lamps always blink.

Stream live Backup done Low disk Offline
.ag-toggles > .ag-toggle[aria-pressed]

On/off tiles for dashboards and control panels. Your script updates aria-pressed and the state text.

06 Forms

Plain form elements are styled with no classes. The .ag-* versions do the same job when you need classes on them.

.ag-field · .ag-input-group · .ag-field__hint · .ag-field__error

Put each control in an .ag-field with a <label>, and add a hint or an error under it (link an error to its input with aria-describedby). .ag-input-group adds a prefix or suffix. Unclassed inputs, selects and textareas are styled automatically; .ag-input, .ag-select and .ag-textarea do the same when you need classes.

$
.ag-input-group + __addon
input[type=password]
Enter an address like name@domain.tld
input[type=search]
select
input[type=date]
input[type=number]
:disabled
textarea
fieldset · label.ag-check · .ag-checkbox · .ag-radio · .ag-switch · .ag-range

Checkboxes are squares, radios are diamonds and switches are slanted bars (role="switch" or .ag-switch). Wrap each control and its text in label.ag-check, stack them in .ag-choices and group them in a fieldset. Controls that are off are Void with Bone in light mode.

Checkboxes
Radios
Switches
Range, file, colour
Accent

07 Feedback

Alerts and toasts take a status tone. Progress bars are segmented; a bar with no value runs hazard stripes.

.ag-alert.ag-tone-* > .ag-alert__body

Inline messages with a hazard edge in their tone; the title gets the status glyph automatically. The title is two or three words, the text says what happened and what to do. Use role="alert" only for danger and role="status" otherwise.

Update readyVersion 2.3 adds prose placement: left, centre, right and full width.
Backup completeSnapshot saved to the NAS at 03:00.
Certificate expiringRenews in 6 days. Check the DNS record if it fails.
.ag-toast.ag-tone-* (click to send one)

Brief confirmations. Stack them in a fixed .ag-toast-stack and remove each after about 4.5 seconds. The title repeats the action: SAVE becomes SAVED.

SavedYour settings are live.
dialog.ag-dialog

A native <dialog> opened with showModal(); Esc closes it. Put the safe action first and the destructive one last.

.ag-progress > progress

A native <progress> drawn as a segmented bar. Leave out value for an indeterminate stripe.

Download75%
Upload100%
Indexing…
meter (low / high / optimum)

A native <meter>. Segments turn ok, warn or danger according to low, high and optimum.

CPU12%
Memory68%
Disk92%
.ag-spinner · .ag-meter

The spinner is for short waits; give it role="status" and an aria-label. .ag-meter is a decorative segmented bar: light segments with .is-on and state the number in text.

Awaiting input
details (plain) inside .ag-accordion

Plain <details> elements, grouped in .ag-accordion. No script needed.

What is Anti-Gravity?

A stylesheet with a neo-cyberpunk look. No framework and no build step.

Does it need JavaScript?

No. Tabs, toasts and the theme switch on this page use a little script, but every style works without it.

Can I change the colours?

Set data-accent on the html element, or set your own with --ag-accent-dark, --ag-accent-light and --ag-accent-deep.

08 Data

Tables use mono headers over a highlight rule. Cards hold one big wide number each.

.ag-table-wrap > .ag-table (plain table looks the same)

Wrap tables in .ag-table-wrap so they scroll on phones. Right-align numbers with .ag-num and show state with a lamp. --striped and --compact suit dense data.

Services on node-01
IDNameStatusCPUMemory
101webRunning2.4%128 MB
104databaseRunning12.8%512 MB
107workerIdle0.1%64 MB
112cacheStopped0.0%0 MB
Total15.3%704 MB
.ag-brackets > .ag-plate

The hero panel, with two cut corners, for the one to three headline readings on a screen. .ag-brackets frames it.

ThroughputNET-01
940Mb/s
Peak
1.2 Gb/s
Latency
8 ms
.ag-card + .ag-meter

The standard tile: one job, one hero number. Only the single most important number on a screen takes .ag-value--accent.

Storage usedST-02
1.84TB
Of 3.00 TB
.ag-card + .ag-hazard--thin

Countdowns and warnings: a toned text tag, the value, then thin hazard tape while the clock runs.

MaintenanceMW-03
Window opens in
03:12

09 Patterns & devices

Bigger pieces built from the parts above, plus the small marks that give the system its edge.

.ag-brackets > .ag-plate > .ag-lead

A lead article: a numbered plate with a wide headline. .ag-display--md suits a headline of up to two lines.

Featured · Design[AUTHOR] · 05:41
01

One stylesheet, no framework, and nothing to install

How a single CSS file covers type, forms, navigation and data, and why it stays that way.

Read more ▸
.ag-card.ag-story

Article or post lists in an .ag-grid. Headlines use Chakra Petch, never the wide face.

The devices below are decoration: use one or two per screen and give each aria-hidden="true". Code stamps (.ag-code) label real things, never filler.

.ag-hazard
.ag-hazard--thin
.ag-barcode
.ag-brackets--accent
Framed
.ag-divider-label
End of transmission
.ag-divider · hr

Versions

Each major version lives in its own folder. Fixes and new elements go into the current folder in place, so every site linking to it updates within minutes. Anything that would break existing markup ships as a new folder instead.

FolderLatestStatusStylesheetRelease notes
/v2/2.3 · 16 Oct 2026Currentv2/anti-gravity.cssWhat changed in v2
Wipe cache?
This clears 148 cached items. The next load fetches everything again, which takes about a minute.