Appearance
Theming
gomawt widgets use CSS custom properties (variables) for all visual styling. Every token is prefixed with --goma- and defined on the :host element inside the Shadow DOM. Because inline styles on :host have the highest specificity, consumer overrides always win.
Quick start
js
const el = document.querySelector('goma-events-horizontal')
el.theme = {
highlightPrimary: '#dc2626',
backgroundPrimary: '#1a0505',
buttonBackgroundPrimary: '#dc2626',
}The widget automatically prepends --goma- to each key, so highlightPrimary becomes --goma-highlightPrimary on the host element. All three key formats are accepted:
| Input key | Resolved CSS property |
|---|---|
highlightPrimary | --goma-highlightPrimary |
--highlightPrimary | --goma-highlightPrimary |
--goma-highlightPrimary | --goma-highlightPrimary |
Using config.theme
You can also pass the theme inside the config object:
js
el.config = {
apiBaseUrl: 'https://api.example.com',
theme: {
backgroundPrimary: '#1a0505',
highlightPrimary: '#dc2626',
},
}Both el.theme = {...} and config.theme use the same code path. Setting either one applies the overrides immediately.
Switching themes at runtime (light / dark)
Define your light and dark palettes as two plain JavaScript objects with the same set of keys, then assign whichever one you want — the widget reflects the change on the next paint without a remount, a reload, or a class swap. The reactive bridge picks up el.theme = … immediately and writes the values to inline custom properties on the host, so every Vue component that reads var(--goma-…) updates in place.
js
const lightTheme = {
backgroundPrimary: '#ffffff',
backgroundSecondary: '#f4f5fb',
backgroundCards: '#ffffff',
textPrimary: '#0b0d2a',
textSecondary: '#5a6280',
highlightPrimary: '#ff6600',
buttonBackgroundPrimary: '#ff6600',
buttonTextPrimary: '#ffffff',
separatorLine: '#e2e5f0',
// … cover every token you want to differ between modes
}
const darkTheme = {
backgroundPrimary: '#03061b',
backgroundSecondary: '#161732',
backgroundCards: '#1f2147',
textPrimary: '#ffffff',
textSecondary: '#939dff',
highlightPrimary: '#ff6600',
buttonBackgroundPrimary: '#ff6600',
buttonTextPrimary: '#ffffff',
separatorLine: '#2a2d60',
// … same keys as lightTheme
}
const el = document.querySelector('goma-events-horizontal')
// Apply light mode
el.theme = lightTheme
// Later — flip to dark mode
el.theme = darkThemeReacting to the host's prefers-color-scheme
Wire the system preference once and let the watcher swap themes for you:
js
const mql = window.matchMedia('(prefers-color-scheme: dark)')
function syncTheme() {
el.theme = mql.matches ? darkTheme : lightTheme
}
syncTheme()
mql.addEventListener('change', syncTheme)One important caveat — keep both objects complete
Each el.theme = … call writes the keys of the object you pass; it does not clear keys set by a previous assignment. If lightTheme defines backgroundCards and darkTheme doesn't, the value from lightTheme will linger after the swap.
The safe pattern is to make both objects exhaustive over the tokens you care about. If you must override a single token on top of a base theme, merge explicitly:
js
el.theme = { ...darkTheme, highlightPrimary: '#dc2626' }Token reference
All tokens are defined in src/styles/main.css under the :host block. Each token has a DEFAULT and a -dark variant. Set both for consistent rendering.
Backgrounds
| Token | CSS variable | Default | Description |
|---|---|---|---|
backgroundPrimary | --goma-backgroundPrimary | #03061b | Page / widget background |
backgroundSecondary | --goma-backgroundSecondary | #161732 | Secondary panels, betslip |
backgroundTertiary | --goma-backgroundTertiary | #1f2147 | Cards, inputs |
backgroundBorder | --goma-backgroundBorder | #2a2d60 | Card border backgrounds |
backgroundCards | --goma-backgroundCards | #1f2147 | Card inner background |
backgroundDrop | --goma-backgroundDrop | #03061b | Dropdown overlays |
backgroundOdds | --goma-backgroundOdds | #434799 | Odds button background |
backgroundDisabledOdds | --goma-backgroundDisabledOdds | #2a2d60 | Suspended odds background |
Text
| Token | CSS variable | Default | Description |
|---|---|---|---|
textPrimary | --goma-textPrimary | #ffffff | Primary text (team names, labels) |
textSecondary | --goma-textSecondary | #939dff | Secondary text (competition, time) |
textHeadlinePrimary | --goma-textHeadlinePrimary | #ffffff | Headline text |
textDisablePrimary | --goma-textDisablePrimary | #434799 | Disabled / muted text |
textOdds | --goma-textOdds | #ffffff | Odds value text |
textDisabledOdds | --goma-textDisabledOdds | #434799 | Suspended odds text |
Icons
| Token | CSS variable | Default | Description |
|---|---|---|---|
iconPrimary | --goma-iconPrimary | #ffffff | Primary icon fills |
iconSecondary | --goma-iconSecondary | #5559b4 | Secondary icon fills |
Highlights
| Token | CSS variable | Default | Description |
|---|---|---|---|
highlightPrimary | --goma-highlightPrimary | #ff6600 | Primary accent (CTA, active states) |
highlightSecondary | --goma-highlightSecondary | #404cff | Secondary accent |
highlightTertiary | --goma-highlightTertiary | #01b72e | Tertiary accent (green) |
highlightPrimaryContrast | --goma-highlightPrimaryContrast | #ffffff | Text on primary accent |
highlightSecondaryContrast | --goma-highlightSecondaryContrast | #03061b | Text on secondary accent |
Separators
| Token | CSS variable | Default | Description |
|---|---|---|---|
separatorLine | --goma-separatorLine | #2a2d60 | Divider lines |
separatorLineSecondary | --goma-separatorLineSecondary | #393d83 | Secondary dividers |
Buttons
| Token | CSS variable | Default | Description |
|---|---|---|---|
buttonBackgroundPrimary | --goma-buttonBackgroundPrimary | #ff6600 | Primary button fill |
buttonTextPrimary | --goma-buttonTextPrimary | #ffffff | Primary button text |
buttonActiveHoverPrimary | --goma-buttonActiveHoverPrimary | #ff7e29 | Primary button hover |
buttonBackgroundSecondary | --goma-buttonBackgroundSecondary | #2a2d60 | Secondary button fill |
Live
| Token | CSS variable | Default | Description |
|---|---|---|---|
liveTag | --goma-liveTag | #ff6600 | "LIVE" badge background |
liveBorder1 | --goma-liveBorder1 | #ff6000 | Live card border gradient stop 1 |
liveBorder2 | --goma-liveBorder2 | #ff934c | Live card border gradient stop 2 |
liveBorder3 | --goma-liveBorder3 | #7a83ff | Live card border gradient stop 3 |
liveShadowColor | --goma-liveShadowColor | rgba(235, 92, 104, 1) | Live badge drop shadow |
Live-count badge (sports-navigation)
Used by <goma-sports-navigation-horizontal> for the small pill on the top-right of each sport tile that has numberOfLiveEvents > 0.
| Token | CSS variable | Default | Description |
|---|---|---|---|
liveCountBackground | --goma-liveCountBackground | #ed4f63 | Pill background |
liveCountText | --goma-liveCountText | #ffffff | Number colour |
Both have -dark variants. The badge wraps a 2px --goma-backgroundPrimary ring around the pill so it pops cleanly off the surrounding circle.
Odds-update flash (RegularOdds)
When odds tick up or down on a <RegularOdds> button, the card temporarily highlights with a coloured border + arrow icon. The background during that highlight is controlled by the two tokens below; both default to the resting --goma-backgroundOdds so the card doesn't flash by default — that matches the betsson-france baseline where the only visual cue is the border and the up/down arrow.
| Token | CSS variable | Default | Description |
|---|---|---|---|
oddsUpdateUp | --goma-oddsUpdateUp | var(--goma-backgroundOdds) | Card background while odds are flashing up |
oddsUpdateDown | --goma-oddsUpdateDown | var(--goma-backgroundOdds) | Card background while odds are flashing down |
oddsUpdateUpBorder | --goma-oddsUpdateUpBorder | #21ba45 | 2 px border + ▲ arrow colour while odds are flashing up |
oddsUpdateDownBorder | --goma-oddsUpdateDownBorder | #ed4f63 | 2 px border + ▼ arrow colour while odds are flashing down |
All four have -dark variants. The borders + arrow inherit the alertSuccess / alertError palette by default so the price-change cue stays vibrant against the resting card. The fill stays unchanged unless a theme overrides oddsUpdateUp / oddsUpdateDown.
Alerts
| Token | CSS variable | Default | Description |
|---|---|---|---|
alertError | --goma-alertError | #ed4f63 | Error state |
alertSuccess | --goma-alertSuccess | #21ba45 | Success state |
alertWarning | --goma-alertWarning | #f2c037 | Warning state |
Cards
| Token | CSS variable | Default | Description |
|---|---|---|---|
cardBorderLineGradient1 | --goma-cardBorderLineGradient1 | #393d83 | Card border gradient stop 1 |
cardBorderLineGradient2 | --goma-cardBorderLineGradient2 | #7c4b57 | Card border gradient stop 2 |
cardBorderLineGradient3 | --goma-cardBorderLineGradient3 | #b25633 | Card border gradient stop 3 |
Game details (tab pills + market cards)
Used by <goma-game-details>. Each token falls back to the existing token in parentheses if you don't override it, so a host theme that doesn't know about these still renders consistently.
| Token | CSS variable | Fallback | Description |
|---|---|---|---|
tabPillBackground | --goma-tabPillBackground | --goma-backgroundCards | Inactive market-tab pill fill |
tabPillBackgroundActive | --goma-tabPillBackgroundActive | --goma-buttonBackgroundPrimary | Active market-tab pill fill |
tabPillText | --goma-tabPillText | --goma-textSecondary | Inactive pill text |
tabPillTextActive | --goma-tabPillTextActive | --goma-buttonTextPrimary | Active pill text |
marketCardHeaderBackground | --goma-marketCardHeaderBackground | --goma-backgroundTertiary | Market card header strip background (separates the title row from outcomes visually) |
Miscellaneous
| Token | CSS variable | Default | Description |
|---|---|---|---|
favorites | --goma-favorites | #fac125 | Favorite star colour |
statsHome | --goma-statsHome | #d99f00 | Home team stats |
statsAway | --goma-statsAway | #46c1a7 | Away team stats |
Typography & Shape
| Token | CSS variable | Default | Description |
|---|---|---|---|
fontSize | --goma-fontSize | 13px | Base font size |
scoreRadius | --goma-scoreRadius | 4px | Score box border radius |
Embedding examples
Vanilla HTML
html
<goma-events-horizontal id="sb"></goma-events-horizontal>
<script type="module">
import '@gomagaming/events-horizontal'
const el = document.getElementById('sb')
el.config = { apiBaseUrl: 'https://api.example.com' }
el.theme = { highlightPrimary: '#dc2626', backgroundPrimary: '#1a0505' }
</script>React
jsx
import '@gomagaming/events-horizontal'
function Feed({ config }) {
return (
<goma-events-horizontal
ref={(el) => {
if (!el) return
el.config = config
el.theme = { highlightPrimary: '#dc2626' }
}}
/>
)
}Vue 3
vue
<script setup>
import '@gomagaming/events-horizontal'
import { ref, onMounted } from 'vue'
const el = ref(null)
onMounted(() => {
el.value.config = { apiBaseUrl: 'https://api.example.com' }
el.value.theme = { highlightPrimary: '#dc2626' }
})
</script>
<template>
<goma-events-horizontal ref="el" />
</template>Full theme example
A complete red theme:
js
el.theme = {
backgroundPrimary: '#1a0505',
'backgroundPrimary-dark': '#1a0505',
backgroundSecondary: '#2d0a0a',
'backgroundSecondary-dark': '#2d0a0a',
backgroundCards: '#3d1212',
'backgroundCards-dark': '#3d1212',
backgroundOdds: '#5c1a1a',
'backgroundOdds-dark': '#5c1a1a',
highlightPrimary: '#dc2626',
'highlightPrimary-dark': '#dc2626',
buttonBackgroundPrimary: '#dc2626',
'buttonBackgroundPrimary-dark': '#dc2626',
liveBorder1: '#dc2626',
'liveBorder1-dark': '#dc2626',
liveShadowColor: 'rgba(220, 38, 38, 0.8)',
cardBorderLineGradient1: '#5c1a1a',
cardBorderLineGradient2: '#8b2020',
cardBorderLineGradient3: '#dc2626',
}