This page is the single source of truth for the design and brand system of citelight.ai as shipped in this version. It is written for whoever touches the site next: designer, engineer, or Andy in six months. Everything here was extracted from the live build, not reconstructed from memory. The :root token block in this page’s own stylesheet is copied verbatim from index.html at build time, and every swatch and specimen below renders from those variables. If this page looks wrong, the system has drifted; fix the drift, then rebuild this page.
“Locked” means: these decisions were made deliberately, tested at both breakpoints, and survived review. Changing a locked value is allowed, but it is a design decision with site-wide consequences, not a tweak. Section 13 defines what is open.
Premise. Citelight measures whether AI platforms (ChatGPT, Perplexity, Gemini, AI Overview: always these four, always this order) cite a real estate agent when buyers and sellers ask who to work with. The product’s emotional engine is exclusion and its resolution: the agent discovers they are absent from answers their competitors live in, then watches the light move to them.
The metaphor is citation-light. Gold is not decoration; it is the light of being cited. This single rule governs every use of aurum on the site: a gold element must represent citation, presence, or the action that earns them. A gold divider for taste is a violation.
Two registers, one world. The paper world (bone grounds, ink text) is where the agent reads, decides, buys. The vessel (the dark gradient) is inside the machine: streamed answers, audits, the takeover. Paper is calm and editorial; the vessel is where things happen to you. Crossing between them is an event, never a casual background change.
Lexicon. Speak the system’s language in code and conversation: bone (paper grounds), ink (text on paper), aurum (citation gold), void (vessel palette), vessel (the dark surface itself), pmark (platform mark), absence salmon (the not-cited tone), the ledger and the search (the mobile audit mechanics).
Copy is part of the design system and carries hard rules. These apply to UI text, marketing copy, study pages, emails, and code comments alike.
scripts/check-studies.mjs encodes these rules and must exit 0 before any study page ships.Casing. Spaced-caps registers (eyebrows, marquee, mono labels) use text-transform:uppercase, except where a brand’s casing is its identity: eXp is exempted via .brokq__item--case. Never re-case a brand name.
One family speaks for the brand: Söhne (Klim Type Foundry), with Söhne Mono as the machine’s voice. Sans carries reading and display; Mono is reserved for genuine data registers: labels, timestamps, counts, queries, machine output. Mono used decoratively is a violation.
assets/fonts/soehne-*.woff2 behind assets/fonts.css.Söhne Buch 400 · body, ledes, long reading
Söhne Kräftig 500 · every heading and button on the site
Söhne Halbfett 600 · rare emphasis inside data surfaces
Söhne Mono Buch 400 · labels · queries · counts
Söhne Mono Halbfett 600 · emphasized data
| role | size | tracking | notes |
|---|---|---|---|
| h1 (hero) | clamp(2.65rem,6.6vw,5.5rem) | -.03em class | line-height 1.02, text-wrap balance |
| .h-section | clamp(1.9rem,3.8vw,3.1rem) | -.028em | weight 500, ink-0 |
| .lede | clamp(1rem,1.35vw,1.16rem) | default | max-width 52ch, ink-2, text-wrap pretty |
| .eyebrow | .72rem mono | .16em caps | ink-2, inline-flex with .6em gap |
| body | 1rem/1.6+ | default | ink-1 on paper, void-fg-1 in vessel |
| credits caps (marquee) | clamp(.86rem,1.5vw,1.02rem) | .24em (.18em ≤640) | weight 500, ink-2 |
font-variant-numeric:tabular-nums on every count, percentage, timer, and score. A rolling count in proportional figures is a defect.Four families and one rule of scarcity: the page is bone and ink; aurum appears only as citation-light; the vessel is its own world with its own foreground ramp. Platform tints exist solely to identify the four platforms in data marks.
--bone-0#F1EEE8Page ground. The default paper.--bone-1#EAE7E0Raised paper: cards on the ground, one step lighter-warm.--bone-2#E3DFD5Recessed paper: wells, input grounds.--bone-3#D9D4C8Deep recess. Rare; use before reaching for a border.--ink-0#1A1613Display and headline ink. Never for long body.--ink-1#37322BBody ink on paper.--ink-2#6E685EMuted ink: ledes, descriptions, marquee names.--ink-3#9C9589Whisper ink: leads, ornament labels. Below AA alone; only for non-essential text.--linergba(26,22,19,.10)Hairline on paper.--line-2rgba(26,22,19,.17)Hairline, emphasized (hover, active edges).--aurum-300#F6D378Light aurum: chips, CTA fills on the vessel, marks on dark.--aurum-400#F4C95DMid aurum: gradients, glows.--aurum-500#E5B53EBrand aurum: bars, lit dots, citation-light on paper.--aurum-600#B8913ADeep aurum: gradient anchors.--aurum-ink#8A6B22Aurum as TEXT on paper (contrast-corrected). Never use 300-500 for text on bone.--aurum-glowrgba(229,181,62,.30)Glow at strength (lit dots, focus moments).--aurum-glow-softrgba(229,181,62,.09)Ambient glow. Backgrounds only.--void-0#141009Vessel floor (gradient end).--void-1#1C1710Vessel body (gradient start rgb(28,23,16) pairs with this family).--void-2#262016Raised element inside the vessel.--void-fg-0#EDE7DCPrimary text in the vessel.--void-fg-1#B7AF9FBody text in the vessel.--void-fg-2#928A7CMuted text in the vessel.--void-linergba(246,211,120,.13)Hairline inside the vessel: aurum at 13%, never grey.--t-gpt150,195,165ChatGPT tint (r,g,b triplet).--t-plx60,165,195Perplexity tint.--t-gem130,145,235Gemini tint.--t-aio235,155,85AI Overview tint.Absence has a color: salmon, used only for the not-cited state. Text rgba(222,138,107,.95), borders rgba(222,138,107,.3). It exists in the vessel only.
color:inherit with opacity, never a named grey. Where text sits on imagery, its color derives from the measured luminance of what is actually behind it, re-derived when the ground can change; if the composite cannot be sampled honestly, the element gets its own opaque scrim. Naming a color here has broken this site before.Bands. Sections are .band blocks with vertical rhythm --band-y: clamp(88px,12vh,164px). Grounds change by band class; content is centered by .band__in (max-width --max, inline padding --gut).
Paper surfaces. Cards use the fill-delta recipe: interior panels are one bone step away from their parent, hairline --line, and at most two shadow layers (a 1px contact shadow plus one long soft drop). No third material inside a card.
The vessel. linear-gradient(rgb(28,23,16), rgb(20,16,9)). Inside it, hairlines are --void-line (aurum at 13%), never grey; text uses the void-fg ramp; raised elements use --void-2.
--r-lg22pxLarge surfaces: cards, exhibits.--r-md14pxInterior elements.--r-sm9pxSmall interior chips, wells.--r-pill999pxButtons, chips, stamps, bars.0.5px renders nothing on 1x screens. Thinner lines are made with 1px at lower alpha.| token | value | meaning |
|---|---|---|
--max | 1200px | content column ceiling |
--gut | clamp(20px,5vw,48px) | inline gutter, fluid |
--band-y | clamp(88px,12vh,164px) | section vertical padding |
| width | change |
|---|---|
| ≤860px | Exhibits stack single-column (copy above surface; flipped exhibits un-flip). Share rows compress their grid. |
| ≤720px | The device split. Audit submit opens the mobile takeover instead of the inline theater. This is the boundary between the two exclusive audit experiences. |
| ≤640px | Marquee tracking eases to .18em; share names wrap to 2 lines; after-tag reflows to its two-row grid; type floors enforced. |
Two curves, one duration scale, and a doctrine: motion is diegetic. Every animation depicts something the interface is actually doing (extracting a name, searching text, filling a segment of elapsed time). Motion that only decorates is removed.
--d-micro.16sPress feedback, transforms under the finger.--d-state.24sHover, color, state changes.--d-move.32sElements changing place.--d-long.5sSurfaces arriving or leaving.--d-epic1.1sReserved: one-time theatrical moments only.--beat.09sStagger unit between siblings.Arrival grammar. Entrances use .rv: opacity 0 and 12px rise, .6s on the house curve, staggered by --beat via .rv-2 etc. Arrival is a one-time event with memory; scroll does not scrub it backwards. High-frequency interactions animate at --d-micro/--d-state or not at all.
Counters roll only when something is decided. A count changes at the moment a conclusion lands (a platform finishes, a chip arrives), rendered as a masked digit swap. Ambient counting is banned.
| component | prefers-reduced-motion behavior |
|---|---|
| .rv reveals | Elements render settled; no rise, no fade choreography. |
| Brokerage marquee | Static centered wall: item-level wrap, mask off, duplicate set hidden. |
| Audit (mobile + desktop) | Theater and takeover never mount; submit goes straight to the done state. |
| qfield ambient prompts | Drift suppressed; field rests composed. |
| Hero / footer video | Poster frame; video does not autoplay. |
Platform marks. Official monochrome marks (OpenAI, Perplexity, Gemini, Google) inlined as .pmark SVGs on currentColor. On paper they run ink-toned and muted; in data contexts they take their platform tint via color:rgb(var(--t-*)). Full-color logo walls are banned: muted marks read as confidence, color reads as a sponsor wall and implies endorsement.
The brokerage wall. Nine official monochrome marks, one ink. The standing ruling holds and is unchanged: official assets or deliberate typographic voice, never in-between, and never a redrawn wordmark. The ruling never banned logos - it gated them on completeness, and the gate is now met, so the wall converted. Every mark is knocked out of its official file and tinted to a single baked ink (#57514A, measured 6.04:1 in situ against the band). Ink is baked rather than applied as CSS opacity, because opacity over the mark lightens the effective colour and invalidates the measurement. Corcoran is the one name held back: the supplied file is a crop with the outer letterforms amputated at the canvas edge, and a shaved wordmark is not an official asset. It returns to the wall when a clean file exists. wall-scan in the decay gate now enforces the ruling: a wall that mixes marks with typographic brand names closes the gate, as does a mark whose file is missing from the deploy. The italic closer is exempt - it is a phrase, not a brand.
Every named component, its purpose, and its laws. File references are the component’s home; shared pieces live in index.html unless noted.
--d-state color.hero-loop.mp4, mobile variant) behind measured space, palms as depth props..playing; poster covers reduced-motion and failed autoplay. Type sits in composed empty space, not over busy imagery.order alone squeezes the surface.[hidden]{display:none!important} guards every state against display-rule leaks..btn. Any new page using shared class names must import or redefine them.translateX(-50%) track, 42s linear, hover-pause, 12%/88% mask fades, item-level RM wrap.#auditData JSON contract; specimen mode shows the fictional market.max(.62em, 9.5px).[hidden]{display:none!important} on every page; display utilities silently defeat the attribute otherwise.@media (hover:hover); touch gets resting-state parity.outline:none without replacement.Until the real audit engine ships, every surface draws from one fictional market so a visitor who reads everything finds a single consistent world. All of it is marked ILLUSTRATION.
| entity | canonical value |
|---|---|
| Competitor 1 | Las Olas Isles specialist · cited on 4 of 4 platforms |
| Competitor 2 | Rio Vista listing agent · 3 of 4 (ChatGPT, Perplexity, AI Overview) |
| Competitor 3 | Harbor Beach broker · 2 of 4 (GPT, GEM) |
| Share table | 34 / 22 / 17 / You 9 / five others 18 (sums to 100) |
| Queries | QUERY-BANK.md canon; the scan set is B2, S1, B1, S2 |
| Contracts | /report/ #auditData JSON and the takeover SPEC share one shape family; API integration swaps data blobs and drops ILLUSTRATION marks everywhere at once |
scrollBehavior='auto' before tile capture; smooth scroll races the shutter and manufactures false empties.device_scale_factor:2, is_mobile, has_touch; self-verify with saved stills before delivery, never by asking Andy to look.Locked: tokens, type system and license scope, the two registers, motion doctrine and RM contracts, language laws, the data canon, component laws above.
Open: new sections and surfaces, the desktop switchboard build, copy refinement inside the laws, roster curation, real-API data replacing the canon.
The extension bar. A new surface earns its place with one structural idea that only it uses. If a proposed section could be described as two-column copy/image, centered hero, or a rounded rectangle grid sharing one rhythm, it does not ship; it gets a concept. “Feels generic” from Andy triggers a full concept rebuild, never a patch.
Ship gates: check-studies.mjs exits 0; em-dash grep is clean; both breakpoints captured and reviewed; overflow 0; zero console errors; processor-scan passes, meaning every external host in shipped code is named in the privacy policy; deploy via vercel --prod from ~/citelight-deploy/ with hash verification.