One system. Recognisably ours — without ever overpowering the developer.
This is the canonical reference for offplan.online. Tokens, type, colour, components, the mark, its motion, and how it all lands in product. Everything here is driven by colors_and_type.css — the one file that decides every value. Read it all on one page, or flip Section solo to work one chapter at a time.
Skeleton White
Marketing. Sculptural, asserting, Calatrava-inflected. Bone surface, espresso ink, generous 80–120px rhythm, reveals up to 720ms.
Warm Stone
Product. Receding, museum-label calm. Warm-stone surface, hairline borders, tabular density, motion 120–280ms only. (This page runs in Warm Stone.)
Core principle: the platform is recognisable inside the Admin Panel — full lockup, top-left, every screen, every theme; admin chrome never themes. On a developer's own marketing surface it recedes to a 14px corner plaque. On co-branded artifacts the project is always 1.5× our mark, on the opposite side of a hairline.
The mark
12 outer dots on a circle (R14, r1.35) — an O rendered as a perimeter — with a polar dot core. No inner ring. The outer ring stays anchored; energy lives in the core. The mark-only is the favicon and app icon.
For live motion — breathe, core fill-in / sweep, core spin, flicker, ring chase, ring emanate — see the Motion section below. The breathing dot field decompressed from this core powers Overlays and Hotspots.
Wordmark lockups
V1 Hairline — the mark + “offplan.online” in Inter Tight 200 (hairline), uniform weight. The mark's optical height matches the wordmark. Never re-weight, tint, distort, or alter the spacing.
Brand identity guide
The mark + Inter Tight 200 hairline wordmark, where it shows up and where it steps back: full presence inside the admin panel, a corner signature on a developer's project page, and never larger than 1.5× smaller than the project on any co-branded surface.
Give it air, and stop shrinking it before you reach the limit.
Reserve a square of one mark-height (X) of empty space around the entire lockup on every side. Nothing — type, photography, ribbon edges, page chrome — enters this zone.
The clear-space zone exists at every size, in every register, in every co-branded context. When you can't give the lockup its full margin — small toolbar buttons, table-cell attribution — drop to the mark-only or wordmark-only variant rather than violating it.
| Horizontal lockup | Mark 16px / wordmark 14px. Below this, drop to mark-only. |
|---|---|
| Mark only | 12px. Favicon 16/32/64 use a slightly thicker variant — see aa6-favicon.svg. |
| Wordmark only | 11px Inter Tight 300 (NOT 200 — hairline breaks below 12px). |
| App icon | 1024×1024 source, 22% rounded square, mark inset 18%. |
Six anchored sizes covering every real surface in the system. Inter Tight is a true variable font — these are real weights, not snapped instances. At 14px and below the wordmark steps up to weight 300; the hairline 200 starts to disintegrate.
Espresso on bone, paper-white on onyx. Two colours only.
The wordmark is never an accent colour, never tinted, never gradient-filled, never project-coloured. It renders in --skel-rib (#1A1816) on every light surface and paper-white (#FAFAF8) on every dark surface. The adaptive-text primitive decides for us when the surface is imagery.
A project's hero on the marketing register reads in their palette. The offplan.online wordmark still renders in espresso/paper — it never picks up the project accent. The platform identity is a signature on someone else's wall.
Inside the agent's workspace, the brand is present and stable.
The admin panel is our wall. The agent is logged into our tool, not the developer's website. Brand sits top-left of the nav rail at 20px, every screen, every project, every theme. The admin chrome never picks up a project theme — agents must always know which side of the wall they are on.
| Unit | Floor | Type | Area | Price | Status |
|---|---|---|---|---|---|
| B-L42-4204 | L42 | 4 BR + study | 284 m² | AED 9,840,000 | Available |
| B-L41-4108 | L41 | 3 BR | 198 m² | AED 6,420,000 | Reserved |
| B-L39-3906 | L39 | 2 BR | 142 m² | AED 4,200,000 | Sold |
Sign in to the admin panel.
Use the email tied to your brokerage account.
The developer is the hero. We sign the corner.
A buyer landing on Côte Résidence is there for Côte, not for us. The project's logo, palette and language own the hero. Our identity recedes to a single attribution plaque — bottom-right of the page, footer, or top-right of an embedded widget — at 14px, never larger. The rule: if both brands could ever be the same size on the same view, ours is wrong.
A floor plate is an argument.
When both names appear, the project's is 1.5× ours. Always.
On co-branded artifacts — sales presentations, joint emails, brochure covers, event banners — the project takes the upper-left position and 1.5× the visual weight. Our lockup takes the upper-right, mark + wordmark, no plaque. They sit on opposite sides of a 1px hairline divider. Never overlapping. Never the same size.
| Admin panel · all screens | Top-left nav rail · full horizontal lockup · 20px. Same on every screen. Never themed. |
|---|---|
| Auth · login, signup, password reset | Stacked lockup, centred above the form · mark 48px, wordmark 22px. Brand-forward. |
| Splash · app load, transitions > 720ms | Mark only, 72px, pulsing at 2.4s cycle. No wordmark. |
| Empty state · admin tables | Mark only, 32px, at 30% opacity above the empty-state copy. Decorative, not signature. |
| Toast · system confirmations | Mark watermark at 55% opacity, right edge of the toast, 14px. Optional. |
| Project page · hero | No platform identity in the hero. Project owns it. Period. |
| Project page · footer | Full lockup, paper-white on espresso, 16px, centred. One per page. |
| Project page · floating attribution | "Listed on" plaque, bottom-right, 11px. Optional; on by default on micro-domains. |
| Brochure PDF · cover | Co-brand bar: project upper-left at 26px, our lockup upper-right at 16px. Hairline beneath. |
| Brochure PDF · running footer | 11px Inter Tight 300 wordmark only, page number on the right. No mark. |
| Email · system (auth, lead, contract) | Header mark + wordmark 24px on Skeleton-White. Signature plaque at the bottom of the body. |
| Email · marketing (project blast) | Project art in the hero, "Listed on" plaque at the footer at 14px. We never headline a developer's email. |
| Embedded widget · partner site | "Powered by" plaque, bottom-right of the widget, 12px. Always visible, never hidden. |
| Loading spinner · in-button | Mark at 14px, breathing at micro-pulse, no full rotation. Inherits button text colour. |
| Favicon | Mark only, dedicated 16/32/48/64 SVG with slightly thicker dots — hairline rings disintegrate below 24px raster. |
| iOS / Android app icon | Mark on espresso ground, 22% rounded corner, inset 18% for safe area. |
Favicon, app icon, OS surfaces.
The mark survives at every raster — but the construction of the hairline rings has to change. The default mark uses a 12-dot outer ring at 1.35px radius; below 24px raster that hairline vanishes. We ship a dedicated aa6-favicon.svg with chunkier ring dots (radius 1.9px) and a denser inner core, preserved at 16/32/64. Above 64px raster, the standard mark takes over.
Hi Mira,
A new lead arrived on Côte Résidence, Unit B-L42-4204.
Pick up the thread in your pipeline →
Sky Villa · L42
The eleven ways to break the wordmark.
Each of these has happened on a real designer's surface at some point. Each is a soft no. The hairline is delicate by design — protect it.
The brand is a confident whisper, not a billboard.
offplan.online connects developers, agents and buyers. The product's job is to make the developer's project look great — and to be unmistakably our tool when an agent or builder is looking at it. Two registers, one wordmark, six placements, and one rule about size.
- Inside the panel — full presence. Lockup top-left of every screen, 20px. Same on every theme.
- On a project's page — corner attribution. Plaque, 14px max, never in the hero.
- Co-branded — 1.5× smaller than the developer. Right of a hairline, never opposite-equal.
- Two inks, no tint. Espresso on light, paper on dark. Adaptive-text decides for imagery.
- Mark alone for tight slots. Favicons, app icons, toasts, spinner buttons.
- Hairline 200 above 14px. Below that, step up to weight 300. Below 11px, don't.
Colour
Two surfaces, one ink scale, restrained accents. Never invent a hex outside the token file — derive in oklch() from an existing token and name it. One accent per view.
Typography
Inter Tight for display, Inter for body, JetBrains Mono for IDs. Variable cuts — every weight 300–700 is real, never snapped to a static instance.
Brand fonts
Four families, locked and self-hosted from /fonts — referenced only through tokens, never named in a component.
Côte Résidence is a 14-storey beachfront tower on the Palm crescent — 86 units across two cores, finished by Q3 2027. Six floor plates, three exposures.
Noto Sans SC) and Hindi (Noto Sans Devanagari) are system / CDN fallbacks, auto-bound through [lang="zh"] and [lang="hi"] — they are not bundled in /fonts. Only the four families above are self-hosted.
Layout & grid
One content shell, three shell paddings, and two density registers — marketing breathes, product compresses. Everything lands on the 4px spacing scale, never an off-scale value.
Container
All content sits inside one shell capped at --shell-max 1240px, then centred. The shell padding steps up with the viewport so the gutter feels intentional at every width.
1240px
Breakpoints
The system uses five thresholds, mobile through wide. Each one earns its keep — a real layout change happens at every step, nothing speculative.
| Breakpoint | What changes |
|---|---|
| ~560px | Mobile ceiling. Single-column everywhere; cards and demo grids collapse to one column, filters become a sheet. |
| ~640px | Large phone / small tablet. Two-up card grids return; inline labels stop wrapping under their fields. |
| ~760px | Tablet. Section demo grids reflow from one column to multi-column; shell padding steps from small to medium. |
| ~880px | Small laptop. The product sidebar pins open instead of collapsing; three-up grids unlock. |
| ~920px | Wide. Shell padding steps to large (48px); the full 1240px shell sits centred with generous outer margin. |
Density
Two registers, one component contract. Marketing (Skeleton White) breathes on an 80–120px section rhythm; product (Warm Stone) compresses to a 24–48px rhythm with tabular field and row heights.
Marketing
Skeleton White · breathes
Section rhythm 80–120px (--space-20–--space-24 and up). Large display weights, generous tracking, sculptural reveals.
Product
Warm Stone · compresses
Section rhythm 24–48px (--space-6–--space-12). Hairline borders, tabular density, fast 120–280ms transitions.
Rhythm
Every vertical measure resolves to the 4px spacing scale — no off-scale values. Component padding lives in the lower steps; section padding lives in the upper steps.
--space-3 (12px) to --space-6 (24px). Cards, fields, rows, and inset panels.--space-12 (48px) to --space-24 (96px). The gap between sections and the marketing breathing room.Spacing & radius
4px base, doubling. Component padding sits at 12–24px; sections at 48–96px. Never a value outside the scale. Corners are Apple-continuous, never overly square.
Shadows
Three only, all low-opacity. Never coloured, never glow.
Iconography
Phosphor Icons, Thin weight. 1.25px stroke at 24px artboard, round caps and joins, outline only, always currentColor. Custom additions (floorplan, units, keystone) match the family exactly.
Accessibility
Accessibility is a property of the tokens, not a layer added afterwards: contrast targets, a single visible focus ring, generous hit targets, honest motion and clean semantics are all baked into the colour, density and motion primitives below.
Target WCAG AA: 4.5:1 for body copy, 3:1 for large text (≈24px+) and UI components. Readable copy uses only the upper three ink tokens; the lightest token is decorative.
Primary UI text
--text-900 · #323840 ReadableBody copy
--text-700 · #3D3B39 ReadableSecondary label
--text-500 · #6A6865 ReadableDecorative only
--text-300 · #A09E9C Never readable copyOver photographs, renders or glass panes, never hard-code white. Add data-adaptive to the surface and reference --surface-fg / --surface-shadow on the text; the sampler flips ink between Onyx and paper based on the actual luminance behind the words, defaulting to the safe dark-bg branch when JS is off.
Sky Villa · 4 BR + study — ink driven by --surface-fg, not a literal colour.
Two cases need a deliberate check rather than a blanket pass: --status-reserved (burnt honey, #B58440) drops below 4.5:1 as small text on light surfaces — use it for pills/large labels with weight, not body copy; and any very-low-opacity label can fall under target at small sizes — verify the resolved colour, not the token.
Every interactive control shows a visible focus state. The system focus ring is a 2px --moss outline at 2px offset — the same ring used by .btn:focus-visible and .field input:focus. Keyboard operability is required for all controls: navigation, toggles, copy targets and sliders must all be reachable and actionable from the keyboard alone, in a logical tab order.
| Token | Value | Applies to |
|---|---|---|
| --tap-min | 44px | Touch / mobile — minimum tappable size for any control on touch surfaces (nav items, toggles, status pills, slider thumbs). Matches --field-h. |
| --click-min | 32px | Pointer / desktop — minimum target for mouse-and-keyboard density (compact rows, toolbar buttons). Matches --field-h-compact. |
44 × 44 · touch
32 × 32 · pointer
Motion is decoration, never meaning — nothing in the system requires animation to be understood. When prefers-reduced-motion: reduce is set, every duration token collapses to 0ms at the root, so all token-driven transitions resolve instantly.
@media (prefers-reduced-motion: reduce) {
:root {
--duration-micro: 0ms; --duration-page: 0ms;
--duration-panel: 0ms; --duration-wing: 0ms;
}
}
Beyond the token reset: the living-field canvas engine paints one static frame and stops rather than looping; demo CSS animations set animation: none; and any reveal-on-scroll lands in its final state immediately.
- Heading order is sequential — one
h1per view, thenh2/h3without skipping levels. Visual size comes from the type role, never from picking a heading tag for its size. - Every control and input has an accessible name — a visible
<label>, oraria-label/aria-labelledbywhere a visible label is not present (icon-only buttons, the copy targets, slider thumbs). - Decorative marks, the brand-mark glyph and the living-field
<canvas>elements carryaria-hidden="true"so they are skipped by assistive tech. - Imagery has meaningful
alttext when it carries information, emptyalt=""when purely decorative, and an appropriateroleon inline SVG used as iconography.
Voice & content
Architectural, not aspirational. Specific over evocative. The words on the page carry the same restraint as the tokens behind them — Dubai-literate, never realtor-speak.
Architectural, not aspirational; specific over evocative; no realtor-speak.
- Architectural, not aspirational. "1,242 m² floorplate" beats "expansive living spaces."
- Specific over evocative. Project, tower, floor band and AED price first; adjectives last.
- Dubai-literate. AED with thousands separators, m² (never sqft as primary), Q-quarter handover, tower·unit notation — "Tower B · L42 · 4204".
| Field | Rule | Rendered |
|---|---|---|
| Money | Space after currency, comma thousands, no decimals on whole AED. Uses the .price register. |
AED 4,200,000 |
| Area | Space, m with superscript ². Never sqft as the primary unit. | 142 m² |
| Counts | BR uppercase, single space. Halves allowed. | 2 BR3.5 BR |
| Dates | Q-quarter for handover, or day month year. Never US format, never relative ("in 4 months") in marketing. | Q3 202612 Mar 2026 |
| IDs & coords | Monospace (var(--font-mono)), uppercase, hyphenated. |
OFP-2026-1204 |
| Element | Cap | Note |
|---|---|---|
| Hero headline | ≤ 7 words | One claim, no clause stacking. |
| Section eyebrow | 2–4 words | All-caps with the wider tracking token. |
| Card title | ≤ 40 chars | Truncate the address, not the project name. |
| Empty-state body | ≤ 18 words | One line, paired with one action. |
| Field help | ≤ 10 words | If you need more, you've designed the form wrong. |
- Architectural-first. Wide angles, cool light. People only in second-tier lifestyle slots.
- No people in heroes. The frame is the building, not the lifestyle.
- No golden-hour cliché. Skies lean overcast plaster and predawn — the atmosphere palette.
- Floorplans at native scale. Never stretch a webp plate to fit the frame.
Buttons
Display type, uppercase, +0.06em. Ink primary, hairline secondary, quiet ghost, moss for the one accented action. Focus ring is always moss. The brand-infused field buttons below are the canonical loading / primary-action treatment — reused verbatim in Motion, Hotspots and Overlays.
brandAA6.startLivingField() engine drives the FAB, the hotspots, and the overlays.
Fields & inputs
44px comfortable field height. Uppercase micro-labels, moss focus ring, oxblood error. ~80% of the Admin Panel is forms and dense tables — these set the tempo.
Status & pills
Three states, oxidised so they sit next to mineral neutrals yet still scan correctly. Inside a project page, Reserved rebinds to the project's own accent.
Cards
The unit card is the workhorse of the inventory surface. Generic card chrome carries panels, modals and form groups.
Sky Villa · 4 BR + study
Payment plan
20 / 40 / 40 over 36 months. First instalment on reservation.
Motion
The locked set — the outer ring stays anchored at the viewBox centre and never drifts. Whole-mark breath, core fill-in / sweep, core spin in place, core flicker (thinking), ring chase, and the settle entrance — each stage has play/pause and a speed slider so you can read the motion at any tempo.
In context
Three real product moments where the motion does the work.
Hotspots / POI
The locked mark keeps its 12-dot ring — but when the mark becomes a hotspot (a map pin, a unit dot on a floorplate, a hotspot on a 360° tour) that ring is just scaffolding, so it gets dropped. What's left is the dense polar field breathing inside a paper disc. No CSS halos, no soft glow shadows — the dots themselves do all the work. Six motion variations, three sizes, five colour modes, glass over imagery, and three in-context scenes. The field is the signal.
01 · Motion variations
Six ways to make a hotspot feel alive. Each stage shows the same motion at large (96 px), medium (56 px) and small (32 px) — the small one is what you put on a dense map; the large is for a hero callout, a primary CTA, or a single-spot screen.
02 · Colour modes · breathing field, no halo
Five fills the hotspot ships with. Each is the same pulse motion — but on its own ground, with dots in the inverse value. The glass tile is the version that sits on top of architectural photography in the sales app.
03 · Glass · over imagery
Three architectural surfaces — same hotspot, semi-transparent backdrop-blur tile, paper-white field breathing on top.
04 · In context
The hotspot's first three jobs: a locations map (large size, themed), a floorplate (medium, one per unit), and a 360° tour (medium, glass over photo).
Floorplate · L42
Six units, six hotspots. Each one is 56 px. Status is in the disc colour; field motion is the same flicker on all.
360° tour · interior hotspots
Glass discs, paper-white field flickering inside. No outer halo — the field IS the signal.
Overlays · living dot field
The same breathing-dot-field attractor engine carries system state across every shipped surface — from a 200 px Apple Watch glance up to a 1080 px sales-kiosk monitor — including a text-aware variant that carves a feathered exclusion around live type.
Sales presentation
FAITHFUL summary — the marketing kit where the project leads and offplan.online recedes.
A floor plate is an argument.
Eighty-six residences across fourteen storeys on the Palm crescent. Six exposures. Two cores. One staircase between sea and city.
Calatrava-light, on a Palm crescent.
Two cores. Fourteen storeys. A façade structured in vertical ribs that break the marine glare into thin shadows. Every plate from L08 upward opens to the sea; every plate below opens to the central garden. No corners are wasted on circulation.
Three things you don't get on the next plate.
Direct beach line.
Crescent C is the only Palm address with an unbroken beach line for 480 m. No service road between you and the water.
Two cores, no shared corners.
Six units per plate, served by two cores. Every residence has glass on at least two perpendicular faces.
L08 dedicated lift.
Sky villas above L40 share a private lift lobby. Day-staff and service flow are routed through Core B only.
Six exposures.
One staircase.
The plate is the unit. Plates L08–L24 publish as the Garden series; L26–L42 as the Sky series.
Forty-two open. Eleven on hold.
Sky Villa · 4 BR + study
Pano Balcony · 3 BR
Skyline · 3.5 BR
We didn't design a tower with views. We designed a section through the crescent and stood it on its end.
Forty-two residences open. The next viewing slot opens at 09:00 GST.
Calatrava-light, on a Palm crescent.
Two cores. Fourteen storeys. A façade structured in vertical ribs that break the marine glare into thin shadows. Every plate from L08 upward opens to the sea; every plate below opens to the central garden. No corners are wasted on circulation.
Three things you don't get on the next plate.
Direct beach line.
Crescent C is the only Palm address with an unbroken beach line for 480 m. No service road between you and the water.
Two cores, no shared corners.
Six units per plate, served by two cores. Every residence has glass on at least two perpendicular faces.
L08 dedicated lift.
Sky villas above L40 share a private lift lobby. Day-staff and service flow are routed through Core B only.
Six exposures.
One staircase.
The plate is the unit. Plates L08–L24 publish as the Garden series; L26–L42 as the Sky series.
Forty-two open. Eleven on hold.
Sky Villa · 4 BR + study
Pano Balcony · 3 BR
Skyline · 3.5 BR
We didn't design a tower with views. We designed a section through the crescent and stood it on its end.
Forty-two residences open. The next viewing slot opens at 09:00 GST.
Calatrava-light, on a Palm crescent.
Two cores. Fourteen storeys. A façade structured in vertical ribs that break the marine glare into thin shadows. Every plate from L08 upward opens to the sea; every plate below opens to the central garden. No corners are wasted on circulation.
Three things you don't get on the next plate.
Direct beach line.
Crescent C is the only Palm address with an unbroken beach line for 480 m. No service road between you and the water.
Two cores, no shared corners.
Six units per plate, served by two cores. Every residence has glass on at least two perpendicular faces.
L08 dedicated lift.
Sky villas above L40 share a private lift lobby. Day-staff and service flow are routed through Core B only.
Six exposures.
One staircase.
The plate is the unit. Plates L08–L24 publish as the Garden series; L26–L42 as the Sky series.
Forty-two open. Eleven on hold.
Sky Villa · 4 BR + study
Pano Balcony · 3 BR
Skyline · 3.5 BR
We didn't design a tower with views. We designed a section through the crescent and stood it on its end.