Back to Index
EurekaGO Brand Playbook
12
Web Design
Rules

EurekaGO web design rules — Layout grid, components, states and responsive web UI rules.

Document 12 / 15 Version 1.0 · May 2026 Confidential
Brand Colors

Primary Palette

Primary
#00aeef
Dark
#0090c6
Mid
#40c2f3
Light
#80d7f7
Pale
#cceffc

Bootstrap Semantic Colors

Primary
.bg-primary
Secondary
.bg-secondary
Success
.bg-success
Danger
.bg-danger
Warning
.bg-warning
Info
.bg-info
Light
.bg-light
Dark
.bg-dark

Text & Background Utilities

text-primary text-success text-danger text-warning text-info text-muted bg-primary 10% bg-success 10% bg-danger 10%
Buttons

Solid

Outline

Sizes

Rounded / Pill — Solid

Rounded / Pill — Outline

Rounded / Pill — Sizes

Rounded / Pill — With Icons

Icon-only Pill Buttons

With Icons

States

Full Width & Groups

Badges
Primary Secondary Success Danger Warning Info Light Dark
Pill Primary 99+ New Pending
Alerts
Inputs & Form Controls

Looks good!
Please provide a valid value.
€ .00
@

Select2 Dropdowns
Auto-initialize: Bas .select-2 class lagao — panel.js automatically Select2 initialize kar deta hai Bootstrap 5 theme ke saath. <select class="select-2" data-placeholder="Select...">
Single selection with search
Multiple tags with search
Grouped options
Admin pre-selected
Disabled state
Bootstrap native select
Forms
Login Form
Forgot password?
Form with Validation
Name is required.
Valid email required.
Select a role.
You must agree.
Modals
Tooltips & Popovers

Bootstrap Tooltips

Tippy.js

Popovers

Progress Bars
Primary 60%
Success 80%
Warning 45%
Danger 25%
Info 70%
Striped Animated
Multi-color Stacked
35%
25%
20%
10%
Animated Demo 0%
Spinners & Loaders

Border Spinners

Grow Spinners

Sizes

Inside Buttons

Full Page Overlay

Cards
Basic Card

Simple card with title, text, and a button.

Learn More
Featured

Card with a colored header and footer.

John Doe

Product Designer

Total Orders
1,240
+12% this month
Revenue
€48,290
↑ 8.5% this week
Active Users
3,812
↑ 5.3% today
Open Tickets
42
↓ 3 since yesterday
Task Progress
In Progress

Website redesign milestone Q2 2026.

65% complete13/20 tasks
Monthly Target
€95,000
78% achieved — €74,100 / €95,000
Accordion

Bootstrap 5 is the latest version of the popular CSS framework. It dropped jQuery as a dependency, improved utilities, added RTL support, and introduced new components like offcanvas and modals enhancements.

Add class select-2 to any <select> element. panel.js auto-initializes it with Bootstrap 5 theme and full search functionality. Supports single, multiple, and grouped options.

Use swalWithBootstrapButtons.fire({...}) for styled alerts. The swalWithBootstrapButtons mixin is defined in panel.js and applies Bootstrap button styles automatically.

Use data-fancybox="gallery" on anchor tags for image galleries. For inline HTML popups use Fancybox.show([{ src: '#id', type: 'inline' }]). Bind: Fancybox.bind('[data-fancybox]').
Tabs & Pills

Overview content — general summary of the selected item.

Details panel — specific information, specs, or logs.

Settings panel — configure preferences and options.

Showing all records.

Showing only active records.

Showing archived records.

Tables
User List
# Name Role Status Progress Actions
1
A
Alice Johnson
Admin Active
90%
2
B
Bob Smith
Editor Pending
55%
3
C
Carol White
Viewer Inactive
20%
4
D
David Brown
Editor Active
75%
5
E
Eve Davis
Admin Review
40%
Showing 1–5 of 24 records
SweetAlert2 (swalWithBootstrapButtons)
panel.js mein defined: swalWithBootstrapButtons — Bootstrap 5 styled buttons, custom animations. Swal.fire() directly use mat karo.
Fancybox — Image Gallery & Popups

Image Gallery (click any image)

AJAX File Popup Recommended

panel.js pattern: data-popup-ajax attribute lagao — Fancybox automatically AJAX se page load karta hai.
data-src="controller/method" — relative URL dena hai.

Inline HTML Popup

Flatpickr — Date & Time Pickers
Mobile Navigation

Live component — the replacement

Rules

  • Build it on <details>/<summary>, the same disclosure as the language switcher. It works with JavaScript disabled and is announced as a disclosure by assistive technology. Script is only needed to close it on an outside click or on Escape — extend the handler the switcher already uses rather than writing a second one.
  • One source for the items. On a templated site, render both the bar and the panel from the same function. On hand-written pages, derive the panel from that page’s own navigation markup, which already carries its active state. Never retype the list: across sixteen pages, two hand maintained copies will drift, and the drift will be silent.
  • On a phone the call to action yields — never the menu, never the language switcher. Logo, language, menu and a CTA do not fit one row. The CTA is the one that can go, because Contact is the last item of the menu that just replaced it; the menu is the only way to move around the site at that width, and the switcher is the only way to change language.
  • Menu links take Ink; only the current page takes azure. Watch the specificity: a global li a:not(.btn) { color: … } is (0,1,2) and outranks a plain .navmenu-list a at (0,1,1), so every item comes out coloured and the current page stops being distinguishable. Raise the selector — do not reach for !important.

Verify it, do not assume it

Language Switcher

Live component — English current, Italian current

Rules

  • Show the language the visitor is on, never the one they would switch to. A bare “EN” sitting in the corner of an Italian page reads as a label of that page to about half the people who see it. The control states the current language and opens onto the others.
  • Rectangular flag, then the ISO code. Flags are served from https://assetscache.eurekabike.com/flags/, the estate’s own asset host — the same one the admin panel uses. English is shown with the United States flag (us.svg), matching that panel; do not substitute gb.svg.
  • Build it on <details>/<summary>. It works with JavaScript disabled and is announced as a disclosure by assistive technology. Script is only needed to close it on an outside click or on Escape.
  • Link to the twin page, not to the site root. File names are localised across our sites (ecosystem.html / ecosistema.html), so the alternate must be mapped per route. Dropping a reader on the other language’s home page loses their place; pointing at a name that does not exist there gives them a 404.
  • Never hide it on small screens. Below 900px the navigation links collapse, which leaves the switcher as the only way to change language. It stays.

On narrow screens, the endorser gives way

Markup

<details class="langsel">
  <summary aria-label="English — change language">
    <img class="langsel-flag" src="…/flags/us.svg" alt="" width="21" height="14">
    <span class="langsel-code">EN</span>
    <span class="langsel-caret" aria-hidden="true"></span>
  </summary>
  <ul class="langsel-menu">
    <li><a href="…/ecosistema.html" hreflang="it">
      <img class="langsel-flag" src="…/flags/it.svg" alt="" width="21" height="14">
      <span class="langsel-code">IT</span>
      <span class="langsel-name">Italiano</span>
    </a></li>
  </ul>
</details>

/* narrow screens: the endorser yields, the subject scales */
@media (max-width: 640px) {
  .nav-logo .wordmark ~ .tagline,
  .nav-logo .wordmark ~ .eb-lockup { display: none; }
  .langsel { flex-shrink: 0; }   /* never hidden */
}
Open Graph Cards

Live templates, drawn at half scale — a product site and a brand site

HERMES

Il marketplace B2B della bike industry

EurekaBike

Product site — the name leads, EurekaBike endorses

EurekaBike

Il supersystem della bike industry

Brand site — the lockup is the subject, so BIKE keeps its azure

Three slots, and nothing else

  • Nothing on the card may be smaller than 38px. LinkedIn renders a 1200px card at roughly 500, X at 506 — about 42%. An 11px eyebrow arrives at 5px and a 25px line of body copy at 10px: present in the file, illegible in the feed. 38px lands at 16px, which reads. Size the card by what survives the shrink, not by what looks balanced at 100%.
  • The name, one payoff, the logo. That is the whole card. No eyebrow, no navigation, no second line of argument. If a payoff needs two lines, break it balanced rather than fill-and-wrap — a lone trailing word reads as a layout mistake, not a decision.
  • Do not print the domain. Facebook, LinkedIn and X print it themselves underneath the card, reading it from og:url. Setting it in the artwork is not merely small, it is duplicated.
  • Light ground, left aligned, artwork bleeding right. This is the chapter-cover language of this playbook: the line illustration runs off the right edge and is put out by a single horizontal veil where the text column begins. Keep the veil a smooth curve — a straight two-stop ramp shows its own change of slope as a visible vertical seam.
  • Fade the illustration before the veil, not only with it. At full strength the drawing eats the card. On the covers it is scenery, not subject; blend it about halfway to the ground first.

Which illustration, and which part of it

The endorsement follows document 04

  • 50 to 60% of the name height. On the card above that is 60px against a 112px name — 54%.
  • Ink on light, white on dark, never the vertical’s primary colour. As an endorser the lockup is monochrome, so BIKE loses its azure. Where the lockup is the subject of the card — home.eurekabike — the azure stays, because there it is not endorsing anything.
  • Use the real asset, do not retype the logo. The wordmark is a file in this repository. A name set in Archivo 900 is close enough to look intentional and wrong enough to be noticed.
  • Drop the word by. At feed scale it is unreadable, and an unreadable word is worse than none: the size hierarchy and the accent rule already say which mark is the signature.

Technical specification

  • 1200 × 630. The one size Facebook, LinkedIn, WhatsApp and Slack all read, and which X accepts as summary_large_image.
  • JPEG, quality 88, under 300 KB. WhatsApp discards heavier previews. PNG is the wrong container once the illustration is in the card — the same artwork lands around 420 KB as a PNG and about 85 KB as a JPEG, and on a near-bitonal line drawing the difference is not visible. A flat card of colour fields and type is the exception: that one stays PNG.
  • Both languages, always. One card per language per property, with the payoff actually translated. A shared card means half the audience gets the wrong language at the moment the link is shared.
  • Version the file name when the card changes. Crawlers cache previews hard, and republishing to the same URL leaves the old image in circulation for days.

Markup

<meta property="og:type"          content="website">
<meta property="og:url"           content="https://hermes.eurekabike.it/site/">
<meta property="og:title"         content="HERMES — Il marketplace B2B della bike industry">
<meta property="og:description"   content="…">
<meta property="og:locale"        content="it_IT">
<meta property="og:locale:alternate" content="en_GB">

<!-- Absolute URL. A relative one resolves for the browser and fails for the crawler. -->
<meta property="og:image"         content="https://hermes.eurekabike.it/site/og-image.jpg">
<meta property="og:image:width"   content="1200">
<meta property="og:image:height"  content="630">
<meta property="og:image:type"    content="image/jpeg">
<meta property="og:image:alt"     content="HERMES, by EurekaBike">

<meta name="twitter:card"         content="summary_large_image">

A website is not finished without it