make_post_sell/docs/design-system.md
russell@unturf.com 547cc14589
docs: notification system + design-system surface for offers/auctions
- New docs/notifications.md: schema, kind matrix, breadcrumb walk,
  per-call-site wiring, UI surfaces, read-but-not-deleted semantics,
  non-fatal design.
- docs/architecture.md feature-toggle matrix extended with
  make-an-offer (shop + per-product gate), pre-accept expiration
  window, post-accept pay window, and the always-on notification
  surface. Related-docs section now links the new notifications doc
  + the existing auction-house / make-offer state-machine docs.
- docs/design-system.md component library extended with every class
  shipped this offer/auction/notification cycle: cart-negotiation-card
  + deadline + pill, offer-pay-cta-actions row, auction-winner-pay
  well, product-add-disabled-note, shop-offers-page width override,
  notification-badge pill + row + breadcrumbs + read-fade behavior,
  billing redesign classes, and the [data-pay-deadline] tick
  convention.
2026-05-14 14:49:39 -04:00

15 KiB
Raw Blame History

MPS Design System

Overview

Make Post Sell uses a design token architecture with CSS custom properties as the single source of truth. Mobile-first. CSS Grid only (no Flexbox). Accessible. Respects reduced motion. Supports light and dark themes.

Architecture Diagram

┌─────────────────────────────────────────────────────────┐
│                    tokens.css                            │
│              Design Tokens (:root)                       │
│                                                          │
│  Colors · Typography · Spacing · Shape · Elevation       │
│  Motion · Z-index · Layout · State overlays              │
│                                                          │
│  [data-theme="dark"] overrides                           │
│                                                          │
│  Base resets · Focus · Selection                         │
│  Typography utilities (.type-*)                          │
│  Elevation utilities (.elevation-*)                      │
│  Surface utilities (.surface-*)                          │
│  State layer · Ripple effect                             │
│  Animations · Skeleton loading · Spinner                 │
│  Spacing utilities (.mt-*, .mb-*, .p-*, .gap-*)         │
│  Container utilities (.container, -narrow, -wide)        │
└──────────────────────┬──────────────────────────────────┘
                       │ consumed by
                       ▼
┌─────────────────────────────────────────────────────────┐
│                    common.css                            │
│              Component Styles                            │
│                                                          │
│  Body layout · Navigation · Forms · Buttons              │
│  Product grid · Cards · Cart · Comments                  │
│  Wells · Alerts · Ribbons · Footer                       │
│  Watch mode · Landing page · Login                       │
│  Responsive breakpoints                                  │
│                                                          │
│  References tokens via var(--token-name, fallback)       │
└──────────────────────┬──────────────────────────────────┘
                       │ rendered in
                       ▼
┌─────────────────────────────────────────────────────────┐
│                   templates/                             │
│              Jinja2 Templates                            │
│                                                          │
│  base.j2 → theme toggle, nav, footer                    │
│  styleguide.j2 → live component reference               │
│  product.j2, content.j2, shop.j2, etc.                  │
└─────────────────────────────────────────────────────────┘

File Map

File Lines Purpose
static/css/tokens.css 775 Design tokens, utilities, animations, resets
static/css/common.css 3879 Component styles consuming tokens
templates/styleguide.j2 1083 Live styleguide at /styleguide
views/misc.py:23 Styleguide view controller

Token Categories

Colors

Brand           Surface              Text                Border
──────────      ──────────           ──────────          ──────────
--color-green   --surface-base       --text-primary      --border-default
--color-blue    --surface-dim        --text-body         --border-light
--color-navy    --surface-container  --text-secondary    --border-focus
--color-purple  --surface-container- --text-muted        --border-error
--color-danger    high               --text-faint
--color-gold    --surface-inverse    --text-disabled
                                     --text-inverse

Typography Scale (Major Third 1.250)

Token          Size     Use
──────────     ──────   ──────────────────────
--text-xs      12px     Captions, overlines
--text-sm      14px     Labels, small body
--text-base    16px     Body text (root)
--text-md      18px     Large body
--text-lg      20px     Titles
--text-xl      24px     Title large
--text-2xl     30px     Headline 3
--text-3xl     36px     Headline 2
--text-4xl     48px     Headline 1
--text-5xl     60px     Display

Spacing Scale (4px base)

Token          Value
──────────     ──────
--space-0      0
--space-1      4px
--space-2      8px
--space-3      12px
--space-4      16px
--space-5      20px
--space-6      24px
--space-8      32px
--space-10     40px
--space-12     48px
--space-16     64px
--space-20     80px
--space-24     96px

Shape (Border Radius)

--radius-none   0        Sharp corners
--radius-sm     4px      Inputs, code blocks
--radius-md     8px      Cards, buttons
--radius-lg     12px     Modals, panels
--radius-xl     16px     Large surfaces
--radius-2xl    24px     Pills
--radius-full   9999px   Circles

Elevation (Box Shadow)

--elevation-0   none       Flat
--elevation-1   subtle     Cards at rest
--elevation-2   low        Raised cards
--elevation-3   medium     Dropdowns
--elevation-4   high       Modals
--elevation-5   highest    Popovers

Motion

Durations                    Easing
──────────────────           ──────────────────
--duration-instant   50ms    --ease-standard    general transitions
--duration-fast      100ms   --ease-decelerate  entrances
--duration-normal    200ms   --ease-accelerate  exits
--duration-slow      300ms   --ease-emphasize   emphasis
--duration-slower    400ms   --ease-spring      playful bounce
--duration-entrance  250ms
--duration-exit      200ms

Z-Index Scale

--z-base       0      Default stacking
--z-dropdown   100    Dropdowns, popovers
--z-sticky     200    Sticky headers
--z-overlay    300    Overlays, backdrops
--z-modal      400    Modals
--z-toast      500    Toast notifications
--z-ribbon     600    Shop ribbon banner

Layout Breakpoints

--content-narrow   400px    Login forms, narrow content
--content-width    800px    Default content width
--content-wide     1200px   Wide layouts
--bp-tablet        800px    Tablet breakpoint
--bp-desktop       1200px   Desktop breakpoint

Theme System

Light mode is default (:root). Dark mode activates via [data-theme="dark"] on the <html> element. The dark theme overrides all semantic tokens — surfaces, text, borders, brand colors — so components adapt automatically without per-component dark mode rules.

Light                           Dark
──────────────────────          ──────────────────────
--surface-base: #FFFFFF         --surface-base: #0d1117
--text-primary: #333333         --text-primary: #ffffff
--border-default: #e0e0e0      --border-default: #7ab9ff
--color-green: #a3c765          --color-green: #08e700
--color-navy: #5871ad           --color-navy: #7ab9ff

Theme toggle: window.setTheme('dark') / window.setTheme('light').

Typography Utilities

CSS classes that compose token values into complete type styles:

Class Size Weight Use
.type-display clamp(36px, 5vw, 60px) bold Hero headlines
.type-headline-1 48px bold Page titles
.type-headline-2 36px bold Section titles
.type-headline-3 30px bold Subsection titles
.type-title-lg 24px semibold Card titles
.type-title 20px semibold List titles
.type-title-sm 16px semibold Small titles
.type-body-lg 18px regular Lead paragraphs
.type-body 16px regular Body text
.type-body-sm 14px regular Secondary text
.type-label-lg 14px semibold Form labels
.type-label 12px semibold, uppercase Overline labels
.type-caption 12px regular Captions
.type-overline 11px bold, uppercase Section overlines
.type-code 0.9em mono Inline code

Component Library

All components are documented with live examples at /styleguide. The styleguide is the single source of truth for the component library. If it is not in the styleguide, it does not exist as a pattern.

Styleguide Sections

Section ID Description
Tokens #tokens Raw token reference table
Colors #colors Brand, surface, text, border, alert swatches
Typography #typography Type scale and utility classes
Elevation #elevation Shadow levels
Motion #motion Animations, transitions, easing
Spacing #spacing Spacing scale visualization
Shape #shape Border radius samples
States #states Interactive state layers
Loading #loading Skeleton and spinner patterns
Buttons #buttons Button variants (green, blue, red, navy, outline)
Forms #forms Input fields, textareas, selects, settings-form (.settings-form / .settings-form-grid / .settings-field / .settings-field-hint)
Wells #wells Content wells and containers
Alerts #alerts Success, info, warning, danger alerts
Status #status Status indicators
Product Cards #cards Product grid cards, profile card (.profile-card-header / .profile-avatar / .profile-handle / .profile-email-reveal), action button grid (.action-columns / .action-button-grid)
Cart #cart Cart and checkout components
Gift Cards #gift-cards Gift card purchase, balance check, management
Comments #comments Comment form and list
Toggle #toggle Toggle switches
Ribbon #ribbon Shop ribbon banner
Environment Banner .environment-banner Staging/dev environment indicator
Trial Banner .trial-banner Trial countdown and expiry notice
Task Bar #taskbar Task bar component
Layout #layout Grid layout patterns
Theme System #theme Theme toggle and dark mode
Footer #footer Footer component

MPS-20 / MPS-21 components

Class Where Description
.cart-negotiation-card cart.j2 Soft-green "Offer accepted / Auction won" well at the top of a negotiated cart
.cart-negotiation-deadline cart.j2 Pay-by countdown line inside the negotiation card
.cart-negotiation-pill cart.j2 "Offer accepted · quantity locked" pill on line items
.offer-pay-cta-actions offer.j2 Two-col grid: Cancel left, Pay right (stacks on narrow viewports)
.offer-pay-deadline-note offer.j2 Buyer's "Payment due in 23 hours, 14 minutes" copy
.offer-pay-link-row offer.j2 Seller's shareable offer-link with Copy button
.offer-respond-deadline-note offer.j2 "Respond in 5 days, or this offer auto-expires"
.auction-winner-pay auction.j2 "You won this auction!" well with countdown + pay CTA
.product-add-disabled-note product.j2 Caption under disabled Add To Cart when active cart is locked
.shop-offers-page user_offers.j2 + user_bids.j2 + shop_offers.j2 Wider page (max-width 1100px) overriding .one-column for the offers/bids inbox tables
.shop-offers-table inbox templates Responsive table; collapses to per-row block list below 720px
.notification-badge base.j2 + /u/settings Danger-color pill showing unread notification count
.notification-row + .notification-row-unread user_notifications.j2 Notification list rows; read rows fade to 0.65 opacity, unread rows get an alert-info background + navy left border
.notification-row-breadcrumbs user_notifications.j2 Shop Product Offer/Auction/Invoice chain under each row
.billing-page / .billing-paypal-card / .billing-actions billing.j2 /billing redesigned with Grid + tokens (no inline styles)
[data-pay-deadline] offer + auction + cart Convention attribute the shared static/js/pay-countdown.js (and inline tickers in offer.js / auction.js) rewrite once per second with a prose human delta ("in 23 hours, 14 minutes, 8 seconds") matching the server-rendered ago.human() fallback

CSS Conventions

Layout

  • CSS Grid only — never use Flexbox for layout
  • Mobile-first: base styles target mobile, @media queries enhance for larger screens
  • Primary breakpoint: max-width: 800px for mobile

Token Consumption

Components in common.css reference tokens with fallbacks:

/* Good — token with fallback for resilience */
background-color: var(--surface-base, #ffffff);
border-radius: var(--radius-sm, 4px);

/* Good — token without fallback (tokens.css always loaded) */
padding: var(--space-4);

Media Sizing

Never combine width: 100% with max-height on media elements. Use:

/* Correct */
width: auto;
max-width: 100%;
max-height: 33vh;

/* Wrong — creates dead whitespace */
width: 100%;
max-height: 33vh;

Mobile Usability

Never use hover-only interactions. All interactive elements must be always visible and tappable. Design touch-first, then optionally enhance for desktop hover.

Reduced Motion

All animations respect prefers-reduced-motion: reduce via a global media query in tokens.css that collapses durations to near-zero.

Capability-Driven Presentation

Follow Russell Ballestrini's capability-driven presentation practice. A page need not look identical across all browsers. Accommodate what the user's browser can do. Use the js-only / <noscript> pattern for progressive enhancement.

Adding New Components

  1. Define the component styles in common.css, consuming tokens from tokens.css
  2. Add a live example to /styleguide (templates/styleguide.j2)
  3. If the component participates in watch mode SPA navigation, update all three layers: template, watch.js, watch.py

Load Order

base.j2
  └─ <link> static/css/tokens.css     ← tokens + utilities + resets
  └─ <link> static/css/common.css     ← components consuming tokens
  └─ per-page <style> blocks          ← page-specific overrides