Skip to the content
FedM8 Design

Design 002 · Standard

Green and white

This is the FedM8 app. Warm paper, olive buttons, dark green words, serif headings and plain sans-serif controls. Chat comes first: members land in it, and every section carries a room. Build every new screen, tool or page from this page.

Use for
The app: Chat, Veterans, Contracts, Grants, Get Certified, Learn. Every new screen, tool or page.
Fonts
Newsreader (then Source Serif 4) for headings, DM Sans for everything else
Palette
Canvas #f5f3ec, paper #fffef9, olive #526547, ink #29372e
Reference sizes
Desktop 1440 × 1000 · phone 375 × 812 · light only
Source
DESIGN.md, assets/approved-design.css, assets/fedm8-room.css, assets/chat-words.js
Status
Standard · version 2026-10-21

How to use this page

  1. Check that this is the right design. The app and every new screen use 002. Brand marks, walkthrough videos, YouTube thumbnails, social posts and print use 001 Navy and gold.
  2. AI agents: read /design/002/tokens.json first. It holds every color, size, space, corner, word and rule on this page in a form a program can read.
  3. Find the part you need, read its Do and Don't, then copy its snippet. Change the words; keep the classes and the order.
  4. Before you ship, check the screen against Accessibility and the checklist in For AI agents.
  5. If this page and DESIGN.md disagree, DESIGN.md wins until the page is fixed. Say so in Comments.

Every sample on this page is fictional and carries a Sample label. The samples are drawn with page-only classes (they start with x2-) that copy the app's values. In the app, use the app classes and components named in each snippet.

Principles

Six rules carry the whole look. When a case is not covered here, pick what keeps the screen calm, honest and plain.

Calm

Warm paper, thin lines and one olive accent. Nothing blinks, slides in or shouts. Color marks a state, never decoration.

Light only

The design stays light even when a device asks for dark mode: dark green ink on paper, always.

One main action per view

One olive button per view, such as Post or Save and continue. Everything else is a ghost button or a link.

Honest states

Say what is true: loading, nothing yet, could not load, saved. No invented people, counts or scores. Leave a number out rather than guess it.

Plain words

Short sentences a busy owner reads once. Name the thing, then the next step. Define a term where it appears.

44px targets

Anything a finger presses is at least 44 by 44 pixels on a phone, with a visible 2px olive focus ring for the keyboard.

Do

  • Let the content lead. The frame stays quiet.
  • Keep the rules line, where a post goes and the acknowledgment in sight wherever they affect an action.
  • Put longer guidance in the help dialog behind the round ? button.
  • Show the real count, or no count.

Don't

  • Hero banners, gradients or glows. The one framed topic photo is placed by the app; never add your own.
  • A "live" dot on anything that does not update itself.
  • Sales words: unlock, supercharge, don't miss out.
  • A dark theme, or a second accent color.

Colors

Nine core tokens make every screen. The named extras come from the app's own files; use each one only for the job on its card. Press a hex value to copy it. The Tweak button changes the core tokens on this page, in your browser only.

Core tokens

Canvas--fd-bgThe page behind everything.
Paper--fd-paperCards, panels, the header, the dock, dialogs.
Soft--fd-softQuiet fills: chips, the selected room tab, hover in rooms.
Ink--fd-inkBody text and headings.
Muted--fd-mutedSecond lines, meta, hints, rail links at rest.
Line--fd-lineCard and panel edges, dividers. Too light for a field edge.
Olive--fd-greenThe one main button, the current rail bar, the focus ring.
Dark olive--fd-green-darkText on light fills: ghost buttons, the current rail item, room links.
Mint--fd-mintCount pills and the match percent.

Named extras

Strong line--fd-line-2Ghost button and dialog edges, the Sample frame.
Field edge--fd-field-lineInputs, selects and text boxes. Passes 3:1 on paper.
Rail hover--fd-hoverA rail link under the pointer.
Ghost hover--fd-hover-2A ghost button or header button under the pointer.
Current--fd-activeThe current rail item and room, a pressed choice, the P tile.
Selected edge--fd-selected-lineA selected card's border, the plan tile edge.
Callout--fd-calloutCallouts and the Match-M8 box.
Olive hover--fd-olive-hoverThe main button under the pointer.
Link--fd-linkUnderlined links in running text.
Label--fd-labelSmall uppercase group labels in the rail and My rooms.
Chip ink--fd-chip-inkText on fact chips.
Count ink--fd-count-inkNumbers on mint and the match percent.

Status and Chat

AI note--fd-ai-bgThe pinned FedM8 AI note in a room.
AI mark--fd-ai-markThe AI avatar and the Pinned pill.
Heads-up--fd-amberThe heads-up under a box, "Waiting on an answer".
Due--fd-due-bgThe due date chip.
Could not load--fd-fail-bgThe one line that says a read failed.
Refused--fd-red-softA post the server refused.
Danger text--fd-redRemove mine, field errors.
Online--fd-onlineThe online dot. Only where a real heartbeat backs it.
Answered--fd-answeredAnswered, This answered it, Saved.
Selection--fd-selectionSelected text and the tap highlight.

Contrast

Every text pair passes WCAG 2.2 AA (4.5:1). Edges a person must see, such as a field or the focus ring, pass 3:1. The light lines are decoration only.

PairLooks likeRatioUse
Ink on paperAa12.38:1Body text, titles
Ink on canvasAa11.26:1Page titles on the canvas
Muted on paperAa6.04:1Second lines, meta
Muted on canvasAa5.50:1Rail links at rest
Muted on softAa5.34:1Text in soft fills
Paper on olivePost6.28:1The main button
Paper on olive hoverPost8.45:1The main button under the pointer
Dark olive on currentAa7.79:1Current rail item, P tile
Link on paperAa7.19:1Links in running text
Label on canvasAA5.21:1Uppercase group labels
Chip ink on softAa7.26:1Fact chips
Count ink on mint126.86:1Count pills
Due ink on dueAa5.90:1Due date chip
Amber ink on heads-upAa8.03:1Heads-up, Waiting on an answer
Fail ink on could not loadAa9.33:1The could-not-load line
Danger text on paperAa8.10:1Remove mine, errors
Placeholder on whiteAa4.83:1Hint text inside a box
Focus ring on paperAa6.28:1Keyboard focus (3:1 needed)
Field edge on paperAa3.16:1Inputs, selects, text boxes (3:1 needed)
Line on paperAa1.36:1Decoration only: card edges, dividers
Strong line on paperAa1.52:1Decoration only: ghost button edges

A ghost button's text carries its meaning, so its light edge is fine. A field's edge is the only thing that shows where to type, so fields use the field edge #81976b.

Typography

Two kinds of letters do the work. A serif gives page, card and dialog titles a calm, bookish feel. DM Sans carries everything a person reads fast or presses. Rooms set their titles in Source Serif 4.

FamilyWeightsUseApp variable
Newsreader500, 600Page, panel and dialog titles, Chat home headings, serif card titles. Falls back to Source Serif 4, then Georgia.--font-serif
Source Serif 4600, 700Room titles, "People to say hi to", the phone room header. Second choice for every serif heading.none (written in the room files)
DM Sans400, 500, 600, 700Body, buttons, labels, chips, meta and numbers.--font-sans
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,[email protected],400;9..40,500;9..40,600;9..40,700&amp;family=Newsreader:opsz,[email protected],500;6..72,600&amp;family=Source+Serif+4:opsz,[email protected],600;8..60,700&amp;display=swap">

This is the link os.html uses, without Cormorant Garamond: that family belongs to the 001 wordmark, and nothing in this design uses it.

Type scale

WordmarkDM Sans 700 · 29/1 · −1px
Header brand; phone 22px
FedM8
Page titleNewsreader 500 · 31/1.18 · −0.8px
One per screen; phone 28/1.2
Contracts
Panel titleNewsreader 500 · 27/1.25 · −0.5px
An opened notice, a big panel
Sample · Help desk support, Fort Example
Dialog titleNewsreader 500 · 26/1.3 · −0.4px
Help and confirm dialogs
Remove your post?
Chat home headingNewsreader 600 · 21/1.25
Ask your people, the stream
Ask your people
Room titleSource Serif 4 600 · 19/1.3
Every room's head
Sample · Help desk support, Fort Example
Serif card titleNewsreader 600 · 17/1.3
Rail cards, Before your first post
Best contract for you
Notice titleDM Sans 500 · 16/1.4
Result cards
Sample · Grounds maintenance, Example Lake
Section headingDM Sans 600 · 15/1.45
Panel headings, h2 and h3 in panels
What the buyer wants
BodyDM Sans 400 · 14/1.55
Running text
Open a notice to read its brief, requirements and files. Public talk stays with that notice.
PostDM Sans 400 · 13.5/1.55
Words in a room
Has anyone walked this site before? I'm trying to learn how many people sit at the help desk today.
Second lineDM Sans 400 · 13/1.6 · muted
Panel text, hints
Example Command · Fort Example · Posted Oct 20
ControlDM Sans 500 · 12/1.4
Buttons, section tabs
Save this search
MetaDM Sans 400 · 11.5/1.5 · muted
Times, places, counts
2 h ago · NAICS 541519
Group labelDM Sans 600 · 10/1.5 · +1px · uppercase
Rail groups, My rooms
Opportunities
MetricDM Sans 500 · 25/1.2
One number in a metric card
3
Term with a meaninginherits · 1px dotted #7d97ab underline
Opens its plain meaning on tap, hover or focus
This notice is a set-aside for service-disabled veteran-owned small businesses.

Do

  • One page title per screen, in the serif.
  • Sentence case everywhere: "Ask your people", not "Ask Your People".
  • Keep numbers in DM Sans so they line up.

Don't

  • Serif for buttons, labels, chips or body text.
  • Uppercase anything except the small group labels.
  • Text below 10px, or bold for a whole paragraph.

Space and shape

Spacing moves in small steps. Corners stay small: 5px on controls, 6px in rooms, 8px on cards, 10px on dialogs, and full round only on pills. Shadows are barely there; the thin line does the work.

Spacing steps

4pxInside a chip: icon to word.
6pxA plan tile after its tool's name; chips in a row.
8pxBetween buttons; small stacks.
10pxBetween cards in a list and posts in a room.
12pxInside a post; the composer.
14pxInside a result card.
16pxBetween page head and tabs; the Match-M8 box.
20pxPanel sides; Chat home columns.
22pxBetween section tabs.
24pxTop of the content; dialog padding.
28pxHeader sides; left of the rail; right of the content.
30pxRail to content.
44pxThe smallest target a finger presses.

Corners

2pxThe current rail mark
4pxChips, scope tabs, plan tiles
5pxButtons, fields, rail links
6pxPosts, room buttons, callouts
8pxCards, panels, menus
10pxDialogs, the Match-M8 box
14px topPhone bottom sheets
RoundPills: Talk · N, counts, Follow

Shadows

Card0 1px 3px #29372e04
Menu0 8px 25px #29372e16
Room ⋯ menu0 8px 24px #29372e2e
Dialog0 18px 80px #1f2f2540
Phone dock0 -2px 12px #29372e06
New replies pill0 2px 6px #29372e33

Layout

Two reference sizes: desktop 1440 × 1000 and phone 375 × 812. Desktop has a 64px header, a 190px section rail and content that starts about 248px from the left. The phone swaps the rail for a six-item dock at the bottom and keeps one column.

Desktop: 1440 × 1000

PartSizeNotes
Header64px tall · 28px sides · paper · 1px line belowLogo 40px and the FedM8 wordmark on the left; Inbox and My Profile as 44px icon buttons on the right.
Section rail190px wide · 28px from the leftGroups Community, Opportunities and Readiness; Your workspace below a line.
Gap30pxBetween the rail and the content.
Contentfrom about 248px · 24px top · 28px right · 1454px widestPage head, then tabs, then the work.
Page head31px serif title + 44px round ? buttonThe ? opens the help dialog. No paragraph under the title unless it changes an action.
Public scope tabs48px strip · 44px buttonsDiscussions, NAICS rooms, Find teammates, Live All (Read only).
Section tabs44px tall · 22px apart · 2px olive underline on the current oneMore tools holds the specialist tools.
Topic photo6px paper frame · 1px line · 8px corners · image 170px to 230px tall with 4px corners, cropped to fill. On Chat home: 5px frame, 118px image. On a phone: 5px frame, 96px image.Placed by approved-design.js with its own alt text. Never add one yourself.

Desktop, real pixels

fedm8.com/os.html#/opportunities
Community Chat Veterans Opportunities Contracts Grants Readiness Get Certified Learn
Your workspace People & connections My Profile All tools

Contracts

2 sample notices

SolicitationDue Nov 14SDVOSB set-asideNAICS 541519

Sample · Help desk support, Fort Example

Example Command · Fort Example

Talk · 12Posted Oct 20
SolicitationDue Dec 2Total small businessNAICS 561730

Sample · Grounds maintenance, Example Lake

Example District · Example Lake

Talk · 3Posted Oct 18

On a small screen, scroll the sample sideways to see all of it.

Phone: 375 × 812

Chat

Public

Ask your people

Public · Keep prices, bids and nonpublic information out.

This will post in: your NAICS 541519 room ·

in General · 2h

Has anyone done a site visit at Fort Example? Wondering how far the help desk is from the gate.

2 repliesHelpful · M8 4Open

Do

  • The rail on desktop, the dock on the phone. Never both.
  • One column on the phone, with no sideways scrolling.
  • Short scope labels on the phone: Discussions, NAICS, People, Live All.
  • Leave room under the last post so a pinned box never covers it.

Don't

  • A floating chat button over the dock.
  • A hero band or a photo header of your own. The app places one small framed topic photo where it fits.
  • A second rail, or a menu order other than Chat, Veterans, Contracts, Grants, Get Certified, Learn.

Buttons and fields

Every control is at least 44px tall, with 5px corners and DM Sans 500 at 12px. One olive main button per view; everything else is a ghost button or a link. Every field has a label above it and the olive field edge.

Buttons

Main
Main, hover
Ghost
Ghost, hover
Danger, in a confirm step
Busy
Text linkSee plans
KindLooksUse it forApp class
MainPaper on olive #526547; hover #3e5234The one action that moves the work: Post, Save and continue, Search.btn
GhostDark olive on paper, 1px #cbd4bf edge; hover #edf1e5, edge #aebf9cEvery other action: Cancel, Save this search, See all past awards.btn ghost
Danger#9a302d on #fff5f1, edge #d9b2a9Only the last step of something that cannot be undone.btn danger
BusyThe same button at 55% to 60%Only while a request is in flight. To stop an early press, keep the button live and say what is missing.disabled
Text link#435e36, 500, underlinedGoing somewhere: See plans, Check what you do.a

Fields

Your posts show this name when you post as your company.

A NAICS code is 6 digits. Fix it or leave it empty.

Acknowledgment
PartValue
Field44px tall · 8px 10px padding · 5px corners · 1px #81976b edge · paper · DM Sans 13px. Inside #main the app gives every field this edge.
Text boxThe same, 88px or more, grows with the words. Room boxes are white, 6px corners, 15px text.
LabelAbove the field · DM Sans 600 · 12px · ink
HintUnder the field · 12px · muted · linked with aria-describedby
ErrorUnder the field · 12.5px · #8f2d22; the field gets a 2px ink edge and aria-invalid="true"
Placeholder#6a7565. An example, never the label.
Checkbox20px (18px in rooms) · olive accent · the words are the label, so the whole line is the target
PhoneField text is 16px so the phone does not zoom in.

Focus ring

Talk · 12

App-wide: a 3px olive outline #526547, 3px outside the control; fields keep it 1px outside. Inside rooms, chips and plan tiles it is 2px, 2px outside. It passes 3:1 on paper and canvas. Press Tab on this page to see the real ring on any sample control.

<button type="button" class="btn">Save and continue</button>
<button type="button" class="btn ghost">Save this search</button>
<button type="button" class="btn danger">Remove</button>

<label for="company">Company name</label>
<input id="company" type="text" aria-describedby="company-hint">
<p id="company-hint" class="muted">Your posts show this name when you post as your company.</p>

<label><input type="checkbox"> I'm not working on this buy for the government, and I won't share nonpublic information.</label>

Do

  • Put the main button last in its row.
  • Name buttons with a verb and the thing: Save this search, Post reply.
  • Say what a field needs before someone types, and what went wrong after, right under the field.
  • Give icon-only buttons an aria-label.

Don't

  • Two olive buttons side by side.
  • A placeholder as the only label.
  • Red for anything except errors and removing.
  • Remove the focus outline without a stronger one in its place.

Chips and counts

A chip states one fact. Most chips are quiet: soft fill, thin line, 11px words. Color is saved for meaning: the Talk door, a count, a due date, an answer and a host.

FactSDVOSB set-aside
CodeNAICS 541519
Due dateDue Nov 14
Room kindContract
Grant roomGrant
Code roomCode 541519
Talk doorTalk · 12
Talk door, no posts yetTalk · 0
People in4 in
Count12
New in a room3 new
Teaming tagNeeds a sub
PinnedPinned
Your own postYou
Server-set labelFounding crew
Answered✓ Answered
WaitingWaiting on an answer
From SAM dataSAM lists SDVOSB
Room hostFedM8 AI
Plan tilesBasic plan tilePro plan tile
ChipValueRule
Fact3px 7px · 4px corners · #eef1e7 · #42533a · 11pxSet-aside, code, place, notice type. Plain words, no color.
Due date#825322 on #fff2d8, edge #eddbb6Only the response deadline.
Room kind22px · round · soft · dark olive 600 · 11.5px; grant #e9f4ea; code #f6efdcContract, Grant, Award, Lesson, Code 541519, Room, Certification. First thing in a room's head.
Talk · N34px · round · 1px olive edge · dark olive 600 · 13px · speech-bubble iconThe door into a room, wherever a contract, grant or code appears. The number is posts. No number when the count did not load.
Count#31553b on mint #d9eddd, edge #c5ddc9, 600A real count only.
Answered#2f6b3a on #e6f1e3, edge #b9d4b3The thread's asker marked a reply. Never set by FedM8.
Waiting#5c4708 on #fbf3dcA question with no answer for over a day.
Founding crew, Staff, GreeterOlive edge on #eef2e6Set by the server, never typed by the poster.
SAM lists SDVOSB#22502a on #e3f0e3Only from SAM data for a verified UEI. Never from a profile.
FedM8 AIPaper on dark olive, 4px corners, 700The room host. Always with "not a member".
// A "Talk · N" door for a list row. Counts fill in from one batched read.
var door = FedM8TalkDoors.chip(document, {
  item: FedM8TalkDoors.itemFor("notice", noticeId),   // "grant" -> "grant:<id>", "naics" -> "naics:<code>"
  signedIn: !!ctx.user,
  title: notice.title
});
row.appendChild(door);
FedM8TalkDoors.counts([door.getAttribute("data-td-item")], { client: ctx.sb, user: ctx.user && ctx.user.id })
  .then(function (map) { FedM8TalkDoors.fill(list, map); });

Do

  • One fact per chip, in plain words.
  • Keep chips in one row that wraps.
  • Let the door's aria-label name the room and the count: "Talk about …, 12 posts".

Don't

  • Make a chip a button unless it opens something.
  • Invent a status color, or turn a fact chip green to look good.
  • Show a "SAM lists" chip from anything but SAM data.

Cards and panels

Paper on canvas, a 1px line, 8px corners and almost no shadow. A panel holds a tool or a form. A card holds one thing in a list. A selected card gets a darker edge and a 2px olive bar inside its left edge, never a fill.

What the buyer wants

Help desk support for about 400 people, Monday to Friday, 7 a.m. to 6 p.m. Tier 1 and Tier 2 calls. A site visit on Nov 3.

Due Dec 2Total small businessNAICS 561730

Sample · Grounds maintenance, Example Lake

Example District · Example Lake

Talk · 3Posted Oct 18
Due Nov 14SDVOSB set-asideNAICS 541519

Sample · Help desk support, Fort Example

Example Command · Fort Example

Talk · 12Selected

Metrics, callouts and dialogs

Open pursuits

3

1 due this week

Saved searches

2

5 new notices since Monday

Rooms you follow

4

2 with new posts

Ask the contracting officer about the requirement, in writing.

The short version

The buyer wants one firm to run the help desk for about 400 people. Small businesses with an SDVOSB certification can bid.

Contracts help

Search by keyword or NAICS. Open a notice to read its brief, requirements and files. Public discussion stays with that notice. Keep bid files, pricing and proposal work in your private pursuit.

PartValueApp class
Panel18px 20px padding · 14px below · heading DM Sans 600 15px · text 13px mutedpanel inside #page-content
Card14px padding · 10px apart · title DM Sans 500 16px · meta 12px mutedcard
Selected cardEdge #b8c5aa · box-shadow: inset 2px 0 #81976bsel on the card
MetricLabel 10px 600 +0.7px uppercase muted · number DM Sans 500 25px · two across on the phonemetrics > metric > lbl + val
Callout12px · 6px corners · #f0f4e8 · edge #cfd8c2page-specific
Lede#eef1e7 · 2px #81976b bar on the left · 11px 13pxpage-specific
DialogPaper · 10px corners · 1px #cbd4bf · 24px padding · up to 520px · shadow 0 18px 80px #1f2f2540 · scrim #23302366 · 44px close buttonnative <dialog>; the help dialog is drawn for you
<section class="panel">
  <h2>What the buyer wants</h2>
  <p>Help desk support for about 400 people, Monday to Friday.</p>
  <button type="button" class="btn ghost">Open the files</button>
</section>

<div class="metrics">
  <div class="metric"><div class="lbl">Open pursuits</div><div class="val">3</div></div>
</div>

Do

  • One idea per panel, with a plain heading.
  • Show selection with the edge and the inside bar.
  • Close a dialog with ×, Escape and Cancel, and return focus to what opened it.

Don't

  • Cards inside cards inside cards.
  • Heavy shadows, colored card tops or gradients (Win Kit's olive top line is the one exception).
  • A dialog for something a line of text can say.

Chat

Chat comes first. Members land on Chat home, and every contract, grant and NAICS code has its own room. One component draws every room, so each one has the same head, tabs, actions, ⋯ menu and box. The rules line, where a post goes and the box stay in sight while someone writes.

Public name
Contract Chat
In the app
Chat, at /os.html#/talk
A conversation
A room. Rooms hold posts; posts hold replies.
The action
Post. In a reply box: Post reply.
Room host
FedM8 AI · not a member
Drawn by
assets/chat-home.js and assets/fedm8-room.js; every word in assets/chat-words.js

Chat home on a desktop

Three columns: My rooms, then Ask your people above the new posts, then one card at a time. The sample is the whole 1440 × 1000 screen, scaled down to fit.

fedm8.com/os.html#/talk
Community Chat Veterans Opportunities Contracts Grants Readiness Get Certified Learn
Your workspace People & connections My Profile All tools

Chat

Public

My rooms

Rooms

Your codes

My conversations

  • Marcus T.

New means posted in the last 24 hours.

Ask your people

Public · Keep prices, bids and nonpublic information out.

This will post in: your NAICS 541519 room ·

2 new posts left today · replies are open

New in your rooms

Unanswered near you

“Has anyone cleaned the Example Lake visitor center? Do they want day porters or only a night crew?”

NAICS 561720 · 1d · no replies yet

Waiting over a day. Can you answer it?

in General · 2h

Has anyone done a site visit at Fort Example? Wondering how far the help desk is from the gate.

2 repliesHelpful · M8 4Open
Founding crewin NAICS 541519 · 5h

We're a prime on a help desk recompete and need a sub with Tier 2 network support near Fort Example. Roles only here; we can talk more in a private chat.

1 replyOpen
in New here · 6h

Hi all. I run a two-person IT shop and I'm learning how set-asides work. Glad to be here.

4 repliesHelpful · M8 6Open

Topic photo
placed by the app

Best contract for you

Sample · Help desk support, Fort Example

Example Command · NAICS 541519

Due Nov 14SDVOSB set-aside82% match

12 posts about it

Basic shows all your matches, with fit and summaries. See plans

1 of 3

On a small screen, scroll the sample sideways to see all of it.

PartValueWords
GridMy rooms 190px to 220px · middle takes the rest · rail 240px to 290px · 16px between rows, 20px between columns · 1180px widest. My rooms and the rail stay in place 82px from the top while the middle scrolls.none
My roomsPaper card · rows 38px, DM Sans 13px · current row #e4ead8 with a 3px olive bar inside its left edge · group titles 11.5px muted · "N new" pill #e6ecddMy rooms · Rooms · Your codes · My conversations · Messages · More rooms · New means posted in the last 24 hours.
Ask your peoplePaper card, 16px 18px · Newsreader 600 21px · rules line 12px above a white box (#b9c4ab edge, 6px corners, 72px tall) · destination 13px · Post 40px, olivePublic · Keep prices, bids and nonpublic information out. · This will post in: your NAICS 541519 room · Change · 2 new posts left today · replies are open · Post
New in your roomsCards 13px 15px, 8px corners, 10px apart · 34px initials · name 600 13.5px · meta 12px · words 14px, five lines at most · foot 12.5pxin General · 2h · 2 replies · Helpful · M8 4 · ⋯ · Open
Unanswered near you#f7f0dc, edge #e3d6ae, title 600 14px #5a4a17The question in quotes · NAICS 561720 · 1d · no replies yet · Waiting over a day. Can you answer it? · Answer
Right railThe topic photo (118px), then one card at a time · kicker #6b5a1f · Newsreader 600 17px title · chips 11.5px roundBest contract for you · Who's around · Wins and milestones · Say hello · Help a newcomer · 1 of 3 · Next: Who's around
761px to 1180pxTwo columns. The rail moves under the stream and scrolls with the page.none
Phone, 760px and underOne column: Ask, Say hello (new members), My rooms as one sideways row of 44px pills, the stream, the rail. No topic photo.Group titles drop out; the rooms keep their names.
// Chat home is drawn for you on #/talk. assets/commons-feed.js calls it:
FedM8ChatHome.render(root, ctx, isCurrent);   // ctx: { sb, user, account, plan }

// Every word comes from one file. Read it; never retype it.
var W = FedM8ChatWords;
W.chatHome.askTitle;      // "Ask your people"
W.chatHome.streamTitle;   // "New in your rooms"
W.rulesShort;             // "Public · Keep prices, bids and nonpublic information out."
W.helpfulLabel(4);        // "Helpful · M8 4"   (just "Helpful" at 0)

A room

Every contract, grant, award, NAICS code and topic gets this same room. Here is a contract room as a member sees it, with the ⋯ menu drawn open on Lena K.'s reply.

Contract

Sample · Help desk support, Fort Example

Example Command · Fort Example · Due Nov 14

We'll tell you when someone answers.
FedM8 AIPinnedAI brief

The buyer wants one firm to run a help desk for about 400 people, Monday to Friday, 7 a.m. to 6 p.m. It is set aside for SDVOSB firms. Questions are due Nov 4 and offers Nov 14.

FedM8 AIWaiting on an answer · pinned · not a member

1 question in this room is still waiting on an answer. If you know, reply.

Sub · Veteran (self-reported)✓ Answered2h

Has anyone done a site visit at Fort Example? Wondering how far the help desk is from the gate, and how long badges take.

2 replies
PrimeSAM lists SDVOSB1h

I walked it last year. The help desk is in Building 12, about ten minutes from the main gate. Ask the contracting officer in writing what the visit covers.

✓ This answered it · marked by Dana R.

1 reply
Sub · Veteran (self-reported)45m

Thanks, that helps.

Independent specialist30m

Badges took me about a week there. Start the form early.

People you hid

Founding crewPrimeWaiting on an answerOct 19

Anyone here with Tier 2 network support near Fort Example? We're a prime on this one and want a sub for the network side.

Talk about the work and who you need. Keep prices, bids and contact details out of open rooms. Share prices only privately with teammates, under a signed teaming agreement. Ask the contracting officer about the requirement, in writing.

2 new posts left today · replies are open

Looking for:

Roles only. Keep prices, rates and whether you'll bid out of the room.

Public · this conversation

Room parts

Your own post, ⋯ open

SubYou12m

We can cover Tier 1 nights if a prime needs it. Happy to talk roles in a private chat.

Helpful · M8 3

You follow this thread because you posted it. We'll tell you when someone answers.

A reply box

18 replies left today

Public reply

A NAICS code room's Monday note

FedM8 AIMonday note · pinned · not a member

Last 7 days in 541519: 6 new notices, 2 due in 10 days and 1 grant that matched by words.

Sources: SAM.gov, Grants.gov. Built Mon 9:00 AM ET.

Catch up, on a long thread

Catch up. Members say the help desk sits in Building 12, about ten minutes from the main gate, and that badges take about a week.

FedM8 AI · not a member · picked by members' Helpful marks.

Held while FedM8 looks

Youjust now

Hidden while FedM8 reviews it. Only you can see it.

Does anyone know who holds the current help desk contract?

Live All, read only

Live All is read-only. To post, pick This one or the code room.

PartValueWords
HeadKind chip (22px, round, soft) · title Source Serif 4 600 19px · second line 12.5px muted · Follow (36px, round, olive edge) and its hint on the rightContract, Grant, Award, Lesson, Code 541519, Room, Member, Certification · Follow · Following
Scope tabs36px (44px on a phone) · 6px corners · 13px muted; the chosen one gets the soft fill, a line edge and dark olive 600. In the app: role="tablist", arrow keys, Home and End.This contract · NAICS 541519 · Live All. A grant: This grant · NAICS 541519 (guessed). A code room: This code.
New replies pillOlive, round, 34px, 600 13px, shadow 0 2px 6px #29372e33, centered and held 76px from the top. Checks every 30 seconds while the tab is visible. It never moves the page.3 new replies · Show · 1 new post · Show
Pinned note#fbf7e9, edge #eadfb8 · AI initials on #efe2b5FedM8 AI · Pinned · AI brief. A code room: Weekly note · From public contract counts.
Host cardPaper · 3px olive left edge · 6px corners · chip paper on dark olive, 4px corners, 700 · lead line 15.5px 650 · links 13.5px with 1px lines betweenMonday note, Waiting on an answer, Office hours, Friday prompt, New today · "pinned · not a member" · Sources: … Built Mon 9:00 AM ET.
Post12px padding · 1px line · 6px corners · 10px apart · 30px initials · name 600 13px dark olive · meta and time 11.5px muted · words 13.5px. Your own post #fbfcf6; held posts dashed.just now · 12m · 2h · Oct 19 · You · Hidden while FedM8 reviews it. Only you can see it.
Actions32px (44px on a phone) · 6px corners · 12.5px dark olive · Helpful marked: #e8eedf, edge #c9d4bb, 600. Your own post shows its count as plain words, no button.Helpful · M8 4 · Reply · Follow · Check the record · I'm interested · 2 · ⋯
⋯ menu220px · paper · 8px corners · shadow 0 8px 24px #29372e2e · 40px rows. A bottom sheet on a phone. In the app: role="menu", arrow keys, Escape; Tab closes it.Someone else's post: Report · Hide this person · People you hid. Your post: Remove mine (your post).
Repliesdetails with a 2px line on the left, 12px in · up to 8 levels; Reply leaves at the 8th · stays open or closed in this tab2 replies · 1 reply
AnsweredReply edge #a9c9a2 on #f2f8ef · line #2f6b3a 600, under the words✓ Answered · This answered it · marked by Dana R. · You marked this as the answer.
BoxRules line 12.5px above the box · white box, 15px words, #c9d1bd edge, 6px corners, 72px · cap 12px · Post 36px olive (44px on a phone) · destination 12px on the left of PostAdd to the conversation · Ask about this contract, or find a teammate. · Public · this conversation · Post · Reply to Dana R. · Write a reply… · Public reply · Post reply · Cancel
Looking forRound chips 32px (44px on a phone); chosen: olive edge, #e5ecdb, 600Need a sub · Can sub · Need a prime · Independent specialist. A grant: Lead applicant · Partner · Independent specialist.
// One call draws a whole room: head, tabs, posts, replies, ⋯ menus, the box.
var room = FedM8Room.mount(host, {
  ctx: ctx,                         // { sb, user, account, plan }
  item: noticeId,                   // "grant:<id>" for a grant, "naics:541519" for a code room
  kind: "notice",                   // "grant", "code", "award", "cert", "room"
  code: "541519",                   // the NAICS tab
  label: notice.title,
  header: true, title: notice.title, sub: "Example Command · Fort Example · Due Nov 14",
  stickyCompose: true,              // on a phone the box is pinned above the dock
  empty: FedM8ChatWords.empty
});
room.ready.then(function () { /* posts are drawn */ });

// The same actions and ⋯ menu on a post shown outside a room (Chat home does this):
var acts = FedM8Room.actions(post, { ctx: ctx, kind: "post", helpful: true });

// Follow in a header row, with its hint:
head.appendChild(FedM8Follow.button(ctx, noticeId, { hint: true, what: "conversation" }));

Do

  • Mount every conversation with FedM8Room.mount, and link to it with a Talk door.
  • Keep the rules line above every box and where the post goes next to Post.
  • Ask for the acknowledgment before a first post in a contract or grant room.
  • Keep unsent words in the box after any failure, and say "Not sent yet (kept in this tab)".
  • Let the asker mark the answer. Show "✓ Answered" on the thread.

Don't

  • Build a second chat, chat bubbles or a floating chat button.
  • Typing dots, read receipts or a "live" dot in a room.
  • Move the page when new posts arrive. Show the pill.
  • Give FedM8 AI a Helpful button, a profile or a member's voice. It is always "not a member".
  • Hide Report or Hide this person behind a plan.

Who's here and People to say hi to

Contract and grant rooms open with one card above the posts. It counts who raised a hand to team, lets a member raise theirs, and suggests up to three people to say hi to, each with one reason. It never shows who is viewing a notice.

3 raised a hand · 2 primes, 1 independent specialist · no sub yet · 1 online now

People to say hi to

  • Marcus T.Prime · SAM lists SDVOSB

    Raised a hand as a prime.

    Online now

  • Example Network ServicesPrime

    Raised a hand as a prime.

  • Lena K.Independent specialist

    Raised a hand as an independent specialist.

PartValueWords
CardPaper · 1px line · 8px corners · 12px 14px · first thing in the room, above the postsnone
Count line13.5px ink, parts joined with " · " · the count 700 · the role split muted · the gap in a round #e5ecdb pill · the online count after an 8px #2f7d4a dot · Match-M8 adds muted italic3 raised a hand · 2 primes, 1 independent specialist · no sub yet · 1 online now · 1 matched by Match-M8, not confirmed. A grant: lead applicants, partners, no partner yet, no lead applicant yet. A code room: 12 members work in 541519. Nobody yet: Nobody has raised a hand yet · No members list 541519 yet.
I'm in asOne joined row, 1px line, 8px corners · label 12.5px muted · choices 36px (44px and full width on a phone), dark olive 600 13px · the chosen one olive with white words · contract and grant rooms onlyPrime · Sub · Independent specialist. A grant: Lead applicant · Partner · Independent specialist.
People to say hi toTitle Source Serif 4 600 16px · up to three cards, 190px at least, #fdfdf8, 6px corners · 32px initials with a 9px green dot when online · name 600 13.5px, badges 11.5px muted · one reason 12.5px · Say hi olive, 36px (44px on a phone), opens a private chat with a first line readyPeople to say hi to · Hide · Prime · SAM lists SDVOSB · Online now · Say hi · Show people to say hi to. First line: Hi Marcus, I saw you raised a hand on this one. Want to talk about teaming?
Consent line11.5px muted, under the cards, every timeOnly members listed in the directory who turned on Suggest me in My Profile. FedM8 never shows who is viewing a notice.
Free memberThe count line shows; names and cards do notNames show on Basic. See plans
Phone, 640px and underOne line of names replaces the cards; See why opens themSay hi: Marcus · Example Network Services · Lena · See why · Show less · Hide
// Who's here goes first in a contract, grant or code room. The room page mounts it:
FedM8Teaming.whosHere(hereHost, ctx, noticeId, {
  item: notice, title: notice.title,
  onDone: function () { room.reload(); }      // after the member raises a hand
});

// Item keys: a notice id, "grant:<id>" for a grant, "naics:541519" for a code room.
FedM8Teaming.tagKind("naics:541519");          // "code"

Before your first post

A member with no public name yet sees this card the first time they press Post. It opens inside the box, right above Post, and their words stay where they are. Here a company is posting for the first time.

Talk about the work and who you need. Keep prices, bids and contact details out of open rooms. Share prices only privately with teammates, under a signed teaming agreement. Ask the contracting officer about the requirement, in writing.

Before your first post

People see this next to your post. You can change it any time in My Profile.

Post as

Shows as: Example Help Desk LLC

We team as

Prime needs a SAM-verified UEI. Add yours later in My Profile.

Your codes

One quick step before your first post. Check how your name shows, then press Post again. Tick the box too.

3 new posts left today · replies are open

Public · this conversation
PartValueWords
Card#f6f8f1 · edge #cbd4bf · 8px corners · 14px 16px · 560px at most · title Newsreader 600 17px · line 13px muted. In the app a section named by its h3 title.Before your first post · People see this next to your post. You can change it any time in My Profile. A private chat says "message".
ChoicesRound, 38px (44px on a phone), white, #b9c4ab edge · chosen: #e4ead8, olive edge, dark olive 600 · not open yet: dashed, #f1f2ee, #7d8778, with the reason linked to itPost as: Me · My company. A person: What fits you: Just learning · Independent specialist. A company: We team as: Sub · Both · Prime.
NameBox 40px (44px on a phone), white, #b9c4ab edge, 5px corners, 420px at most · the preview under it 13px dark olive 600, read aloud as it changesYour name or Company name · Shows as: Example Help Desk LLC · Shows as: (type a name)
Codes38px round chips, each with a checkbox, ticked · the add box 140pxYour codes · 541519 (from sign-up) · Add a code (6 digits, optional) · No codes yet. Add one if you know it.
VeteranVeteran accounts only, ticked from the sign-up answer. Never asked of anyone else.Show Veteran (self-reported) on my posts
Step line#fbf7ea · edge #d9d2b6 · 6px corners · 13px · just above Post · read aloud (role="status")One quick step before your first post. Check how your name shows, then press Post again. · Tick the box too. · Saving how your name shows… · Saved. Your posts show as Example Help Desk LLC.
ProblemsThe same line, with focus moved to the fieldEnter a name people see, 2 to 120 characters. · A NAICS code is 6 digits. Fix it or leave it empty. · We couldn't save your name. … Your words are still in the box.
After the first postOne quiet line with one linkFinish your card so primes can find you. · Finish your card
// A room's box does this already. For a box of your own:
var fp = FedM8FirstPost.create(ctx, { button: "Post", noun: "post" });
postButton.addEventListener("click", function () {
  if (!fp.node.isConnected) form.insertBefore(fp.node, buttonRow);   // right above Post
  // First press: shows the card and the step line, resolves false.
  // Next press: checks and saves the name, resolves true. The words in the box are never touched.
  fp.run(statusLine, "Post").then(function (ok) { if (ok) send(); });
});
fp.finish(composeHost);   // after the first post: "Finish your card so primes can find you."

Talk doors

A Talk door opens a room from anywhere else: a notice card, a grant card, a grant page, a lesson. It says how many posts the room holds and, when known, who is in. Talking is free on every plan, so a door never carries a plan tile.

ContractDue Nov 14SDVOSB set-aside

Sample · Help desk support, Fort Example

Example Command · NAICS 541519

Talk · 124 in · 1 prime

Marcus T.: I walked it last year.

GrantCloses Dec 9

Sample · Rural IT skills grant

Example Workforce Office · Grants.gov

Talk · 42 in

A grant's own page

Sample · Rural IT skills grant

Example Workforce Office · Closes Dec 9

The same row on a phone

DoorLookWords
Talk chip34px (44px on a phone) · round · 1px olive edge, no fill · dark olive 600 13px · 14px speech-bubble icon · hover #eef2e6 · count in tabular figures. The one main door on a page may be filled olive.Talk · 12. Until the count loads: Talk. Read aloud: "Talk about <title>, 12 posts"; signed out: "Sign in to talk about <title>, 12 posts".
Who is in12.5px muted, right after the chip4 in · 1 prime · 2 in
Latest wordsOn a card: a 1px line above, then one line, 12.5px muted, cut with "…" · the name 600 ink · the first sentence, 80 characters at mostMarcus T.: I walked it last year.
Grant page row44px buttons · 0 16px · 6px corners · 600 14px · Talk olive with paper words; the rest paper with a #81976b edge and dark olive words · hover #eef2e6 · one group named "Talk, team up or watch this grant"Talk about this grant · 4 · Find a partner · Watch. Signed out: Sign in to Watch one, and to talk about it. Talking is free on every plan.
PhoneThe grant row sticks 59px from the top, under the header · paper · #dfe5d4 line below · Talk grows to fill the rowTalk · 4 · Partner · Watch
var TD = FedM8TalkDoors;
var item = TD.itemFor("notice", notice.id);      // "grant:<id>" for a grant, "naics:541519" for a code
var door = TD.chip(document, { item: item, title: notice.title, signedIn: !!ctx.user });
cardFoot.appendChild(door);                       // signed out, the door goes to sign-in, then the room

// One read for the whole list, then every door gets its count:
TD.counts(itemIds, { client: ctx.sb, user: userId }).then(function (map) { TD.fill(list, map); });

A room on a phone

On a phone a room fills the screen between the header and the dock. A slim bar gives Back, the room's name and Room info. The box is pinned right above the dock, with the rules line kept to two lines. The sample scrolls inside the frame.

Sample · Help desk support, Fort Example

3 raised a hand · no sub yet · 1 online now

Say hi: Marcus Example Network Services Lena
FedM8 AIPinnedAI brief

One firm runs a help desk for about 400 people, weekdays 7 a.m. to 6 p.m. Set aside for SDVOSB firms. Offers are due Nov 14.

Sub✓ Answered2h

Has anyone done a site visit at Fort Example? How far is the help desk from the gate?

2 replies

Replies open here.

PrimeOct 19

We're a prime on this one and want a sub for the network side.

Talk about the work and who you need. Keep prices, bids and contact details out of open rooms. Share prices only privately with teammates, under a signed teaming agreement. Ask the contracting officer about the requirement, in writing.

Room info

Contract details

Example Command

SDVOSB set-aside. Questions about VetCert? Ask in the VetCert room

NAICS 541519

People you hid

PartValueWords
Room barUnder the 59px header · paper · 1px line below · 4px 2px inside the page's 13px sides · Back 44 × 44 with a 22px arrow in dark olive · the name DM Sans 650 15px on one line, cut with "…" · Room info 44px round, 1px line edge, dark olive Georgia 700 17px← (read aloud "Back to Chat", or "Back to NAICS 541519") · the room's name · i (read aloud "Room info")
Who's hereThe count line, then I'm in as at full width with 44px choices, then one line of namesSay hi: Marcus · Example Network Services · Lena · See why · Hide
Pinned boxHeld 78px from the bottom, right above the dock · paper · 1px line above · shadow 0 -4px 14px #29372e14 · 8px 12px 10px · rules 12px, two lines at most · box at least 44px, 16px words so the phone does not zoom, and tall enough that the whole placeholder shows · Post 64 × 44 · while writing it grows to 52% of the screenAsk about this contract, or find a teammate. · Post · Not sent yet (kept in this tab)
SheetsRise from the bottom · paper · 14px top corners. Room info: shadow 0 -6px 28px #29372e33 · 82% of the screen at most · scrim #1b241e66 · grip 40 × 4 #cdd5bf · title Source Serif 4 600 18px · Close 44px, 64px wide at least · a dialog named by its title. The ⋯ menu: scrim #1d2a2140 · grip #d9ded0 · rows 48px, 15px.Room info · Contract details · Ask in the VetCert room · NAICS 541519 · View team · Close. The ⋯ menu: Report · Hide this person · People you hid.
TargetsEvery action, tab, reply toggle, chip and link in a room is 44px tall on a phonenone

Chat states

Every state says what is true and keeps the member's words. These are the app's own sentences from assets/chat-words.js; use them, never new ones.

Loading

Loading…

Nobody has posted

Nobody has posted yet. Ask a question or share what you know.

Could not load

Chat could not load. Check your connection, then try again.

Heads-up while typing, Why open

This looks like pricing. Share prices only privately with teammates, under a signed teaming agreement.

Rooms on FedM8 are public. Prices, contact details, Social Security and VA numbers, and nonpublic information about a buy stay out, so every member can trust what they read here. The same check runs again when you post.

Refused after Post

We didn't post this. It looks like pricing, and prices stay out of open rooms. Share prices only privately with teammates, under a signed teaming agreement. Your words are still in the box.

Not sent yet (kept in this tab)

Could not send

We couldn't post this. Your words are still in the box. Check your connection, then try again.

Gates: one line, one link at most

Sign in to read and join this conversation.

Set up your Team Up profile to post. Set up profile

You've used today's 3 new posts. You can still reply. New posts open again tomorrow.

Posting is paused on this account. Write to Support and we'll look at it with you. Write Support

Box not ticked

Check the box first. It takes a second.

Remove your own post

Remove your post?

It comes down for good, with any replies under it.

Done: a short toast

Posted.

Reply posted.

Reported. FedM8 will look at it.

StateLookIn the app
LoadingOne 13px muted line. No spinner, no grey skeleton people.W.loading "Loading…"
Nobody yetPaper, 1px dashed #cbd4bf edge, 8px corners, 13px mutedW.emptyRoom, W.empty (contract), W.emptyCode(code)
Could not load#fbf4e8 · edge #e3c9a6 · words #5b3a12 13px · Try again olive, 44pxW.readFail; with a draft in the box W.loadFail "Chat could not load. Your message is kept here until you try again."
Heads-up#fbf3dc · edge #e3cf94 · words #5c4708 · "!" in a 20px ring · Edit and Why 30px (44px on a phone) · Why opens the reason under themFedM8Room.headsUp: checked 0.8 seconds after typing stops, read aloud politely (role="status"). It never blocks Post.
Refused#fbecea · edge #e2b8b2 · words #6d231b · Edit and Why only when the server refused the wordsFedM8Room.refusal (role="alert"), words from W.refused
Gates13px muted, one link at most: dark olive 600, underlinedW.gate(document, message). Never shows a raw code.
Field problem12.5px #8f2d22 under the field, which is marked aria-invalidW.ackFirst, W.writeFirst "Write a message first."
RemoveDialog 460px at most · 20px · 10px corners · shadow 0 12px 40px #29372e40 · title Source Serif 4 600 20px · text 13px muted · Remove #8f2d22 with white wordsRemove your post? · It comes down for good, with any replies under it. · Cancel · Remove · then "Removed."
ToastDark olive #344b2c · white 13.5px · 8px corners · 24px from the bottom, centered · leaves by itselfPosted. · Reply posted. · Reported. FedM8 will look at it. · Removed. · Marked as the answer.
var W = FedM8ChatWords;

// A gate: plain words and at most one link.
host.appendChild(W.gate(document, err));       // "Set up your Team Up profile to post. Set up profile"

// After Post fails: the server's sentence, right above the buttons. The words stay in the box.
form.insertBefore(FedM8Room.refusal(err, { verb: "post", textarea: input }), buttonRow);

// While typing: the heads-up under the box.
var hu = FedM8Room.headsUp(input, { ctx: ctx, item: noticeId });
input.after(hu.node);

Do

  • Keep the member's words in the box after every failure, and say so.
  • Use the server's own sentence for a refusal, with Edit and Why.
  • Put one next step in a gate, as one link.
  • Ask before anything that cannot be undone, and name what goes.

Don't

  • "Something went wrong", a raw error code or a red banner across the page.
  • Spinners or grey placeholder people and counts.
  • Block Post because of a heads-up. The server decides when someone posts.
  • Clear the box when a post fails.

Match-M8

Match-M8 is the product name of the matching AI. Never show an engine or vendor name. Match-M8 says how well a notice fits what a member does, and why, in plain lines. It suggests; the member decides.

Name
Match-M8, in every word a member reads or hears: buttons, help, alerts, email, video narration and samples
Plan
Basic and Pro · feature id found_for_you in tier.js
Shows
A percent, the role it fits and up to five reasons
Drawn by
assets/os-search.js (the match box) with FedM8TeamUpUI.reasons

The match box on a notice

Scored

82% match as a sub

Edit what you do
  • You fit a key role this work needs
  • You do most of this work
  • As a sub you could do a major piece
  • You have done this kind of work for other customers
  • No clearance, license, brand-name or incumbent requirement found

Not scored yet

No Match-M8 score for you on this one yet

Match-M8 scores notices that share your NAICS codes or work terms, every 15 minutes. Check what you do

A Free member

Basic shows how well each notice fits what you do. See plans

On a list card and in Who's here

82% matchDue Nov 14

3 raised a hand · 1 matched by Match-M8, not confirmed

PartValueWords
Box#f0f4e8 · edge #cfd8c2 · 10px corners · 16px · headline 700 16px #31553b · reasons 15px ink, a plain bulleted list82% match as a sub · for your firm · for you as an independent specialist · to lead it · Edit what you do
ReasonsFive at most, built from the member's own answers by FedM8TeamUpUI.reasons(answers, role). Never invented.You fit a key role this work needs · You do most of this work · As a sub you could do a major piece · You have done this kind of work for other customers · No clearance, license, brand-name or incumbent requirement found
Not scoredThe same box, a 14px muted note and one linkNo Match-M8 score for you on this one yet · Match-M8 scores notices that share your NAICS codes or work terms, every 15 minutes. · Check what you do
Free memberOne quiet plan line, no boxBasic shows how well each notice fits what you do. See plans
ElsewhereList card foot: 700 #31553b. Who's here: muted italic until the member confirms.82% match · 1 matched by Match-M8, not confirmed

Win Kit: what they paid before

Win Kit answers one question from public award records. It is part of Pro, so its heading carries a P tile. It shows the dollars obligated, never what anyone bid.

What they paid beforeP

The last time this exact work was bought, it was awarded for $1.2M to Example Support Co. (Oct 1, 2021).

Half of these awards were under $640K. The middle half ran from $310K to $1.1M.

Closest past awards

  • $1.2M Example Support Co., Oct 1, 2021 Same solicitation number
  • $880K Example Systems Group, Mar 3, 2023
  • $410K Example Network Services, Aug 19, 2022

From USAspending.gov award records: who won and the dollars obligated. They do not show what anyone bid.

What did they pay before?

Past awards from Example Command under NAICS 541519, last 5 years: 24.

$310KLow

$640KMiddle

$1.1MHigh

These are total dollars obligated per award over its whole life. They are not a yearly rate and not a bid price. Build your price from your own costs, then check it against this band.

Source: USAspending.gov award records. They show who won and the dollars obligated. They do not show who lost or what anyone bid.

PartValue
ColumnPaper · 1px line · a 4px olive top edge (the one colored card top in the app) · 8px corners · 16px 18px
HeadingDM Sans 600 16px with a 1px line under it, then the P tile
Lines15px ink for the answer · amounts 600 #31553b · 13px muted for how to read it and the source · past awards 14px with 1px lines between · "Same solicitation number" in a round canvas tag
BandThree soft cells, 8px corners · 20px 700 #31553b figure over a 13px muted label · Low, Middle, High
HonestyEvery view names USAspending.gov and says it does not show bids or losers. USAspending does not publish who lost.
// The headline and the reasons, as the match box builds them:
var pct = Math.round(Number(match.fit) * 100);
var how = match.basis === "firm" ? "for your firm"
        : match.role === "ind" ? "for you as an independent specialist"
        : match.role === "prime" ? "to lead it" : "as a sub";
headline.textContent = pct + "% match " + how;                     // "82% match as a sub"
var lines = FedM8TeamUpUI.reasons(match.answers, match.role);      // five at most, from the member's answers

Do

  • Write Match-M8 wherever a member meets the matching AI: labels, help, alerts, email, narration, alt text and samples.
  • Say what Match-M8 used: the member's codes, work terms and answers.
  • Show "not confirmed" until the member confirms what Match-M8 added.
  • Link to Edit what you do, so the member can fix the inputs.

Don't

  • Show an engine, model or vendor name anywhere a member can see or hear it.
  • Call a match a chance of winning.
  • Invent a reason, or show more than five.
  • Show bids or losers. Public award records do not have them.

Plan tiles

A plan tile is a small square right after the name of a paid tool, output or ability: B for Basic, P for Pro. It tells a member which plan the thing belongs to. It informs; it never sells. Free features get no tile. Pro includes AI, so there is no AI tile.

Files
assets/plan-tile.css and assets/plan-tile.js
The plan comes from
FedM8Tier.minPlanFor(featureId) in tier.js, never typed by hand
Size
16 × 16 · 4px corners · DM Sans 700 10px · 6px after the name. A link tile has a 44px hit area.
Colors
B: olive #526547 letter, no fill, #b8c5aa edge. P: dark olive #344b2c on #e4ead8.

The forms

Award IntelPA link tile after a name. Hover or focus shows "Pro plan".
Bid CoachBBasic: outlined, no fill.
Inside a control: hidden from screen readers; the control says "(Basic plan)".
Proposal helpProThe word form, for menus and lists with room.

In context: see it as each plan

Press Free, Basic or Pro. Tiles for a plan the viewer already has turn quiet and stop linking, and the Free line goes away once the plan is there. The samples below change as you press.

Match-M8 matches are part of Basic. See plans

What they paid beforeP

Win Kit is part of Pro. See plans

The last time this exact work was bought, it was awarded for $1.2M to Example Support Co. (Oct 1, 2021).

  • Notices
  • Grants
  • Chat
  • Match-M8 matches with reasonsB
  • Saved searches with alertsB
  • Bid CoachB
  • My pursuitsB
  • Win KitP
  • Award IntelP
  • Proposal helpP
PartValue
PlacementRight after the name, on the same line, 6px away. In a flex row that has its own gap, add plan-tile--flush so the gap is the only space.
Link tile<a> to /plans#basic or /plans#pro · a 44 × 44 hit area around the 16px mark · label on hover or focus: "Basic plan" · read aloud "Basic plan feature. See plans"
Inside a controlA <span aria-hidden="true"> tile, and "(Basic plan)" in the control's name: an aria-label that starts with the visible words, or hidden text where the page has a hidden-text class. The control keeps its own action.
Word formplan-tile--word: "Basic" or "Pro", 10.5px 600, for menus and lists with room
By a headingplan-tile--lg: 18px, 11px letter
On olive or darkplan-tile--on-dark: white letter, white edge at 62%
The viewer has it55% opacity, no link, read aloud "Included in your plan: Basic", label "In your plan" (FedM8PlanTile.apply)
Free linep.plan-lock[data-plan]: one 13px muted line, the tile, one sentence, then "See plans" in dark olive 600, 44px tall. Hidden once the viewer has the plan. No blur, no banner.
FeatureId in tier.jsTile
Notices, Grants, Chatopportunities, grants, chatnone (free)
Match-M8 matches with reasonsfound_for_youB
Saved searches with alertssaved_searchesB
Bid Coachbid_coachB
My pursuitspipelineB
Win Kit and Award Intelaward_intel (Win Kit has no id of its own yet)P
Proposal helpproposal_assistP
Company workspacecompany_workspacenone (company seats are not sold)
<!-- Filled from tier.js; removed when the feature is free -->
Saved searches<a class="plan-tile" data-plan-feature="saved_searches"></a>

<!-- One quiet line where a Free member meets a paid output -->
<p class="plan-lock" data-plan="basic"><span class="plan-tile" data-plan="basic" aria-hidden="true">B</span>Match-M8 matches are part of Basic. <a href="/plans#basic">See plans</a></p>

// In your page's .js file (never an inline script):
var tile = FedM8PlanTile.forFeature("award_intel");                 // a link tile, or null when free
if (tile) heading.appendChild(tile);

var inside = FedM8PlanTile.forFeature("saved_searches", { inside: true });
if (inside) {
  saveButton.appendChild(inside);                                    // hidden from screen readers
  // os.html has no shared hidden-text class, so the button's name carries the plan:
  saveButton.setAttribute("aria-label", "Save this search (" + (inside.dataset.plan === "pro" ? "Pro" : "Basic") + " plan)");
}
FedM8PlanTile.apply(root, ctx.plan);                                 // quiets tiles the viewer already has

Do

  • One tile per tool, right after its name, on the same line, 6px away.
  • Read the plan from tier.js: data-plan-feature or FedM8PlanTile.forFeature.
  • Inside a button, tab or link, hide the tile from screen readers and add "(Basic plan)".
  • Run FedM8PlanTile.apply with the viewer's plan so tiles they have go quiet.
  • Use "See plans" as the only upgrade link.

Don't

  • Color a whole button, card or row by plan.
  • Shout: Upgrade, Unlock, Go Pro, lock icons, blur or banners.
  • Type the plan by hand in page code.
  • Put a tile on a free feature, or an AI tile anywhere.
  • Two tiles on one tool, or a tile on every line of a paid screen.

States

Every screen says what is true, in words: loading, nothing yet, could not load, saved. One main action per state, then one line that says what it does. No grey placeholder people or counts.

Loading

Loading…

Nothing yet

No pursuits tracked yet.

Could not load

That did not load.

Not sure it was sent

We could not confirm it was sent. Try again; it will not send twice.

Offline

You're offline. Not sent yet. Your words are kept in this tab.

Changed in another tab

This changed in another tab. Reload to see the latest.

Not open

This is not open to you. If someone invited you, check that you are signed in with that account.

This page is not open yet.

Paused or closed, draft kept

This opening is paused. You can still read it. Your draft is kept for when it opens again.

This opening is closed. It is no longer taking responses.

Saved

Saved. Find it on the Saved tab.

A field with a problem

A NAICS code is 6 digits. Fix it or leave it empty.

StateLookRule
LoadingOne 13px muted lineWords only. No spinner, no skeleton people or counts.
Nothing yetPaper, 1px dashed #cbd4bf, 8px corners, 13px mutedSay what is missing. Add the next step when there is one.
Could not load, unsure, offline#fbf4e8 · edge #e3c9a6 · words #5b3a12 · one olive Try again, 44pxThe retry sends with the same key, so nothing sends twice. The draft stays in the tab.
Not open, paused, closedOne 13px muted line, no buttonA paused or closed line keeps the draft. "This page is not open yet." is what a page says while its switch is off.
Changed elsewhereOne line and a ghost ReloadNever overwrite newer work without asking.
Saved12.5px #2f6b3a 600 with a ✓, next to the control that savedShow it only after the server says it stored the row.
Refused#fbecea, edge #e2b8b2, words #6d231bThe server's own sentence, above the footer, with focus on it. The field it is about is marked.
Field problem2px ink edge on the field · 12.5px #8f2d22 line under itaria-invalid="true" and aria-describedby on the field; focus moves to it.
Free memberOne quiet plan line (see Plan tiles)Never blur or hide the whole screen.

Do

  • One main action per state, then one line that says what happens ("Keeps it in your pipeline. Nobody is told.").
  • Move focus to a refusal or a receipt so it is read aloud.
  • Keep drafts through every failure.

Don't

  • "Oops", "Something went wrong" or a raw error code.
  • Red for anything except a refusal, an error line or a remove button.
  • Errors in a toast. A toast only says something is done.

Words

FedM8 sounds like a calm colleague who has done this before: short sentences, plain words, the next step. Words live in one table per file, such as assets/chat-words.js for Chat. Read them from there; never retype them.

  • Say what is true, then the next step: "Chat could not load. Check your connection, then try again."
  • Write short sentences a busy owner reads once. One idea each.
  • Define a term where it appears, in a few words.
  • Use the names members know: My Profile, Support, the contracting officer.
  • Stay calm: no exclamation marks, no "Oops", no capitals for stress.
  • No sales words: unlock, supercharge, don't miss out, exclusive.
  • Give the real count or none. Say where a fact comes from: "SAM lists SDVOSB", "Veteran (self-reported)".
  • Keep the member's words safe, and say so: "Your words are still in the box."
SayNotWhy
Chat (in the app) · Contract Chat (its public name)Forum, board, CommonsOne name in each place
roomchannel, group, thread listRooms hold posts; posts hold replies.
Post · Post replySubmit, Publish, Send (in a room)Post is the action word in rooms. A private chat says Send.
Helpful · M8 4Like, upvote, thumbs upThe writer gets M8.
Follow · FollowingSubscribe, Watch (in a room)Watch is for notices and grants.
Report · Hide this person · Remove mineFlag, Block, DeleteEach says exactly what happens.
FedM8 AI · not a memberbot, assistant, moderatorThe room host never speaks as a member.
Match-M8any engine, model or vendor name, "the algorithm"Match-M8 is the product name of the matching AI.
Certify (dock) · Get Certified (rail and titles)Certs, Certification CenterThe dock has room for one short word.
independent specialist1099, freelancerThe word members use for themselves
See plansUpgrade, Unlock, Go ProThe only upgrade link
Sample · Help desk support, Fort Examplereal people, companies, emails or phone numbersSamples are fictional and labelled.

Accessibility

WCAG 2.2 AA is the floor, and the app's release check allows no serious or critical findings. Most of it comes free with the parts on this page; these are the rules to keep when you build something new.

CheckRule
Targets44 × 44 on a phone for every control. Links inside a sentence are the one exception.
FocusA 2px olive ring (3px on large controls), 2px off the edge, never removed. A focused control is never hidden under the header, a pinned box or the dock.
ContrastText 4.5:1 at least; field edges, control edges and the focus ring 3:1. See the pairs below.
NamesEvery icon-only control has a name. When a control shows words, its name starts with them ("Helpful, M8 4. The writer gets M8.").
HeadingsOne h1 per screen, then h2 and h3 in order. A card or sheet title is a heading in the app.
Read aloudHeads-up: role="status", polite. Refusal: role="alert". The first-post step line and toasts: role="status".
KeyboardThe ⋯ menu: role="menu", arrow keys, Escape; Tab closes it. Scope tabs: role="tablist", arrows, Home, End. Dialogs and sheets keep focus inside, close on Escape and return focus to the control that opened them.
FieldsA visible label on every field; hints and problems tied with aria-describedby; a problem sets aria-invalid and takes focus.
ColorNever the only signal: Answered has a ✓ and a word, online has "Online now", a plan has its letter.
MotionNo transitions when the device asks for reduced motion. New posts never move the page.
PhoneNo sideways scrolling at 375px. 16px text in boxes so the phone does not zoom. Pages work at 200% zoom.
PairRatioUse
Ink #29372e on paper #fffef912.4:1Body text
Muted #586653 on paper6.0:1Second lines, meta
Muted on canvas #f5f3ec5.5:1Notes on the page
Paper on olive #5265476.3:1Main buttons
Dark olive #344b2c on #e4ead87.8:1Current rail item, the P tile
Link #435e36 on paper7.2:1Links
Placeholder #6a7565 on white4.8:1Placeholders (never the only label)
Olive ring on paper6.3:1Focus ring
Field edge #81976b on paper3.2:1Field edges
Line #d9ded0 on paper1.4:1Dividers and card edges only, never the only edge of a field

Known gap: the Chat boxes still use lighter edges (#c9d1bd in rooms, #b9c4ab on Chat home and the first-post card, about 1.6 to 1.8:1). New fields use #81976b.

For AI agents

Building a FedM8 screen? Read this list, then /design/002/tokens.json, then copy the closest snippet on this page. /design/catalog.json lists every design.

  1. Use design 002 for the app and every new screen. Use 001 only for brand marks, walkthrough videos, YouTube thumbnails, social posts and print.
  2. Build with the app's own parts, named in each snippet: the shell in assets/approved-design.css, FedM8Room.mount for any conversation, FedM8ChatWords for every Chat word. The x2- classes on this page are for samples only.
  3. Take colors only from the --fd-* variables. No new hex values, no gradients, no dark theme.
  4. Newsreader (then Source Serif 4) for page and card titles, Source Serif 4 for room titles, DM Sans for everything else.
  5. One olive button per view. Everything else is a ghost button or a link.
  6. Every control 44 × 44 on a phone, with a 2px olive focus ring. Check at 1440 × 1000 and 375 × 812.
  7. Names: Match-M8 for the matching AI, FedM8 AI · not a member for the room host, Contract Chat in public, Chat in the app, rooms, Post. Never an engine or vendor name.
  8. Plans come from tier.js. Free features get no tile, and "See plans" is the only upgrade link.
  9. States in words. Keep the member's words after every failure.
  10. Samples are fictional and labelled Sample. No real people, emails or phone numbers.
  11. The site's security rules allow no inline styles or scripts, no style attributes and no inline event handlers. Styles go in a .css file, behavior in a .js file.
  12. When this page and DESIGN.md disagree, DESIGN.md wins. Say so in Comments.

The core variables

/* assets/approved-design.css sets these on body.fd-design. Read them; do not redefine them. */
body.fd-design {
  --fd-bg: #f5f3ec;          /* canvas */
  --fd-paper: #fffef9;       /* cards, header, dock, dialogs */
  --fd-soft: #eef1e7;        /* quiet fills */
  --fd-ink: #29372e;         /* text */
  --fd-muted: #586653;       /* second lines */
  --fd-line: #d9ded0;        /* card edges, dividers */
  --fd-green: #526547;       /* the one main button, focus ring */
  --fd-green-dark: #344b2c;  /* text on light fills */
  --fd-mint: #d9eddd;        /* count pills */
}

Where things live

NeedUseFile
Header, rail, dock, buttons, fieldsbody.fd-design, .btn, .btn.ghostassets/approved-design.css, assets/approved-design.js
A conversationFedM8Room.mountassets/fedm8-room.js, assets/fedm8-room.css
Chat homeFedM8ChatHome.renderassets/chat-home.js
Any Chat wordFedM8ChatWordsassets/chat-words.js
A door into a roomFedM8TalkDoors.chipassets/talk-doors.js
FollowFedM8Follow.buttonassets/talk-follow.js
Who's hereFedM8Teaming.whosHereassets/teaming.js
Before your first postFedM8FirstPost.createassets/first-post.js
Plan tilesFedM8PlanTileassets/plan-tile.js, assets/plan-tile.css
Plan rulesFedM8Tier.can, FedM8Tier.minPlanFortier.js
Comments on a page<div class="pc" data-page-comments data-topic="…">assets/page-comments.js, assets/page-comments.css

Comments and questions

Ask a question about this design, or point out something that is missing or wrong. Answers stay here for the next person who builds a screen.