Cleaned and rebuilt around the locked direction: bookend wordmark (V styled like monogram + dot at end), V. monogram with tighter+bigger dot, three full-dashboard UI direction studies, deprecated explorations moved to bottom.
Final direction. The V is rendered as a brand-mark element (refined wider stance + softened point), inline with the typography, in clay. "ecreal" follows in Inter Semibold primary text color. The XL dot closes the wordmark in clay. The wordmark reads as one unit while the V and dot both function as brand-color elements.
The wordmark is the only place where the V is rendered as a custom SVG brand mark instead of a typeset letter. By styling the V as a refined wider-stance geometry inline with "ecreal" typeset in Inter Semibold, the wordmark reads as one continuous word while the V and dot both function as brand-color anchors. The result: a distinctive but quiet brand presence — not a logo bolted onto text, but a typographic system where the brand color appears at two points (V at the start, dot at the end) in a way that reinforces "this is a wordmark" rather than "this is decoration around a name."
Clay Light (#A05847) is the locked accent for white surfaces — warm and lifted, retaining construction-materials earthiness without the heaviness of deeper Clay variants. Clay Bright (#C68070) on dark surfaces preserves legibility while keeping the same warmth. Clay Dark (#7A3D32) stays in the palette as a deeper accent for high-emphasis brand moments only — it's not the default.
Refinement of exact letterform proportions and kerning belongs to a real designer pass for v1+. The current geometry holds at every locked size (96 to 18px) and works in both light and dark themes via a single token swap.
V monogram with dot positioned tight to V, sized for visibility. Both elements colored clay. Used wherever the wordmark is too long: favicon, app icon, mobile nav, social avatar, splash screens.
The monogram uses the same V geometry as the wordmark — identical SVG path, identical dot color. Scale and proportion are the only differences. This is what makes the brand cohesive across surfaces: the favicon at 16px and the marketing wordmark at 96px are clearly the same mark, just at different presence levels.
The dot is rendered as a separate <circle> (not text) to keep it precisely aligned with the V at every render size. The contained app-icon variant uses an inverted color treatment (clay background, soft-white V + dot) for OS app-icon contexts where the icon must work against any wallpaper.
For favicon / app-icon use cases, the contained variant is preferred. For inline UI use (sidebar mark, mobile nav, social avatar), the open variant on transparent background is preferred.
The brand mark is a system. V. monogram for tight contexts. Full bookend wordmark for marketing and branded surfaces. Same V geometry, same dot, different scales of presence.
One mark, two presentations. The monogram is the tight context expression — favicon, mobile, app icon, social avatar — where space won't fit the wordmark. The wordmark is the full presence expression — marketing surfaces, document headers, dashboard branding — where Vecreal needs to be named explicitly.
The V geometry, dot color, and dot proportion (∼32% of V height) are shared by reference: the monogram uses the same SVG path as the wordmark's .bk-v. Update the path in one place and both surfaces inherit the change.
Selection rule: use the wordmark whenever there is room for it to read at ≥ 18px. Below that — or in dense UI contexts where text would compete — use the monogram.
B2B software palette with warm-grounded character. Clay accent system (Clay Light primary on white, Clay Bright primary on dark) — distinct from Procore (orange), Bluebeam (blue), and the standard tech-startup blue/teal/purple.
Warm near-blacks and warm near-whites instead of cool blue-grays. Construction is a tactile industry — concrete, wood, drywall, steel. The palette grounds the brand in those materials without literally referencing them.
Clay is the singular brand accent. Used sparingly on the wordmark, citations, references, and key chrome moments. The semantic palette (success, warning, error, info) handles functional UI state, distinct from the brand. This separation is intentional — clay is a brand mark, not a status indicator.
Backgrounds are mostly white with subtle warmth (#FAFAF8) rather than pure white. Production tool, not editorial publication.
Single-family system. Inter handles display, headings, body, UI. JetBrains Mono for technical contexts (timestamps, citations, IDs, keyboard shortcuts).
Two families, no exceptions. Inter for narrative content (headings, body, UI labels), JetBrains Mono for technical metadata (citations, IDs, timestamps, code). This split makes the technical layer visually distinct without needing a color or weight cue — the typeface itself signals "this is data, not prose."
Both fonts are free, well-supported, and load quickly via Google Fonts. Inter is the de-facto standard for B2B SaaS (Stripe, Linear, Vercel, Notion); JetBrains Mono is widely respected in technical contexts. Choosing them prioritizes familiarity and craft over novelty.
Letter-spacing tightens at display sizes (-0.03em) and loosens at mono (+0.04em) — an old typographic rule that keeps each context comfortable to read.
Formalized + locked into :root CSS variables. All locked colors, spacing, radii, motion, and shadow values now live as design tokens at the top of the file. Components reference var(--token) instead of hardcoded values, so future updates are one-line changes. Reference Stripe / Linear / Atlassian Polaris for the patterns; tuned for Vecreal's density and brand voice.
outline: 2px solid rgba(160, 88, 71, 0.5); outline-offset: 2px; — clay-tinted ring at 50% opacity, 2px gap from element. Visible against any surface, never overlaps the element's own border. Applied via :focus-visible only (not on click, only on keyboard navigation). Stripe / Linear / GitHub all use this pattern.
Tokens are the system's contract with engineering. Every spacing, radius, duration, and shadow value lives in :root as a CSS variable; components consume var(--token). A future repaint of, say, "all 8px gaps to 6px" is a single-line change.
The 4px base (with a 2px hairline at sp-1) snaps everything to a clean rhythm. Stripe, Linear, and Atlassian Polaris all use this scale — it's the de-facto standard for B2B density.
Motion is intentionally restrained: 4 durations, 2 easings. No bounce. Vecreal is professional infrastructure, not a consumer app.
Stroke-based icons on 14×14 viewBox, stroke-width 1.4, stroke-linecap round, stroke-linejoin round. Single layer, no fill (except when filling is the icon's purpose, e.g., status dots). Inherit color via stroke="currentColor". Reference: Lucide / Tabler / Phosphor — geometric, calm, technical without being cold. This is a starting set; the full Vecreal icon library will grow as product surfaces stabilize.
Stroke-based on a 14×14 viewBox. The 1.4 stroke-width reads consistent across all sizes (14, 16, 18, 20px) without requiring optical adjustments per size. Single-layer paths keep the SVG output small enough that inlining 42 icons doesn't bloat HTML.
Lucide / Tabler / Phosphor are the reference set — clean geometric shapes, calm visual presence. The first 42 cover navigation, status, action, communication, file, and time. The library grows as new product surfaces require it — we don't pre-build icons for use cases that haven't shipped yet.
Color inheritance via currentColor means engineering can drop an icon next to any text and have it adopt the surrounding color — no per-icon variants required.
Reference: Linear, Vercel Dashboard, Stripe. Sharp 4-6px radius. High-contrast borders. Tight spacing. Mono prominent in metadata. Restrained accent (almost monochrome). Black primary CTA. Premium-technical signal.
Reference set: Linear, Vercel Dashboard, Stripe. These products are the gold standard for B2B power tools — tight density, high-contrast borders, restrained accent, mono prominent in metadata. The look telegraphs "this is professional infrastructure" without needing to say it.
Sharp radii (4–6px) keep the surface feeling precise. Soft pillowy 12–16px radii read as consumer; we're building for the operator. Black primary CTA keeps the visual hierarchy on actions, not on the brand — clay stays the brand moment.
This direction is the locked default. Section 16 below shows it applied to both dark and light surfaces with the same component vocabulary.
Locked & polished. Inter throughout (JetBrains Mono on technical citation IDs and numerics with tabular figures), 16px card padding, 8px radii, soft off-white #f7f8f8 (warm cream) for primary text on dark, scarce clay. Component refinements (Direction A applied): status-dot eyebrow with colored "FLAGGED" + muted type label fixes the eyebrow/title hierarchy; chevron-prefixed mono reference pills; compact 70px confidence track with paired "HIGH · 0.86" at consistent size; priority-coded action rows with monospace days + assignee initials; sidebar with outline icons + count badge; topbar with live indicator + project breadcrumb (no ⌘K hint). Two baselines below — dark and light with the dark sidebar as brand anchor.
Two streams is the operating principle: dark sidebar always as the brand anchor, with the main canvas swapping between dark and light depending on theme. The dark sidebar carries Vecreal's identity across both themes — it's the consistent visual moment regardless of which theme the user prefers for their main canvas.
This baseline merges the strongest elements of two earlier explorations: V1's surface depth (clear card boundaries, off-white #f7f8f8 text on dark) and V3's power density (16px card padding, 8px radii, tight component spacing). V2 (editorial) was rejected and archived.
Component refinements applied (Direction A): status-dot eyebrow + colored label + muted type, chevron-prefixed reference pills, 70px confidence track with paired "HIGH · 0.86", priority-coded action rows, outline sidebar icons + count badges, live indicator in topbar.
Reusable patterns that compose into product UI. Each component shown on dark and light surfaces with the locked styling applied. These are design-system-level definitions — the actual product UI will compose these into specific surfaces (Brief, Action Register, Drafts, Project State, etc.) with iteration.
Section 21 is the canonical component catalog — the locked base patterns. Subsequent sections (24, 25, 26, 27, 28) extend these baselines with additional variants and use cases.
Every component shown on both dark and light surfaces. The locked styling applied here is what every product surface composes from. New surfaces must compose existing components; new components require an explicit catalog update.
This catalog plus Sections 22 (Foundations) and 23 (Iconography) form the "raw material" layer. Everything in the product is built from this vocabulary.
Form library for any data-entry surface (RFI/submittal creation, settings, filters, drafts). Inputs use 5px radius, 1px borders, clay-tinted focus rings (3px, 18% opacity). Helper text below the input, error state with red icon + message. Multi-select uses chips inside the field. Date picker uses a calendar popover with selected date in clay, today in clay-tinted bg. References: Stripe Dashboard form patterns, Linear filters, Notion property fields.
Forms are the spine of any data-entry surface (RFI/submittal creation, settings, filters, drafts). The library covers every common control with locked sizing, focus state, and error patterns — so PMs experience consistent affordances across every form they touch.
Focus state uses a 3px clay-tinted ring at 18% opacity. Heavier than the button focus ring (2px / 45%) because forms are read more carefully — the ring needs to clearly mark which field has focus when the user is mid-flow.
Validation on blur, errors inline. Validating on every keystroke creates noisy UX during normal typing. Inline errors keep the user in context vs. a toast that requires re-reading.
For Action Register, RFI Log, Submittal Log, Document Library, Subcontractor Registry. Sticky header with sort indicators, filter pill row above, multi-select via checkbox column, row-hover reveals action buttons (view/edit/more), pagination at bottom. The active sort column gets a clay-tinted arrow; the active page in pagination uses clay-tinted bg.
Construction data is dense — RFI logs run hundreds of rows, cost rolls span 20+ columns. The table system has to handle that density without becoming an eye chart. Mono header + sans body + right-aligned numbers + 1px row dividers do most of that work.
Sticky header on scroll. Users lose context fast in long tables — the column headers must stay visible while scrolling row 200 of 800.
Filter pills are outlined clay (not filled). Filled clay would over-color the surface; outlined keeps the table dominant while still showing "you have filters applied."
All cards share the same surface treatment (gradient + inset highlight + soft shadow), border-radius (7px), padding (16px). They differ in internal structure: action card has a primary CTA at the bottom; stat card has a large numeric value + trend + sparkline; info card is passive disclosure with no action; link card is fully clickable with a chevron affordance; summary card has bullet content + secondary actions. References: Stripe (stat cards), Linear (action cards), Mercury (info cards), Notion (link cards).
One surface treatment, five internal structures. The shared treatment (gradient + inset highlight + soft shadow + 7px radius + 16px padding) keeps cards visually cohesive across the dashboard. The internal structure tells the user what kind of action the card affords.
Action ends with a CTA. Stat is a metric + trend. Info is passive disclosure (no action). Link is fully clickable with chevron. Summary is bullet content + secondary actions. Pick by intent, not by visual preference.
The locked centered modal gets two additions (hyperlinked title + full-screen expand button). Plus four new overlay patterns: hover popover (smaller than a modal, attached to a target), email/meeting source popover (inline citation expansion with verbatim content), confirmation modal (destructive actions), dropdown menu, right-click context menu. References: Linear (issue popovers, context menus), Stripe (transaction popovers), GitHub (PR comment popovers + dropdowns), Anthropic Claude (citation hover).
Click the email or meeting line in citations — instead of an agent summary, the popover shows actual verbatim content. The PM trusts the source because it's real, not synthesized.
The Mech room conflict involves M-301 r3 and addendum revisions.
The Mech room conflict involves M-301 r3 and addendum revisions.
Hover any brief, action, or document row, then right-click to surface the same actions a dropdown menu would.
Five overlay patterns covering the full disclosure spectrum: modal (focused decision), popover (inline source disclosure), tooltip (brief hint), dropdown (selectable menu), context menu (right-click). Each has a distinct role and rules — mixing them collapses the affordance vocabulary.
The modal gets two new affordances: a hyperlinked title (jumps to the full source/route) and a full-screen expand button (opens the modal contents as a dedicated route). This matches Linear and Stripe modal patterns.
Source citation popovers are the Vecreal-specific pattern — clicking an inline citation opens a popover with the verbatim source text. This is what makes "show your work" visible at the surface level.
Avatars show initials only — Vecreal is a passive capture tool synthesizing on the user's behalf, not a collaborative space. No online/away/offline statuses (we don't track presence). No user photos (we don't collect them). The avatar marks who something is attributed to (assignee, RFI author, document uploader) without performing presence theater. Avatar groups stack with proper z-index layering + 2px surface-colored ring around each circle so the overlap is visible. Chips: filter (selected/unselected with optional status dot), removable (active filters with x), with avatar inside (assignee/mention picker).
Avatars show initials only, no photos, no presence indicators. Vecreal is a passive synthesis tool, not a collaboration space — we don't track presence and we don't collect user photos. The avatar marks who something is attributed to (assignee, RFI author, document uploader) without performing presence theater.
Avatar groups stack with z-index layering + 2px surface-colored ring around each circle so the overlap is visible without colors bleeding through. Stack max 4 visible; show +N for the rest.
Chips have three roles: filter (selected/unselected toggle), removable (dismissable filter pill), assignee picker (with embedded avatar). Their visual differences signal their behavior.
Search across all project sources: RFIs, drawings, emails, meetings, submittals, COs, photos. Autocomplete dropdown shows top results grouped by type, with the matched query highlighted in amber. Each result row: icon + primary label (with highlighting) + meta line + type tag on right. Below results, "Recent searches" surface lets the PM jump back to a prior query. Footer shows total searchable corpus.
Search spans every project source: RFIs, drawings, emails, meetings, submittals, COs, photos. Results group by source type so the user immediately sees "3 RFIs match, 1 drawing matches" rather than a flat unsorted list.
Match highlighting uses amber, not clay. Clay is brand; amber is functional ephemeral highlighting that disappears once the user has read the result. Mixing the two would confuse the brand semantic.
Recent searches surface below results so the PM can jump back to a prior query — investigation flows often loop. Footer shows the total searchable corpus so the user knows the search scope.
When to use which: relative time (full prose like "14 minutes ago") for human-friendly contexts — brief headers, activity feeds, last-updated indicators. Compact mono ("14m ago", "3d", "Apr 30") for chrome / dense data — topbar, action rows, table cells. Absolute time ("April 30, 2026 · 14:23 EST") for formal contexts — archived audit trails, cited timestamps in citations modals, reports. Date ranges with em-dashes for periods. Aging colors communicate urgency: green "today/just now", neutral "ago", amber "aging", red "overdue".
Time is shown three ways depending on context. Relative prose ("14 minutes ago") for human-friendly contexts where the user just needs to know roughly when. Compact mono ("14m ago") for chrome and tables where space is tight and density matters. Absolute formal ("April 30, 2026 · 14:23 EST") for audit trails and citations where exact time is the record.
Aging colors signal urgency without requiring a separate badge: green for fresh, neutral for older, amber for aging, red for overdue. The color encoding lets the user scan a column of dates and see priority instantly.
For onboarding flows (connect Procore → index docs → sync emails → generate first brief), draft creation wizards (RFI / submittal / change order), and any multi-screen process. Horizontal stepper shows discrete steps with done (green check) / active (clay-tinted ring with number) / pending (neutral with number) states. Linear progress wizard shows continuous progress with current step + percent. Both share the same color logic so the flow reads consistently regardless of variant.
Multi-step flows fall into two visual patterns. Horizontal stepper when steps are discrete and named (Connect → Index → Sync → Generate) — the user sees the whole journey upfront. Linear progress wizard when steps are sequential but the count or names matter less — just "Step 3 of 7, 42% complete."
Both share the same color logic for state: green check for done, clay-tinted ring for active, neutral number for pending. Consistent semantics across variants prevent confusion when a flow uses both within a deeper subprocess.
For Document Library, Drawings folder, Submittal Log, Photo Gallery, anywhere we surface files. Folder rows show category + count + chevron, like Linear's project list. File rows are tabular: icon + name + type + size + modified + owner + ellipsis menu, like Stripe's Files surface or Notion's file blocks. Mono numerics for sizes, mono dates, type extensions in tracked uppercase mono. Ellipsis menu opens the dropdown menu pattern from Section 25.
File patterns are the spine of Document Library, Drawings, Submittal Log, and Photo Gallery surfaces. Folder rows are minimal: name + count + chevron. File rows are tabular with consistent metadata columns: type icon + name + extension + size + modified + owner + actions menu.
Mono everywhere there are numerics or codes — size, date, type extension — so columns align cleanly even across row sizes. The kebab/ellipsis menu uses the dropdown overlay pattern from Section 25.
Toasts: transient (5s auto-dismiss), top-right corner, 3px colored left border + matching icon. Banners: persistent, top of page or surface, with optional CTA (e.g., "Reconnect" on error). Inline validation: below input field, red icon + text for errors, green check + text for success. Variants: success (green), info (slate), warning (amber), error (red). Surface error sync failures at the global banner level (per your earlier note), not per-component.
Three feedback patterns: toasts (transient, low-stakes), banners (persistent, requires attention), inline validation (field-level, contextual). They have distinct lifecycles and shouldn't be interchangeable.
Sync failures use the global banner level (top of surface) rather than per-component error states — one banner explains "Procore sync paused" once, instead of every card showing a stale-data warning.
Toasts auto-dismiss in 5s. Banners persist until the user dismisses or the underlying state resolves.
Bell icon in topbar with unread count badge (clay-tinted, ring-shadowed for visibility on any surface). Click opens a notification panel: header with count + "Mark all read" + settings icon, scrollable list with unread items highlighted (subtle clay-tinted background + bold title + leading dot), each notification has type icon + title + preview + relative timestamp, footer "View all notifications" links to a full-page view. References: GitHub (notification panel), Linear (inbox), Stripe (alerts).
Notifications surface async events: a teammate left a comment, a sync completed, a draft is ready for review. The bell + badge in the topbar is the persistent affordance; the panel opens as a popover-style surface with grouped, scannable list rows.
Unread items get a subtle clay-tinted background + bold title + leading dot. Read items fade to neutral. Mark-all-read clears the visual emphasis but keeps history accessible — we never delete notification history without explicit user action.
Three distinct empty-state contexts with different recovery affordances. Critical for inbox-style surfaces (intake, dialogues, work orders) which start empty — and for filtered tables where the result set may be zero.
An empty state is not a single thing. First-time empty (zero state) is hopeful — the system has never had data, the user just arrived. The copy explains what the surface is for and offers a path to first value. No-data-yet is a steady-state — sources are connected, the system is watching, but nothing has triggered yet. The copy reassures the user that the system is working. Filtered-to-nothing is a recovery scenario — the user has narrowed too far. The copy points back to clearing filters.
Microcopy carries most of the weight. The first-time state is the one place we use a soft brand moment (the small clay V badge in the icon). Variants B and C use neutral stroke icons — they're recurring states, not landing moments.
Construction PMs use these surfaces under time pressure on real projects. Empty states must answer two questions instantly: why is this empty, and what do I do next?
Three error contexts with distinct recovery paths. Construction PMs work in the field on poor connectivity; offline / network-failure UX is operational, not theoretical.
/briefs/0142./briefs/0142.Each error has a different recovery path. 404 is "the thing you asked for isn't here" — the user navigates back. 500 is "our side broke" — the user retries or works in the source system. Network failure is "the connection is the problem" — the user waits or moves to offline-capable tools.
Microcopy is calm and specific. We own the failure ("on our side") rather than apologize. We tell the user what failed, when we last had good data, and how to keep working. Construction PMs don't have time for "Oops!"
The network-failure pattern has two presentations. Inline banner when partial data is still usable (showing last sync, allowing actions to queue). Full-page when nothing useful is reachable. Choose by severity, not by aesthetic preference.
Coordination layer principle in error UX: when Vecreal fails, the user's data is still in Procore / BIM 360 / their email. Every error variant offers a fallback to the source system — the user doesn't lose access to their own data when our layer hiccups.
Three loading contexts with distinct visual treatments. Section 26 covers streaming and phased progress for in-flight work; this section covers the moments before any content renders — cold app boot, route changes, and post-authentication first sync.
Three loading contexts, three visual treatments. Skeleton when the surface has rendered but data is in flight — the user sees layout-as-placeholder so the eventual content has no jarring shift. Full-page boot only for cold app start — the only place we surface the wordmark in a loading context (it's the "Vecreal is starting" brand moment). Initial data loading shows named steps because the user just connected sources and wants to see specifically what's happening ("indexed 1,247 documents").
Skeletons mirror the final layout precisely — widths, heights, gaps. This is what makes the transition from skeleton to content feel cohesive instead of jarring. A generic gray rectangle skeleton is decoration; a skeleton that matches the eventual stat-card grid is preparation.
No spinners. The streaming-dot pattern from Section 26 covers cases where work is happening; the named-step pattern in Variant C covers progress. Spinners say "something is loading" without saying what — we always say what.
When a user selects multiple rows in a table (Action Register, RFI Log, Submittal Log), a contextual toolbar appears above the table with the actions that can be applied to the selection. Replaces the standard filter bar while selection is active.
The toolbar replaces the filter bar (vs. floating below it or appearing as a separate strip) because the user is now in "act on these" mode, not "refine these" mode. One control surface at a time keeps the visual hierarchy clear.
Clay-soft background with a clay border makes the toolbar feel like an active brand moment without overpowering the table. The selected count badge in solid clay anchors the user's attention. Action buttons stay neutral (secondary style) because the brand emphasis is on selection, not on each individual action.
Destructive actions (Dismiss, Delete) are grouped to the right with a separator and use the error color in outline form — not filled, because filled red competes too aggressively with the selection-clay focus.
Section 30 (Tables) covers filter pills above the table. The drawer is the rich filter surface that opens when the user wants to refine on multiple categories at once — date ranges, multi-trade selection, custom sort, advanced filters. Slides in from the right edge.
Filter pills (Section 30) are the lightweight path: one or two filters, applied directly. The drawer is the heavy path: many filters, multiple categories, custom date range. They're complementary — the user picks the affordance that matches their intent.
The live count subtitle ("3 active · affects 142 rows") is the most important detail. It updates as the user toggles filters so the consequence is visible before they Apply. No commit-then-discover.
Filters do not auto-apply on every change. The user composes their filter set, sees the count update, then Apply commits. This is how Stripe, Linear, and Notion handle filter drawers — consistent with B2B power-tool conventions.
Three drag-and-drop contexts with distinct visual affordances and drop-target signals. Each must have a non-DnD alternative for keyboard + screen-reader + touch users — DnD is a speed-up, not the contract.
Three DnD contexts, three visual languages. File drop is the simplest — idle dashed border becomes clay dashed border on dragenter. Reorder needs a grip handle (so user knows which element is draggable) and a clear drop indicator line. Kanban uses the entire column as the drop target with clay-soft tinting and a clay header label.
The ghost (the floating dragged element) gets a slight rotation (-0.5 to -1 degree) and shadow-3. This is the standard convention from Trello, Linear, Notion — the rotation signals "this is in motion."
Every DnD operation has a non-gesture path. Keyboard reorder via Space + arrow keys. Touch via long-press. Tap-menu > "Move to In Review." The DnD is a speed-up for power users, not a barrier for everyone else.
Five small loading indicators that fill specific gaps not covered by Section 26 (streaming dots, pulse) or Section 53 (skeleton, named-step). Each lives at 14–18px and pairs with a text caption — we never run silent. Color treatment follows the locked clay rule: clay-light on light surfaces, clay-bright on dark.
RFI-0142 returned with revised structural specs that affect three open submittals.
Stack mech. confirmed the new spec is acceptable; Capital interiors needs 24h to repackage SUB-041 and SUB-043 before
RFI-0142 returned with revised structural specs that affect three open submittals.
Stack mech. confirmed the new spec is acceptable; Capital interiors needs 24h to repackage SUB-041 and SUB-043 before
The locked rule from Section 53 stands — no generic spinners, always say what's loading. These five additions don't replace that; they fill specific micro-gaps where the existing patterns are too heavy or too verbose. Quarter-ring is a button-level inline loader (skeleton can't live inside a button). Dash-ring is for ongoing chrome state like topbar sync (pulse-dot says "live", not "actively pulling"). Bars is for "analyzing" states unique to Vecreal (synthesis across sources). Shimmer is for streaming LLM-style output. Terminal cursor is for technical surfaces only.
Each loader is paired with a text caption. The caption is the contract; the loader is the visual reinforcement. Bars + "Analyzing 12 emails" tells the user both that Vecreal is busy AND what specifically. The same bars without a caption would violate the locked rule.
Color application follows the locked clay treatment exactly: clay-light on light, clay-bright on dark, status colors only when the operation has known semantic state (e.g., warning amber for slow sync, error red for failed retry). No fills — all loaders are stroke-based or wireframe, matching how clay shows up everywhere else in the system (outlined chips, accent borders, never solid clay backgrounds).
Motion specs are continuous loops outside the named --motion-* tokens (which describe transitions, not loops). All within Section 22's "no bounce" rule. Reduced-motion mode disables every animation and shows a static fallback at the same size.
Five new patterns building on Section 21.5. Each communicates "the system is doing something" without animation noise. References: Anthropic Claude (streaming dots), Vercel deployments (phased progress with checkmarks), Stripe / Mercury (highlight flash on row update, smooth number counter), Linear / Slack (vertical activity timeline with pulsing newest entry).
800ms back to default. Draws the eye to the change without animation noise. Stripe + Mercury pattern.
800ms back to default. Draws the eye to the change without animation noise. Stripe + Mercury pattern.
The system communicates "this is happening right now" through five quiet signals: streaming dots (work in progress), phased progress (multi-step task with checkmarks), flash (a row just updated), animated counter (number changed), activity feed (vertical timeline of changes).
Each pattern is restrained on purpose. The pulse is meaningful when it correlates with real activity. If everything pulses, nothing reads as live — pulse loses signal.
All animations honor prefers-reduced-motion — the dot remains static when reduced motion is requested.
Four data-viz patterns building on Section 21.6. Each shows trend or breakdown without requiring full charts. References: Mercury (sparklines next to balance numbers), GitHub (contribution heatmap), Stripe (multi-segment status bars + comparison blocks), Linear (issue type distribution).
Four lightweight data-viz patterns. Use these before reaching for a full chart library. Sparkline for "trend over time" next to a number. Multi-segment bar for "parts of a whole." Comparison block for two metrics side-by-side. Histogram for distribution.
All four use the same color tokens (success / warning / error / accent / neutral). The semantic of color stays consistent across patterns — green = good direction, red = bad direction, neutral for context.
Status colors and trend colors are distinct. Status describes the state of a thing (open, blocked); trend describes direction of change (up, down). They share some hex values but represent different roles.
Connects to Section 25 hover popovers. The small popover shows preview snippets; clicking any email or meeting opens the full content in a centered modal. Verbatim content throughout — no agent rewriting. Each modal has a footer "Quote in brief" CTA so the PM can pull a specific message or transcript moment back into the brief as a citation.
#1F1D1A) + soft-white text (#f7f8f8) + clay-bright icon (#C68070). Applies to any leading icon in primary CTA: +, send arrow, save check, share, etc. The clay icon is the brand signature accent moment — the eye lands there first, then reads the text. Trailing icons (dropdown caret in split buttons) follow same rule but at 85% opacity since they're secondary affordances. Rule holds on both light and dark surfaces (the bubble is dark in both modes).
#A87A2E light / #d4a960 dark) = flagged; red (#c95151) = overdue / blocked; green (#5DA17D) = healthy / approved.
Citations work in two layers. The popover (Section 25) shows a snippet preview; clicking any source in the popover opens the full source modal with verbatim content — whole email thread or full meeting transcript — no agent rewriting.
This is the "show your work" principle in action: the user can drill from a synthesized claim → popover preview → full source — and trust each layer.
Each modal has a footer "Quote in brief" CTA so the PM can pull a specific message or transcript moment back into the brief as a citation. Vecreal augments the workflow without owning the source data.
When a brief item references many sources across multiple categories, a flat list becomes hard to navigate. The reference tree visualizes the citation graph: central node (the item being investigated) connected to category nodes (Drawings / Emails / Meetings / Related RFIs / Addendums) which expand to show their items. All nodes are opaque (lines never bleed through). Lines terminate cleanly at node edges. Tree is fully expanded by default; click a category chevron to collapse. Click an item leaf to open in source (drawing → Procore, email → thread modal, meeting → transcript modal). Cross-references between items (e.g., an email citing a drawing) shown as dashed green connections. Coordination layer principle: Vecreal does not host or render the source content — we synthesize and navigate, the source-of-truth lives in Procore / Outlook / etc.
Most PMs work on horizontal monitors. The original vertical layout (above) puts the central node on the left and stacks categories down the right side — better for narrow / portrait screens. The horizontal layout below puts the central node at the top and spreads categories horizontally with items extending downward as columns. Same data, same interaction model, different orientation. Either pattern locked — use whichever fits the surface.
When a brief item references many sources across multiple categories, a flat citation list becomes hard to navigate. The tree visualizes the graph: central node (the item being investigated) connected to category nodes (Drawings, Emails, Meetings, RFIs, Addendums) which expand to show their items.
All nodes are opaque. Lines never bleed through. This was a real bug we caught in iteration — transparent nodes broke legibility when graph density increased.
Two layouts are locked: vertical tree (portrait monitors, dialog views) and horizontal flow (widescreen default, reads left-to-right). Most PM monitors are widescreen, so horizontal is the default in dashboard contexts.
Coordination layer: Vecreal does not host or render source content. We synthesize and navigate; source-of-truth lives in Procore / Outlook / etc. Click an item leaf → opens in source.
Drawing revisions, contract markups, spec changes — construction generates document-level diffs constantly. The diff UI surfaces what changed between versions with the warmth of the locked palette, not GitHub's bright red/green which would clash with the brand surface.
Construction's most common diff target isn't code — it's drawings, contracts, specs, cost estimates. The pattern still works (line-level adds/removes/changes) but the visual treatment matters: bright GitHub red/green collides with the warm clay palette. We use warm-tuned variants — the same #5DA17D / #c95151 semantic tokens as the rest of the system, paired with low-opacity backgrounds for the line-level wash.
Side-by-side is the default. When the file gets long enough that scrolling-in-sync becomes painful, the inline toggle lets the user switch. Either view runs the same change-detection — no information is lost in the toggle.
Version history is a rail below the diff. The current version (as of comparison) gets a clay-tinted bg so the user always knows their orientation. Clicking any history row swaps the comparison without leaving the surface.
Google-Docs-style comments that anchor to specific text in a document — spec sections, contract clauses, drawing markups, brief paragraphs. Distinct from threaded discussions (Section 42, free-floating thread): each anchored comment ties to a precise position in the source document.
Drywall installation shall comply with ASTM C 840 and the manufacturer's published instructions. All wall assemblies shall be Type X gypsum board, 5/8″ thickness, with metal stud framing at 16″ on center.
Acoustical ceiling tile shall be Armstrong Ultima or approved equal, suspended on standard 15/16″ T-bar grid. Grid shall be capable of supporting fixtures up to 50 lb per ASTM E 580.
All penetrations shall be sealed in accordance with the firestopping specifications. Sound transmission class (STC) rating shall be minimum 50 for all demising walls.
Coordination with mechanical contractor required for ceiling penetrations. See drawing A-501 r4 for revised penetration locations.
Drywall installation shall comply with ASTM C 840 and the manufacturer's published instructions. All wall assemblies shall be Type X gypsum board, 5/8″ thickness, with metal stud framing at 16″ on center.
Acoustical ceiling tile shall be Armstrong Ultima or approved equal, suspended on standard 15/16″ T-bar grid. Grid shall be capable of supporting fixtures up to 50 lb per ASTM E 580.
All penetrations shall be sealed in accordance with the firestopping specifications. Sound transmission class (STC) rating shall be minimum 50 for all demising walls.
Coordination with mechanical contractor required for ceiling penetrations. See drawing A-501 r4 for revised penetration locations.
Two annotation patterns coexist. Threaded discussions (Section 42) for free-floating conversations attached to a brief or RFI. Anchored comments for precision — the user is asking about a specific clause, dimension, or sentence. The visual treatment makes the role clear: anchored comments live in a margin rail with line-of-sight to their target text.
Default highlights are warm amber (the same #A87A2E / #d4a960 warning palette used for "flagged" states elsewhere). Clay is reserved for the active / selected comment — the one the user is currently reading or replying to. This preserves the locked rule: clay is brand, not annotation.
The quoted snippet at the top of every comment card is non-negotiable. It anchors the conversation in the original text, so a user joining the thread late can read the comment without scrolling back to find what was annotated.
Compact horizontal Gantt for showing project phases at a glance. Read-only initially — we ingest the schedule from Procore / MS Project / Primavera but don't edit it. Each phase row: name + status text + colored bar spanning weeks. Status colors map to our semantic system (green on-track, amber starts-soon, red blocked, slate awaiting). Today marker (clay-bright vertical line with halo) drops on the current week. Time-range toggle (Week / Month / Quarter) via segmented control. Legend in footer. References: Linear roadmap, Asana timeline, GitHub Projects.
Schedules are read-only in Vecreal. We ingest from Procore / MS Project / Primavera but never edit. The reason is the coordination-layer principle: the source-of-truth for schedule lives in the scheduler tool (P6, MSP) and the GC's scheduler maintains it. We surface it for context.
The strip is built in SVG, not CSS Grid. Grid had alignment glitches at certain widths; SVG with preserveAspectRatio stretches cleanly without sub-pixel issues.
Today marker is the visual anchor — clay-bright vertical line with halo at the current week. The user can scan past phases to see where today sits in the project arc.
Subcontractor profile is a summary surface, not a CRM. Top header: company identity (icon + name + status badge + CSI division + contact details). Stats strip with 4 reliability metrics: contract value, change orders (with $ delta), on-time rate (with YoY trend), RFI volume (with response avg). Coordination links section: hyperlinks to the actual artifacts in their source systems — subcontract in Procore, change orders, RFIs, submittals. Each link carries an external-link icon and "Opens in Procore" subtext. Reference: Stripe customer profile, Linear project sidebar.
The subcontractor profile is a summary surface, not a CRM. We surface project-relevant data only: this firm's presence on this project, their open SOW value, RFI velocity, submittal cycle time. We do not duplicate the firm-wide data that lives in the GC's subcontractor management system.
Coordination links section is the centerpiece. Every artifact (subcontract, change orders, RFIs, submittals) is hyperlinked to where it actually lives in Procore. Vecreal augments the navigation; the source-of-truth stays in the source system.
Stats strip uses 4 reliability metrics: contract value, change orders ($ delta), on-time rate (YoY trend), RFI volume (response avg). Mono numerics with right alignment for scannability.
Construction cost tables need to scan as financial statements: every number tabular-aligned, currency formatted with commas, variance color-coded (green under-budget with down-arrow, red over-budget with up-arrow, neutral on-track). Row backgrounds tint to match (subtle green or red wash) so the eye catches risk at a glance. Summary row at bottom with 2px border-top and bold totals. CSI division codes in mono left column. Reference: Stripe billing reports, Mercury account ledger, Procore budget views.
Cost tables read like financial statements. Every number tabular-aligned (mono with tabular-figures), currency comma-formatted, variance color-coded with leading arrow icon, and the row tinted subtly to match.
Subtle row tint is intentional — the eye catches risk at a glance without the table feeling alarmist. A bright red row across hundreds of cost codes would be noise; subtle wash + colored cell is signal.
CSI division code in mono left column. Summary row at bottom with 2px border-top and bold totals — the standard accounting visual cue.
Photo grid for site walkdowns and submittal references. Vecreal generates thumbnail previews from Procore Photos / local files but does not host the full image — clicking a tile opens the full-resolution photo in its source. Each thumbnail has an "Opens in Procore" affordance overlay (top-right) on hover. Metadata strip below thumbnail: title + date + photographer + location. The metadata is what we ingest and cite from; the photo itself stays where the GC stores it. Grid / List toggle for different scan modes.
Vecreal generates thumbnails from Procore Photos but does not host the full image. Click a tile → full-resolution photo opens in its source system. The metadata is what we ingest and cite from; the photo asset stays where the GC stores it.
This is the coordination-layer principle in its purest form: we don't own the data, we navigate it. If Vecreal disappeared tomorrow, every Procore photo is still where it was — we're a layer, not a destination.
Each thumbnail has "Opens in Procore" affordance overlay (top-right) on hover. Metadata strip below: title + date + photographer + location. Grid / List toggle for different scan modes.
Logs are a recurring construction surface. Same skeleton across types: ID column (mono) + description + status indicator (colored dot + label) + lifecycle timeline (4 small horizontal bars showing progress through stages, with completed in green, current in status color, future in subtle border color) + updated date + owner initial chip. The lifecycle column is the key innovation — it visualizes where in the workflow each item sits without needing to read text. Status (dot + label) tells you the current state; lifecycle tells you the journey. Filter / Open in Procore / New {type} buttons in toolbar. Specific column lists vary by log type, but the layout is consistent.
One log skeleton, five log types. Every log surface in construction (RFI, submittal, change order, subcontractor registry, daily report) shares the same scaffold: ID column + description + status indicator + lifecycle timeline + updated date + owner.
The lifecycle timeline is the key innovation. Four small horizontal bars showing progress through stages. Completed in green, current in status color, future in subtle border. The user sees not just "what state is this in" but "how far through the workflow."
Status (dot + label) tells you the current state. Lifecycle tells you the journey. They're distinct signals working together — together they replace what would otherwise be 5–6 status states.
Approval workflows are central to construction: change orders need pricing + owner sign-off, RFIs need engineer + architect approval, contracts need legal + executive signature. The pattern surfaces the entire workflow chain, the current step, who's blocking, and what the current user can do right now.
Vertical rail (vs. horizontal Section 37 stepper) because approval workflows are conversations, not progress bars. Each step has a person, a timestamp, sometimes a comment. The vertical layout gives each step room to surface that context without horizontal cramming.
The active step gets a clay-soft container so the current user instantly sees this is the action surface. The "this is you" callout makes self-identification trivial — especially important when multiple people are watching the same workflow.
The Approve button uses the locked icon-in-CTA pattern (clay check + soft white text on dark bubble). Reject is outlined error red — available but visually quieter than Approve. Reject always requires a comment; the rationale enters the audit trail.
Three system-level concerns that touch every component but don't belong to any one of them. Microcopy: voice and tone rules with do / don't examples drawn from real surfaces (confidence reasoning, error messages). Accessibility: keyboard navigation specs, focus rings, contrast guarantees, screen-reader semantics. Theme switcher: 3-way segmented (Light / Dark / System) in user preferences, persistent on profile, instant switching via CSS variables. The dark sidebar always stays dark — brand anchor is theme-independent.
Three system-level concerns that touch every component but don't belong to any one component. Microcopy is the voice (direct, calibrated, specific — never marketing). Accessibility is the WCAG 2.1 AA baseline that every surface inherits. Theme switcher is the mechanism by which dark/light gets selected without breaking brand presence.
The dark sidebar always stays dark, regardless of theme — brand anchor is theme-independent. This is what gives the product its consistent identity moment across both themes.
The four mobile-specific UI patterns that don't exist on desktop. Construction PMs work in the field on phones constantly — quick reads of an action register on a tablet between trades, a fast dismiss of a notification while walking the site. The desktop component library doesn't cover these gestures or the underlying spatial conventions.
Mobile is not just "desktop scaled down." The interaction model changes: thumb territory (bottom 60% of viewport easiest to reach), gesture vocabulary (swipe-left for actions, swipe-down to dismiss sheets), spatial conventions (sheets slide up from where the thumb is, drawers slide from edges). Each variant respects the locked design system but operates by mobile-native rules.
The dark sidebar stays dark in the drawer too. This is the single most important continuity: regardless of theme on the canvas, the sidebar is the brand anchor. On mobile drawer, that anchor is the first thing the user sees when they open navigation.
Swipe gestures are always optional. Every action reachable by swipe is also reachable by tap → bottom sheet. Construction PMs wear gloves, work in cold, have wet hands — gestures fail. The tap path is the contract; the swipe path is the speed-up.
Touch targets are 44×44px regardless of visual size. A 14×14 dismiss icon still has a 44×44 tap area via invisible padding. This is non-negotiable for field use.
Three onboarding patterns matching three intent levels. Welcome modal for the very first interaction (sets expectations + framing). Coachmarks for one-time discovery moments (introduce a non-obvious affordance). Walkthrough for multi-step setup that requires user input at each step.
Three patterns, three intent levels. The welcome modal is a single moment — it sets up the rest of the journey but doesn't teach the product. Coachmarks are surgical — one tip about one affordance at the moment the user encounters it (not bulk-loaded at start). The walkthrough is a guided setup — multi-step, with user input gating progress.
Skip is always visible. Construction PMs are senior, time-pressured, often skeptical of software. Forcing them through onboarding teaches them to dismiss us. Letting them skip and return when curious teaches them we respect their time.
Coachmark tooltip uses the inverse surface treatment to the page. On a light surface, the coachmark is dark (#1F1D1A) for emphasis. On a dark surface, it's light (#FFFFFF). This is the same pattern as the locked tooltip from Section 25.
The walkthrough's recommended option (Greenline Tower in the example) gets the clay-soft treatment + a "RECOMMENDED" eyebrow. Clay reads as "Vecreal suggests this" rather than "you must" — the user retains agency.
Compliance review surface for who-did-what-when across the project. Every approval, edit, dismissal, upload, and deletion is logged. Filterable, exportable, immutable. Connects to Section 59 (approvals always log) and Section 47 (uses log table pattern).
Audit logs are read for two reasons: compliance (annual SOC 2 review, owner audit, dispute resolution) and investigation ("who changed this and why?"). The visual treatment optimizes for both: action pills let the eye scan for unusual patterns; expandable rows surface before/after values for investigations.
Action pills use semantic color tokens consistent with the rest of the system — APPROVED is success-green, DISMISSED is error-red, EDITED is warning-amber, UPLOADED is info-slate. The user develops pattern recognition: a string of red rows for one user is a flag.
Before/after values use the same diff color treatment as Section 57 (red wash for before, green wash for after). This visual consistency means a user who's seen one diff surface intuits the other.
Immutable by design. Entries cannot be edited or deleted — that's the entire point. Even the user who created an entry can't modify it. The export includes a hash for verification when the log leaves the system.
A real Brief surface using only locked components from Sections 16, 21, 26, 27, 33, 36, 39. Sidebar (with bell+badge from Section 39), topbar (Search + bell + locked CTA), title block (with date pill + flagged count), 3 stat cards (Section 36 stat-card pattern), 3 brief items with different statuses (amber Flagged, green Resolved, red Overdue — tests status color clustering), Open Actions register (Section 16 pattern). Goal: see if components hold together when composed in real proximity, not just in isolation. Look for: status color saturation, surface contrast at multiple nested levels, eyebrow / count pill / status dot competing.
This is the cohesion test that surfaced design notes carried forward into Section 50. A real Brief surface composed from locked components only — sidebar, topbar, title block, stat cards, brief items, action register.
What this test caught: status color clustering creates a "rainbow" that reads as decoration, not signal — the fix was to order action rows by priority & recency, never by status. Surface contrast at multiple nested levels needed adjustment. Eyebrow / count pill / status dot competing for attention required tuning.
The cohesion review only happens once a real surface composes the components. Patterns that look right in isolation can clash when placed in proximity.
Each surface composes locked components from the system — no new components introduced. Goal: prove the components actually fit together when placed in real proximity, not just in isolation. Where tensions surface (status color clustering, surface-depth stacking, accent saturation), the cohesion review pass earlier flagged them. The demos below show what passing the cohesion test looks like at full surface scale.
priority-then-recency.
Seven surfaces that compose from locked components only. No new components introduced. This is the integration test that proves the system actually holds together at full surface scale.
Each demo carries its own design notes locked from the cohesion review (50.1 grouping rule, 50.2 outlined filter pills, 50.3 thin clay accent bar, 50.4 mono divider labels, 50.5 section eyebrow dividers, 50.6 project-specific subtitle, 50.7 trimmed trust list). These notes propagate back to engineering as locked rules.
If a new surface needs a component not in the catalog, the system has a gap — either escalate (add it to the catalog) or constrain the surface to existing primitives. Composition is the test that the system actually holds together.
Calibrated for "intelligent + premium + approachable" — neither cockpit-overload nor minimal-sparse. Modernized B2B, not bleeding-edge minimal.
The principles are the constitution. When the system doesn't answer a question, these do. They're calibrated for "intelligent + premium + approachable" — neither cockpit-overload nor minimal-sparse. Modernized B2B, not bleeding-edge minimal.
If a proposed change conflicts with a principle, the principle wins. They're the longest-lived layer of the system — tokens get tuned, components get extended, but principles stay constant.
Threaded discussions · generic pattern
Generic threaded-discussion pattern (saved for future use — the current product is passive synthesis without multi-party collaboration). Could apply to internal team comments on briefs, RFI back-and-forth when multi-party support arrives, document review discussions, or annotation-attached conversations. Top-level comment with full avatar (28px) + name + role + timestamp + body + actions (Reply / Pin / More). Nested replies indented with a vertical thread line in subtle border color, smaller avatars (24px) and tighter typography. Quoted snippets get a clay left-border + italic muted text for the quote + author attribution. Reactions (emoji + count) and inline file attachments shown as chips under the reply body. Compose-reply input always visible at the bottom of the thread with attach + cancel + send buttons. Send button uses locked icon-in-CTA pattern (clay icon + soft white text on black bubble).
Saved for future use. The current product is passive synthesis without multi-party collaboration — we don't track presence and don't host conversations. But the pattern is documented now so it's ready when collaborative features arrive: internal team comments on briefs, RFI back-and-forth, document review discussions.
One level of nesting only. Deeper conversations belong in a dedicated decision view, not threaded comments.
The send button uses the locked icon-in-CTA pattern (clay icon + soft white text on black bubble) — the only place clay appears on an action surface.