05 · Getting started

One file. No build.

tokens.css is plain CSS custom properties — link it, write variables, and both themes come along. If you need the values programmatically, the same tokens ship as tokens.json.

05.2

The contract

The variable contract.

Write variables, never hex. The contract below is what makes a surface "ShiftOps" — break any row and you've left the system. Click a variable to copy it.

VariablesContract
--bg · --bg-elev · --bg-sunken Page, raised panels, recessed wells. Depth comes from these three plus a border — not from shadows.
--line · --line-strong Every border is 1px in one of these two. -strong is the hover/emphasis state.
--fg · --fg-secondary · --fg-muted · --fg-subtle Four ink tiers: headline, dense body, supporting copy, faint labels. Hierarchy by tier, never by opacity hacks.
--accent · --accent-fg · --accent-hover · --accent-soft · --accent-line Primary actions and selected states. The accent is ink — near-black in light, near-white in dark. Do not substitute a brand hue; there isn't one.
--ai · --ai-soft · --ai-line Violet, only where an agent perceives, decides, or acts. Never for links, focus rings, brand moments, or "premium" anything.
--ok · --warn · --danger (+ -soft fills) Real operational states only — filled, trending short, short. Never decoration, never emphasis.
--radius-* · --container Radius steps 4–28px then full; buttons and pills are always full. Content maxes at 1280px.
--shadow-pop · --shadow-cmd The only two shadows: floating chrome and product-mock windows. Everything else is a border.
--ease-out-expo · --dur-* 150ms hovers, 300ms panels, 600ms reveals, 2s live pulses, 40s marquees. Respect prefers-reduced-motion.
05.3

Dark theme

Dark is one attribute.

Set data-theme="dark" on <html> and every token flips. Persist the choice and apply it before first paint so the page never flashes.

<!-- in <head>, before the stylesheets -->
<script>
(function () {
  try {
    var t = localStorage.getItem("shiftops-theme") ||
      (matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
    document.documentElement.setAttribute("data-theme", t);
  } catch (e) { document.documentElement.setAttribute("data-theme", "light"); }
})();
</script>

<!-- anywhere: the toggle -->
<script>
function toggleTheme() {
  var next = document.documentElement.getAttribute("data-theme") === "dark"
    ? "light" : "dark";
  document.documentElement.setAttribute("data-theme", next);
  localStorage.setItem("shiftops-theme", next);
}
</script>
05.4

Starter

A page in the system, in 30 lines.

Everything below the stylesheet link is plain variables. Rendered live on the right of the code — in whichever theme you're reading this.

Deploy · Day of

Gates open in 40 minutes.

Coverage 91%. Two zones trending short.

Club Level · 18/20
<!doctype html>
<html lang="en" data-theme="light">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://design.shiftops.ai/tokens.css">
  <style>
    body { margin:0; background:var(--bg); color:var(--fg);
           font-family:var(--font-sans); }
    .panel { max-width:420px; margin:48px auto; padding:24px;
             border:1px solid var(--line);
             border-radius:var(--radius-2xl); background:var(--bg-elev); }
    .panel p { color:var(--fg-muted); font-size:14px; line-height:1.6; }
    .go { border:0; cursor:pointer; padding:10px 20px;
          border-radius:var(--radius-full); font:500 14px var(--font-sans);
          background:var(--accent); color:var(--accent-fg);
          transition:background var(--dur-fast) ease; }
    .go:hover { background:var(--accent-hover); }
  </style>
</head>
<body>
  <div class="panel">
    <p class="eyebrow">Deploy · Day of</p>
    <h1>Gates open in 40 minutes.</h1>
    <p>Coverage 91%. Two zones trending short.</p>
    <button class="go">Reallocate</button>
  </div>
</body>
</html>