gitlab-admin-ui
skills/gitlab-admin-ui/
references/tokens.css
@import "tailwindcss";
/* ────────────────────────────────────────────────────────────────────────
GitLab-style dark admin tokens.
Vibe: dense, technical, monospace accents. Orange used sparingly for
primary actions and the logo only. No gradients, no shadows beyond a
faint one under the top bar.
──────────────────────────────────────────────────────────────────────── */
@theme {
/* ── Surface (dark stack) ─────────────────────────────────────────────
Near-black background, slightly lighter panels, a "raised" tone for
menus and the inspector. Pick a fourth tone and the depth flattens. */
--color-surface-0: #1a1d23; /* base background */
--color-surface-1: #16181d; /* panel - sidebar, status bar */
--color-surface-2: #21252d; /* raised - context menu, hover */
--color-surface-3: #2b2f38; /* extra-raised - kbd chips, badges */
/* Hairline border - the only visible separation between panels. */
--color-divider: #2b2f38;
--color-divider-2: #353a44; /* subtle stronger hover/active */
/* ── Text ─────────────────────────────────────────────────────────────
Primary text is almost-white but never pure; muted is the technical
gray for paths, timestamps, second-class metadata. */
--color-ink-primary: #e4e6eb;
--color-ink-secondary: #b3b7c0;
--color-ink-muted: #8b919e;
--color-ink-faint: #5e6471;
/* ── Brand ────────────────────────────────────────────────────────────
GitLab orange - used for the logo, primary buttons, active row left-
borders, focus rings. Never on body text or backgrounds (it's loud). */
--color-brand: #fc6d26;
--color-brand-hover: #ff7e3a;
--color-brand-soft: #fc6d2614; /* 8% - for selected-row tint */
--color-brand-ring: #fc6d264c; /* 30% - for focus rings */
/* ── Accents (state) ──────────────────────────────────────────────────
Used in status dots, toasts, file-type icons, delete-on-hover red. */
--color-success: #22c55e;
--color-success-soft: #22c55e1f;
--color-danger: #ef4444;
--color-danger-soft: #ef44441f;
--color-warning: #f59e0b;
--color-warning-soft: #f59e0b1f;
--color-info: #38bdf8;
--color-info-soft: #38bdf81f;
/* ── File-type icon tints ─────────────────────────────────────────────
Maps to the spec: .tsx blue, .json amber, .md gray, .env red. */
--color-file-tsx: #38bdf8;
--color-file-json: #f59e0b;
--color-file-md: #8b919e;
--color-file-env: #ef4444;
--color-file-css: #a78bfa;
--color-file-default: #b3b7c0;
/* ── Type ─────────────────────────────────────────────────────────────
Inter for prose, JetBrains Mono for paths, SHAs, sizes, timestamps in
detail views. Both load via next/font in layout.tsx. */
--font-sans: var(--font-inter), -apple-system, BlinkMacSystemFont,
"Segoe UI", Helvetica, Arial, sans-serif;
--font-mono: var(--font-mono), ui-monospace, "JetBrains Mono",
"SF Mono", Menlo, Consolas, monospace;
/* ── Spacing ──────────────────────────────────────────────────────────
Dense by design: rows are 26–36px tall, not 48–60px. */
--spacing-row-tree: 26px;
--spacing-row-nav: 32px;
--spacing-row-list: 36px;
/* ── Layout ───────────────────────────────────────────────────────────
Heights/widths called out in the spec. */
--topbar-height: 48px;
--statusbar-height: 28px;
--sidebar-width: 240px;
--sidebar-collapsed: 56px;
--inspector-width: 320px;
/* ── Radius ───────────────────────────────────────────────────────────
Small and consistent. Pills only on kbd chips + search input. */
--radius-sm: 4px;
--radius-md: 6px;
--radius-lg: 8px;
--radius-pill: 980px;
/* ── Motion ───────────────────────────────────────────────────────────
Sharp and fast - this is a technical UI, not a marketing site. */
--ease-snap: cubic-bezier(0.2, 0, 0, 1);
--dur-fast: 120ms;
--dur-base: 180ms;
}
/* ── Light theme overrides ────────────────────────────────────────────
Applied when <html class="light">. Tokens above are the dark defaults;
utilities (bg-surface-0, text-ink-primary, …) re-resolve through these
variables automatically - no class rewrites needed in components. */
html.light {
/* Surface - white base, hairline-separated panels. */
--color-surface-0: #ffffff;
--color-surface-1: #fafafa;
--color-surface-2: #f0f1f4;
--color-surface-3: #e3e5ea;
--color-divider: #e3e5ea;
--color-divider-2: #cdd1d8;
/* Text - near-black primary, progressively lighter grays. */
--color-ink-primary: #1f2329;
--color-ink-secondary: #424854;
--color-ink-muted: #6b7280;
--color-ink-faint: #9aa0ac;
/* Brand stays the same orange - GitLab uses one orange in both modes. */
/* File-type tints - bump the muted/default greys so icons stay legible
on a white background. The accent colors above already work on light. */
--color-file-md: #6b7280;
--color-file-default: #4a5060;
}
/* Smooth surface/ink transition when toggling so the flip isn't jarring. */
html, body {
transition: background-color var(--dur-base) var(--ease-snap),
color var(--dur-base) var(--ease-snap);
}
/* Base resets. */
html {
font-family: var(--font-sans);
color: var(--color-ink-primary);
background: var(--color-surface-0);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
font-feature-settings: "ss01", "cv11", "calt";
color-scheme: dark;
}
html.light {
color-scheme: light;
}
body {
min-height: 100dvh;
overflow: hidden; /* the admin shell manages its own scrolling */
}
/* Faint shadow under the top bar - the only shadow in the whole UI. */
.shadow-topbar {
box-shadow: 0 1px 0 0 var(--color-divider), 0 4px 12px rgba(0, 0, 0, 0.25);
}
/* Active-press feedback - every interactive element gets this. */
.press-feedback:active {
transform: scale(0.98);
}
/* Custom scrollbar for the dark theme. */
.scrollbar-thin {
scrollbar-width: thin;
scrollbar-color: var(--color-divider-2) transparent;
}
.scrollbar-thin::-webkit-scrollbar { width: 8px; height: 8px; }
.scrollbar-thin::-webkit-scrollbar-track { background: transparent; }
.scrollbar-thin::-webkit-scrollbar-thumb {
background: var(--color-divider-2);
border-radius: 4px;
}
.scrollbar-thin::-webkit-scrollbar-thumb:hover {
background: var(--color-ink-muted);
}
/* Focus ring - 2px orange at 30% opacity. Excludes native form fields:
the Input atom wraps inputs in a div whose border already changes on
focus-within, so a second outline on the inner element looks like a
double ring. */
*:focus-visible {
outline: 2px solid var(--color-brand-ring);
outline-offset: 1px;
}
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
outline: none;
}
/* Respect reduced-motion. */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}