- HTML 62.9%
- Python 32.6%
- CSS 3.5%
- JavaScript 1%
secondary is purely a category hue — it differentiates entity types in tasks, leads and contacts, and role badges — so it must not collide with info blue or the brand green. Mapping it to the info ramp made the two indistinguishable. Violet at 258deg, validated with the dataviz palette checker against both: worst adjacent pair 8.8 protan / 16.0 normal, clearing the CVD floor and the 15-point normal-vision floor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| icons | ||
| logo | ||
| scripts | ||
| source | ||
| tokens | ||
| .gitignore | ||
| preview.html | ||
| README.md | ||
Propool brand kit
Everything here is derived from the ProPool logo artwork. The logo files are vector-traced from it; the colour system is measured off it. Nothing was picked by eye.
Open preview.html in a browser to see the whole kit rendered.
brand/
logo/ 21 SVGs + logo.json — traced from the artwork
icons/ 69 SVGs + sprite.svg — the operational icon set
tokens/ colors.json/.css/.js — the colour system
scripts/ the four generators
source/ the artwork everything derives from
preview.html
The two anchors
| hex | where it comes from | |
|---|---|---|
brand-600 |
#17A860 |
the green in the magnifier and in "Pool" |
ink-900 |
#181C25 |
the charcoal in the house and in "Pro" |
ink-950 |
#0C0D12 |
the artwork's own shadow tone |
Every other step in every ramp is a lightness/chroma walk along those hues. The generator asserts the three anchors on every run, so a ramp cannot quietly drift off the artwork.
The one rule that bites
brand-600 is an accent, not a button fill. It measures 3.09:1 against
white — fine for icons, outlines, focus rings and active indicators, not enough
for white body text sitting on it.
accent-brand→brand-600 #17A860— the logo green. Outlines, rings, icons, active indicators, tinted grounds.action-brand→brand-700 #10874B(4.58:1) — filled green with a white label.
Same reason text-muted is ink-600, not ink-500 (which lands at 4.32:1).
Full numbers in tokens/contrast.md.
Beyond that, the design system's own rule holds: white-led UI, charcoal structures, green directs. The primary button is charcoal, not green. Green is reserved for the one move that matters and for brand selection.
Logo
Traced with potrace at the source resolution (2172×724), split into three layers — charcoal, green, tagline grey — by colour and by the blank band the artwork already has between the wordmark and the tagline. Coverage match to the source: 99.6%; the remainder is antialiased edge pixels.
| file | use |
|---|---|
propool-lockup.svg |
mark + wordmark + tagline — the full signature |
propool-logo.svg |
mark + wordmark, no tagline |
propool-mark.svg |
the symbol alone |
propool-wordmark.svg |
the wordmark alone |
propool-lockup-stacked.svg |
for square-ish spaces |
favicon.svg, app-icon.svg, app-icon-dark.svg |
platform icons |
Each of the first four also ships -on-dark, -mono-white and -mono-ink.
- On a dark ground use
-on-dark: charcoal goes white, the green stays. - Mono variants are for where a single colour is forced — embossing, one-colour print, a watermark. Not a style choice.
- The mark never rotates and its two colours never swap.
- Clear space on every side equals the height of the P in ProPool.
- Minimum sizes: mark 24px, logo 132px wide, lockup 180px wide. Below the
lockup's minimum, switch to
propool-logorather than shrinking the tagline.
Icons
69 icons on a 24×24 grid, 2px optical stroke, rounded caps and joins, one dominant metaphor each, 48×48 minimum touch target.
Every icon is stroked in currentColor, so the four states are a colour change
on the parent and nothing else:
| state | colour |
|---|---|
| default | ink-900 |
| selected | brand-600 on a brand-50 ground |
| disabled | ink-400 (40% charcoal) |
| critical | critical-600 — with a label, never colour alone |
Use the sprite:
<svg class="size-6" aria-hidden="true"><use href="/icons/sprite.svg#i-home"/></svg>
Groups: navigation (5), workspace (11), property (20), communication
(13), state (16), brand-device (4). icons/index.json lists them all with
their meanings.
Two near-duplicates are deliberate: inventory is a bar chart and building is
an office block — the design sheet uses both for inventory in different places.
Likewise property and home share a glyph.
Tokens
tokens/colors.json— the source of truth: ramps, semantic tokens, status pairs, channel colours.tokens/colors.css— CSS custom properties as space-separated RGB triplets, matching the convention already inWeb-Frontend/app/assets/css/tailwind.css, so Tailwind can apply an alpha:backgroundColor: 'rgb(var(--color-brand-600) / <alpha-value>)'.tokens/tailwind.colors.js— drop intotheme.extend.colors.tokens/contrast.md— every ramp step against white and against charcoal.
success aliases the brand ramp on purpose: in this system green means "good to
go", and a second green would only muddy that.
Channel colours (Airbnb, Booking, Agoda, Google, Direct) are identity only — never brand, never status.
Regenerating
The kit is generated, not hand-maintained. scripts/ reproduces this directory
byte for byte from the source artwork at
~/Desktop/ChatGPT Image 18 Sept 2026, 19_33_42.png:
python3 scripts/trace_logo.py # needs potrace + pillow
python3 scripts/gen_tokens.py
python3 scripts/gen_icons.py
python3 scripts/gen_preview.py # run last: it reads the other three
Edit the generator, not the output. gen_tokens.py will refuse to run if a ramp
drifts off the three anchors measured from the artwork.
Illustrations
Web-Frontend/public/login-image.svg is the login hero — an animated diagram of
bookings flowing from the channels into one calendar and an owner statement. It
ships with a dark twin, login-image-dark.svg, derived from it by
scripts/make_login_dark.py.
The light file is the source of truth: re-run that script after any edit to
it, rather than editing the dark one. The mapping is by role, not by hex,
because several colours do two jobs in the light artwork — #171D27 is the
statement gradient, the calendar header bar and the body text; #087A49 is
both a green data fill and the check mark.
AuthHero.vue and BrandWordmark.vue render both variants and let CSS pick.
Tailwind's darkMode here is ['selector', '[data-theme="__disabled_dark__"]'],
so dark: follows the product's theme, not the reader's OS — which is what
you want, since the app currently forces light. The moment dark mode is enabled
the artwork and the logo follow it. Do not swap these on
prefers-color-scheme: a dark-OS user would get dark artwork inside a light app.
The logo needs the same treatment for the same reason: the mark and "Pro" are
charcoal, so on a dark ground they vanish without the -on-dark files.
Notes
- The tagline in the traced lockups is outlines, so no file here depends on a font being installed.
source/propool-logo-artwork.pngis the artwork everything was derived from, kept alongside so the kit stays reproducible.- The traced paths carry the artwork's antialiasing as sub-pixel curve detail.
That is faithful, not clean: if you ever get a native vector master from the
designer, prefer it and re-derive
tokens/against it.