G:/My Drive/LoF/design-system · rebuilt from Figma exports

Foxbet Design System — Component Library

Every component and foundation in the Foxbet system, rendered live in the system's own tokens. Interactive components show all five states on both a light and a dark surface, because several variants are defined per-surface rather than per-theme.

Roboto / Roboto Mono Primary #FD3A01 Radius 8px 1200 / 768 / 360 WCAG 2.1 tracked
foundations/colors.md

Color ramps

Seven full 50→950 ramps. Contrast ratios are as recorded in the Figma export (against white or black per the source), with the AA/AAA grade the source assigned.

Selected working set

The curated subset the product actually builds from — when a spec says "Error" with no step, it means these.

Text colors

foundations/colors.md → gradients.png

Gradients

Brand gradients carry emphasis; ranking gradients encode podium position. Prim-Sec 90° is the Primary button fill, and Prim-Prim is its hover — the hover flattens the gradient rather than darkening it.

foundations/typography.md

Typography

Roboto for everything, Roboto Mono for numbers, odds, prices and timers. Mobile is generally one step smaller; H5, H6, body, small and tiny hold at both breakpoints.

Weights

Unconfirmed in the export: line-height and letter-spacing. This page uses the documented defaults — headings 1.25 / −0.01em, body 1.5, labels 1.4.

Font loading: this page loads Roboto and Roboto Mono (weights 400/500/600/700) from Google Fonts, so the type below renders at the real specified metrics. Self-host the woff2 files in production.

foundations/spacing.md

Spacing

16px base, named by the 4px multiple (name = px ÷ 4), so the scale skips 7, 9, 11 and so on. Only these steps exist — no arbitrary spacing.

foundations/effects.md

Radius, shadow & blur

Default radius is 8px, but buttons and tags use the pill. The focus ring — Primary at 40%, 2px spread — is the one shadow that is not decoration: every interactive element in this library uses it.

Border radius

Box shadows

Blur — 0 · 4 · 8 · 16 · 32 · 40px, layer and backdrop

backdrop-filter: blur(8px) — Medium
foundations/grid.md

Grid & layout

Three grids, one page skeleton: Header → (Main + Sidebar) → Footer. Desktop puts main and sidebar side by side at roughly 3:1; tablet and mobile stack them.

Open item from the source: the desktop Main : Sidebar split is estimated at 3:1 from the export and still needs confirming.

components/buttons.md · colors.md → button colours.png

Buttons

16 variants × 5 sizes × 5 states, all on the pill radius. Variants are defined per surface, not per theme — "Secondary Light" means the variant used on a light surface — so each state grid below is shown on both grounds.

Variants × states

Light surface · #FFFFFF
Dark surface · #1A1A1A

Per-variant color tokens

Sizes

Desktop · label maps to the type scale
Mobile · height locked to 33px

Deliberate deviation: mobile action and CTA buttons are a fixed 33px tall — below the 44px touch-target guideline. Horizontal padding and font size are preserved and the label stays vertically centred. Desktop is unaffected. Treat this as a known, accepted brand choice rather than a bug to fix.

Content arrangements

Icon first · icon last · icon only · loader · text only

Usage rules

The single-primary rule. One Primary button per screen or per distinct section — modal, sidebar, card. Supporting actions drop to Secondary or Tertiary so the main action is unmistakable. The exception is high-conversion contexts: special offers, sign-up flows, and betting odds rows may carry several equally urgent CTAs.

Pairing and color-blind safety. Never place two Primary buttons side by side. Pair a Primary with a Secondary or Tertiary, and let fill plus contrast — solid against outlined — carry the hierarchy, so the primary action is identifiable without perceiving color at all.

Correct — Primary + Tertiary
Incorrect — two Primaries side by side
components/buttons.md → related controls

Button-sheet controls

Four small controls that ship on the same Figma sheet as the buttons and inherit its tokens.

Light

Spinning loader

Live beam

Live

Add to favourites — default / active × solid / gradient

Arrow button — solid / gradient / ghost

Dark

Spinning loader

Live beam

Live

Add to favourites — default / active × solid / gradient

Arrow button — solid / gradient / ghost

components/tabs.md

Tabs

Two types, and the choice is structural rather than cosmetic: Pill for primary navigation with only a few tabs, Rectangle for secondary and sub-navigation with many. Corner radius and size carry the hierarchy — not color.

Pill · primary nav · few tabs · active = Sec-Tert gradient
Rectangle · sub-nav · visibly smaller
Rectangle · many tabs · active = Prim-Sec gradient

Tabs above are live — click to move the active state. The last one is disabled.

components/checkbox-radio.md

Checkbox & radio

Checkbox for one-or-more from an independent set, or a single on/off that needs submitting. Radio for exactly one from mutually exclusive options. Both put the label on the right, and both are the full component — input, primary label, helper text, error message.

State grid

Light surface
Dark surface

Full component anatomy

Checkbox · input + primary + helper
Checkbox · error state
Radio group · exactly one
components/pill-toggle.md

Pill toggle

A switch applies instantly — no Save. If the change cannot take effect immediately, the component is wrong: use radios or a single checkbox instead.

Labelling. One or two words, preferably a noun, describing what the control does when it is on — never a neutral restatement of the setting. Label sits to the left of the toggle.

Sizes & arrangements

Pill last (label left) · large & small
Pill first · with helper text

State grid

Light surface
Dark surface
components/tags.md

Tags & badges

Eight variants, each in Large and Small, most carrying a leading clock or medal icon. Offer Special is the highest-emphasis badge in the system — brand gradient plus medal — so it only belongs on genuinely top-ranked content.

Light surface · Large then Small
Dark surface · Banner Tag is the dark-surface variant of Offer
components/odds-cta.md · rendered from lib/odds-cta/*.css

Odds CTA — 5 variants (ART-378)

Five variants in two families that share no CSS. The neutral family (V1–V3, .modd*) keeps the odd on a neutral surface and names the operator, so a mixed row still reads as comparable. The brand-fill family (V4/V5, .bodd*) makes the operator's colour the whole surface, which reads as endorsement — use it where one operator is featured. Everything below renders from the library CSS, not from a copy in this file.

Which variant is a commercial decision, not a design one. Neutral comparison (V1/V3) vs. sponsorship (V2) vs. endorsement (V4/V5) — nothing in the code reveals which arrangement applies. Always ask before placing one.

V1 · standalone · no operator named, no 21+ line

Replaced 2026-07-30. White 41px card, radius 8, a 1px hairline between label and odd. Width hugs — 88.67px is a floor, not a cap, so the longer markets still fit. Last card is suspended.

V2 · sponsored · the same operator on every card
21+ · Παίξε υπεύθυνα
V3 · best odds · operator varies per selection — ships on /analysis
21+ · Παίξε υπεύθυνα

Tile height is a hard 36px at every width — never aspect-ratio, or a wider card grows a taller tile and the row's baseline breaks. Interwetten's light tile carries .is-lt. Width steps at the divider, per market.

V4 · brand pill · inline, 40px, fluid width
21+ · Παίξε υπεύθυνα

Light fills take .is-lt and must swap the logo to plain-dark/. Interwetten's stacked mark also needs .is-icon.

V5 · brand block · stacked, 100 × 68px fixed
21+ · Παίξε υπεύθυνα

V4/V5 carry no selection label — the market must be captioned outside the control, and title/aria-label is mandatory.

This section renders from the library. .modd* and .bodd* are served from lib/odds-cta/*.css, a generated mirror of foxbet-components — no component CSS is inlined in this file any more. The page only bridges token names, scoped to this section. Resync instructions are in lib/README.md.

Sportingbet is blocked in V4/V5. Its #1E87C9 fill scores 3.91:1 with white ink and 4.45:1 with dark ink — the 16px bold odd is 12pt, so it needs 4.5:1 and no ink colour passes. Its plain-light export is also not white. Betsson and Vistabet looked like the same problem but are cleared by .is-lt.

Brand colour lives in two places and they must agree. Each rectangle asset bakes in its own background but cannot stretch, so on any card wider than 72px the colour continues in CSS via --bk. The class suffix must match the asset filename exactly — a mismatch shows as a visible seam at the logo's edge.

Single-primary does not apply here. The outcomes in a market are equally urgent, which is exactly the high-conversion exception the button rules carve out.

Retired — do not reintroduce. The dark #1A1A1A stacked card with a win-probability %, the .modd-rail / .modd-brand wordmark caption, and .modd.op-<operator> card tinting — all of which this page was still showing until 2026-07-30. The old V1 (uniform 100×36, #F2F2F2, Roboto Mono odd in #CB2F01) went with them.

foundations/colors.md → regulatory · grid.md → footer

ΕΕΕΠ regulatory row

Required on gambling content under the 2023 Hellenic Gaming Commission guidelines. White text on navy #1A3362, or plain where a background would fight the layout.

Compact label · on navy and plain
ΕΕΕΠ | 21+ | ΠΑΙΞΕ ΥΠΕΥΘΥΝΑ
ΕΕΕΠ | 21+ | ΠΑΙΞΕ ΥΠΕΥΘΥΝΑ
Full footer row
21+ | ΑΡΜΟΔΙΟΣ ΡΥΘΜΙΣΤΗΣ ΕΕΕΠ | ΚΙΝΔΥΝΟΣ ΕΘΙΣΜΟΥ & ΑΠΩΛΕΙΑΣ ΠΕΡΙΟΥΣΙΑΣ | ΓΡΑΜΜΗ ΒΟΗΘΕΙΑΣ ΚΕΘΕΑ: 210 9237777 | ΠΑΙΞΕ ΥΠΕΥΘΥΝΑ

Also needs the ΕΕΕΠ and 21+ marks as image assets — same missing-SVG gap as the odd CTA.

This copy is out of date, and there are open tickets on it. The footer row transcribed above still names ΚΕΘΕΑ. GR-5563 (“All iGaming sites | Change the Footer Text from ΚΕΘΕΑ to ΕΟΠΑΕ”) changes that, and GR-5907 — now Canceled — reported that the central ΕΕΕΠ band in the new Foxbet footer was not implemented to specification and that Foxbet was the only site still showing ΚΕΘΕΑ. Do not ship this string as written; confirm the current regulator-approved wording, then correct foundations/grid.md at the same time.

MASTER.md → components table

Input fields

Not specified — Figma export pending

Text, select, stepper, search and PIN inputs are named in the system with the state matrix they need — default, focus, error, disabled across light and dark — but no tile has been exported, so there are no real dimensions, padding, or border tokens to build from. Nothing is rendered here on purpose: inventing an input now would put un-reviewed values into the system and they would be copied before the real export lands.

To unblock: export the input-fields sheet from Figma, transcribe it to design-system/components/inputs.md, then add the section here. The newsletter signup in the footer is the first thing waiting on it.

components/social-media.md · assets/flags.md · assets/logos.md

Social icons & flags

Both are real components, but both are pure asset-delivery: the spec is the variant matrix, and the content is an SVG file per channel or country. None have been exported individually yet, so these are documented rather than rendered — substituting emoji or typed text for a brand mark is explicitly forbidden by the system.

Social icons — 5 display styles, one style per context, never mixed in a row

Curated channel list: Instagram · X · Facebook · YouTube · TikTok · Telegram · WhatsApp · LinkedIn · Spotify · Discord · Twitch. The footer uses the first six. The wider catalog runs to 26 channels in four styles.

Flag icons — 6 display variants

Round flag chips get a thin white ring and object-fit: cover. Name files by lowercase ISO-3166 alpha-2 — gr.svg, gb.svg.

foundations/bookmaker-colors.md

Bookmaker palettes

Seventeen operator palettes, 500 being the headline brand colour. Use one only when featuring that bookmaker — branded buttons, accents, odd CTAs — and keep the Foxbet system for layout and structure.

Steps 100, 400, 600 and 900 are absent from the source export; interpolate if one is ever needed. A #D9D9D9 in the Secondary or Tertiary column means no distinct accent is defined for that brand, not a real grey. For some red and orange brands the brighter 300 step matches the actual logo better than 500 — check the logo before picking the accent.

this deliverable

Coverage & gaps

What is rendered live on this page, what is documented only, and what each gap is waiting on.

Open items carried over from the source docs

  • Confirm line-height and letter-spacing — not in the typography export.
  • Confirm whether the mobile breakpoint is the 1199px or 1200px boundary.
  • Confirm the desktop Main : Sidebar split, estimated at 3:1.
  • Export the Foxbet site logo as SVG, then the featured bookmaker logos.
  • Decide which social, payment and broadcaster sets v1 actually needs, then export those.
  • Source a dark-text Foxbet wordmark to unblock a light-surface odd CTA.
  • Export the input-fields sheet — currently the largest hole in the system.
  • Resolve the ΚΕΘΕΑ / ΕΟΠΑΕ footer wording and correct grid.md.
  • Reconcile the four Secondary button entries — "Secondary Light/Dark" name the surface while "Secondary White/Black" name the fill, and the two pairs overlap.