OGE logoOGE

Style the app

Components never hardcode visual values — everything renders through --oge-* CSS design tokens. Override a token globally to restyle the whole suite, scope it to a container for local skins, or let a bridge theme align every component with the CSS framework you already use.

--oge-* tokens bridge themes dark mode high contrast color

Design tokens

Shared across every render layer. The tokens, the theme stylesheets and the component class names are one stylesheet compiled from one source — the React components render the same .oge-* classes the Angular ones do. Everything on this page applies unchanged whichever framework you picked in the header. The only difference lives on the setup page: React imports the stylesheet once at the app entry, Angular ships it inside the components.

Tokens are plain CSS custom properties. Set them on :root (or any stylesheet you already own) — no build step, no theme API, live at runtime. The defaults sit at zero specificity, so a plain :root rule wins wherever your stylesheet loads:

/* One override restyles every component consistently. */
:root {
  --oge-accent: #4f46e5;      /* selection, focus, primary actions      */
  --oge-radius-lg: 10px;      /* cards, popups, buttons                 */
  --oge-row-height: 32px;     /* grid & tree-list row density           */
  --oge-input-width: 240px;   /* default editor width                   */
  --oge-header-bg: #eef2f8;   /* grid header surface                    */
}

The suite covers surfaces, text, accent and severity colors, radii, row and control heights, focus rings, shadows, scrollbars and popup layering. Tints derive from their base token — set --oge-accent on :root and the soft accent, the focus ring and the focused row follow it. Use the Theme selector in the top bar to see token remapping live on every example in these docs.

Scoped overrides

Because tokens cascade like any CSS custom property, an override applies to exactly the subtree you set it on — perfect for dense dashboards, embedded widgets or one-off exceptions:

/* Tokens cascade — scope them to re-skin a single area. */
.compact-dashboard {
  --oge-row-height: 26px;
  --oge-radius-lg: 6px;
}

/* Or a single component instance */
.danger-zone oge-button {
  --oge-accent: var(--oge-danger);
}

Bridge themes

A bridge theme is a small CSS file that assigns your framework's variables to the OGE tokens. Import it once and every component picks up your palette, radii and densities — remove it and the neutral default returns:

/* Bridge themes map --oge-* tokens onto your framework's variables,
   so components automatically follow your existing design system. */
@import '@oge-ui/core/themes/tailwind.css';   /* Tailwind v4  */
@import '@oge-ui/core/themes/bootstrap.css';  /* Bootstrap 5  */

Dark mode

Dark mode is a token remap behind the .oge-theme-dark class (or data-oge-theme="dark") — it composes with bridge themes and scoped overrides. data-oge-theme="auto" follows the operating system's prefers-color-scheme, and .oge-theme-light marks a light island inside a dark page. The rules target the scope element, not a list of components, so popups portalled to <body> follow a themed <html>:

/* Import once, then pick a scope — <html> for the whole app or any
   subtree for a mixed page. Ships in @oge-ui/core, which every OGE
   package installs (with pnpm or Yarn PnP, add @oge-ui/core directly). */
@import '@oge-ui/core/themes/dark.css';
<!-- whole application: a class or the attribute form -->
<html class="oge-theme-dark">
<html data-oge-theme="dark">

<!-- follow the operating system's light/dark setting -->
<html data-oge-theme="auto">

<!-- or a single region — and a light island inside a dark page -->
<section class="oge-theme-dark">
  <oge-grid [data]="rows" />
  <aside class="oge-theme-light">…</aside>
</section>

High contrast & motion

The high-contrast theme is a scoped token remap like dark mode, behind .oge-theme-high-contrast (or data-oge-theme="high-contrast"): black text on white, a deep accent, borders instead of soft shadows and a solid focus ring — body text at 7:1 or more, borders and rings at 3:1 or more.

/* An author-side high-contrast palette: text >= 7:1, borders and focus
   rings >= 3:1, a solid focus ring. Import once, then pick a scope. */
@import '@oge-ui/core/themes/high-contrast.css';
<html class="oge-theme-high-contrast">
<html data-oge-theme="high-contrast">

<!-- or one region only -->
<section class="oge-theme-high-contrast">
  <oge-grid [data]="rows" />
</section>

Whatever theme is loaded, the components also follow the operating system. Under Windows High Contrast (forced-colors: active) selection, focus, checked and disabled states switch to the system colours (Highlight, CanvasText, GrayText…), state never rides on a background colour alone, and the keyboard focus ring stays visible. Under prefers-reduced-motion: reduce transitions, animations and smooth scrolling are switched off. Small grips — resize handles, gantt link dots, close buttons — keep a pointer target of at least 24×24px, and 44px on touch screens. There is nothing to configure.

Component colors

For per-instance color, buttons accept a semantic severity — or an arbitrary color when your brand needs something outside the semantic set:

<!-- Semantic severities cover most cases… -->
<oge-button text="Save" severity="success" />
<oge-button text="Delete" severity="danger" stylingMode="outlined" />

<!-- …and any CSS color works for brand-specific accents; hover and
     soft tones are derived automatically. -->
<oge-button text="Brand action" color="#7c3aed" />
<oge-button text="Teal outline" color="teal" stylingMode="outlined" />