fbe9940a3f
Distill the UI into a single, recognizable voice: a precision instrument for one operator on one machine. Bloomberg-coded chrome, warm-paper detail surfaces, mono-heavy numerics, with one editorial serif accent for moments of weight. Design system - Three-font stack: Geist Sans (UI), Geist Mono (data), Instrument Serif (editorial display). No Inter, no system fonts. - Two surfaces: dark chrome (--background, --accent, --signal) and warm paper detail surfaces (--surface, --surface-ink*). - Inbox has its own Ticker Tape terminal palette (--tt-*). - Shared component classes: .eyebrow, .mono, .display, .surface, .surface-2, .row-hover, .nav-active, .kbd, .editorial, .hairline. - --m-* token aliases for the legacy drawer components so test- asserted class strings keep resolving to the same hue family. Drawers (Claim + Remit) - Editorial display face for totals (paid/adjustment amounts). - Color-coded money tiles: green-tinted paid card, amber-tinted adjustment card when non-zero, muted otherwise. - Tabs get accent-blue underline + CSS-driven active state. - Validation banners with proper background opacity + ring-around- dot success badge. - StateHistoryTimeline: dashed border, ring around dots, ↳ prefix for remit ids. - DiagnosesList, PartiesGrid, MatchedRemitCard, CasAdjustmentsPanel: refined typography, dashed dividers, italic descriptions, mono amounts, font-semibold totals, hover row tints. Inbox Ticker Tape - Custom RowCheckbox with sr-only input + amber accent. - Alternating row striping, hover tints, accent rail with inset shadow on selection. - Refined sparkline with glow at high values. - BulkBar: bottom-floating bar with amber count chip, larger shadow. - CandidateBreakdown: animated progress bars with amber gradient. - InboxHeader: Instrument Serif headline, mono day/date stamp, pulsing amber status dot. Dialogs & search - NewClaimDialog: editorial title, mono NPI/CPT/amount fields. - SearchBar: refined input row with mono, footer with pulsing loading indicator. - KeyboardCheatsheet: monogram icon chip, hover row states, refined eyebrow header. Primitives - StatusBadge / ClaimStateBadge: per-state dot indicators. - SelectItem: data-[highlighted]:outline tokens for keyboard a11y. - Table primitives: refined header treatment, hover/focus states. Tests + build - 354/354 tests passing across 59 files. - Vite build clean (53.84 kB CSS / 560.86 kB JS). - Eyebrow assertions updated to match the consolidated .eyebrow class (intact visual contract, abstracted class string). - Badge variant tokens updated to the polished bg-muted/80 / /0.14 opacity scale.
416 lines
13 KiB
CSS
416 lines
13 KiB
CSS
/* =====================================================================
|
|
Cyclone — design system
|
|
---------------------------------------------------------------------
|
|
A precision instrument for one operator on one machine. The visual
|
|
language borrows from Bloomberg terminals and Linear-grade
|
|
engineering tools: dark, hairline-strict, mono-heavy, with one
|
|
editorial serif accent for the moments that deserve weight.
|
|
---------------------------------------------------------------------
|
|
Type stack:
|
|
- Geist Sans · UI, body, controls
|
|
- Geist Mono · every number, every id, every code-like datum
|
|
- Instrument Serif · editorial display (hero numbers, headlines)
|
|
===================================================================== */
|
|
|
|
@tailwind base;
|
|
@tailwind components;
|
|
@tailwind utilities;
|
|
|
|
@layer base {
|
|
:root {
|
|
/* ---- Core surfaces ----
|
|
A graphite canvas with a whisper of blue. Slightly warm at the
|
|
midtones (--card) to keep the chrome from feeling sterile. */
|
|
--background: 222 18% 5%; /* #0b0c10 — near-black, cool */
|
|
--foreground: 220 14% 96%; /* #f4f5f7 — paper white */
|
|
|
|
--card: 222 16% 8%; /* #11131a */
|
|
--card-foreground: 220 14% 96%;
|
|
|
|
--popover: 222 18% 9%; /* #13151c */
|
|
--popover-foreground: 220 14% 96%;
|
|
|
|
--muted: 222 12% 13%; /* #1f2229 */
|
|
--muted-foreground: 220 8% 64%; /* #9b9ea6 */
|
|
|
|
--secondary: 222 12% 13%;
|
|
--secondary-foreground: 220 14% 96%;
|
|
|
|
/* ---- Accents ----
|
|
Electric blue (primary) for actions and emphasis. Amber (signal)
|
|
is reserved for "needs attention" states and the Inbox terminal
|
|
accents — never decorative. */
|
|
--accent: 212 100% 60%; /* #2e8aff — electric, modern */
|
|
--accent-foreground: 0 0% 100%;
|
|
--signal: 36 92% 56%; /* #f3a531 — warm amber */
|
|
|
|
--primary: 212 100% 60%;
|
|
--primary-foreground: 0 0% 100%;
|
|
|
|
--destructive: 358 82% 60%; /* #ec4458 */
|
|
--destructive-foreground: 0 0% 100%;
|
|
|
|
--success: 152 64% 46%; /* #2cbd76 */
|
|
--success-foreground: 152 70% 8%;
|
|
|
|
--warning: 36 92% 56%; /* #f3a531 */
|
|
--warning-foreground: 26 80% 12%;
|
|
|
|
--border: 222 10% 16%; /* #262932 */
|
|
--input: 222 10% 16%;
|
|
--ring: 212 100% 60%;
|
|
|
|
/* ---- Sidebar ---- */
|
|
--sidebar: 222 20% 4%; /* darker than the page */
|
|
--sidebar-foreground: 220 14% 96%;
|
|
--sidebar-accent: 212 100% 60%;
|
|
--sidebar-border: 222 12% 12%;
|
|
|
|
/* ---- Document surface (drawer detail panels) ----
|
|
A faint warm paper. Keeps detail views distinct from the chrome
|
|
without going full light. Pairs with editorial serif headlines. */
|
|
--surface: 36 18% 96%; /* #f6f3ec */
|
|
--surface-ink: 30 12% 9%; /* #181614 */
|
|
--surface-ink-2: 30 6% 32%; /* #4f4b46 */
|
|
--surface-ink-3: 30 4% 52%; /* #85807a */
|
|
--surface-line: 30 14% 14%; /* #24221f */
|
|
--surface-line-soft: 30 14% 14% / 0.12;
|
|
|
|
/* ---- Ticker-tape terminal (Inbox) ----
|
|
Bloomberg-coded: three accent rails on near-black, with the
|
|
paper-tone ink for legibility. */
|
|
--tt-bg: 220 22% 5%; /* #0a0d12 */
|
|
--tt-bg-elev: 220 18% 9%; /* #13171f */
|
|
--tt-ink: 36 18% 88%; /* #e2ddd0 */
|
|
--tt-ink-dim: 220 6% 58%; /* #8e9098 */
|
|
--tt-amber: 36 88% 56%; /* #efa836 */
|
|
--tt-oxblood: 354 50% 40%; /* #8a2d35 */
|
|
--tt-ink-blue: 212 38% 36%; /* #2e4d77 */
|
|
--tt-muted: 220 4% 38%; /* #5b5d62 */
|
|
|
|
/* ---- Legacy aliases (--m-*)
|
|
Kept as thin shims so any older component still using the
|
|
"warm paper" surface family resolves to the same hue family.
|
|
New components should prefer --surface-* / --destructive / etc. */
|
|
--m-surface: hsl(var(--surface));
|
|
--m-ink-primary: hsl(var(--surface-ink));
|
|
--m-ink-secondary: hsl(var(--surface-ink-2));
|
|
--m-ink-tertiary: hsl(var(--surface-ink-3));
|
|
--m-border-heavy: hsl(var(--surface-line));
|
|
--m-font-mono: var(--font-mono);
|
|
--m-error: hsl(var(--destructive));
|
|
--m-error-bg: hsl(var(--destructive) / 0.08);
|
|
--m-success: hsl(var(--success));
|
|
--m-warning: hsl(var(--warning));
|
|
--m-accent: hsl(var(--accent));
|
|
|
|
--radius: 0.625rem; /* 10px — slightly tighter */
|
|
|
|
/* ---- Type stack ---- */
|
|
--font-sans: "Geist", ui-sans-serif, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
|
|
--font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
|
|
--font-display: "Instrument Serif", "Iowan Old Style", "Apple Garamond", "Baskerville", "Times New Roman", serif;
|
|
}
|
|
|
|
* {
|
|
@apply border-border;
|
|
}
|
|
|
|
html, body, #root {
|
|
height: 100%;
|
|
}
|
|
|
|
body {
|
|
@apply bg-background text-foreground;
|
|
font-family: var(--font-sans);
|
|
font-feature-settings: "ss01", "cv11", "calt";
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
text-rendering: optimizeLegibility;
|
|
}
|
|
|
|
/* A single, precise light source anchored top-right.
|
|
One light, not two — an instrument, not a wash. */
|
|
body::before {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
z-index: 0;
|
|
background: radial-gradient(
|
|
55rem 35rem at 100% -15%,
|
|
hsla(212, 100%, 60%, 0.07),
|
|
transparent 62%
|
|
);
|
|
}
|
|
|
|
/* Hairline grid — the substrate of a precision instrument.
|
|
Sits behind everything, gives the dark surfaces a sense of
|
|
scale and the work a sense of "field". */
|
|
body::after {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
z-index: 0;
|
|
opacity: 0.5;
|
|
background-image:
|
|
linear-gradient(to right, hsl(222 10% 16% / 0.18) 1px, transparent 1px),
|
|
linear-gradient(to bottom, hsl(222 10% 16% / 0.18) 1px, transparent 1px);
|
|
background-size: 64px 64px;
|
|
mask-image: radial-gradient(ellipse 80% 60% at 50% 30%, black 30%, transparent 80%);
|
|
-webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 30%, black 30%, transparent 80%);
|
|
}
|
|
|
|
/* Custom scrollbar — minimal, hairline, Apple-style */
|
|
::-webkit-scrollbar {
|
|
width: 10px;
|
|
height: 10px;
|
|
}
|
|
::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
::-webkit-scrollbar-thumb {
|
|
background: hsl(var(--border));
|
|
border-radius: 999px;
|
|
border: 2px solid transparent;
|
|
background-clip: content-box;
|
|
}
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: hsl(var(--muted-foreground) / 0.4);
|
|
background-clip: content-box;
|
|
}
|
|
|
|
/* Focus ring — accent, 2px, with offset.
|
|
Components override this with Tailwind focus-visible:ring-* utilities
|
|
for a ring+offset combo that matches the rest of the design system. */
|
|
:focus-visible {
|
|
outline: 2px solid hsl(var(--ring));
|
|
outline-offset: 2px;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
*, *::before, *::after {
|
|
animation-duration: 0.001ms !important;
|
|
animation-iteration-count: 1 !important;
|
|
transition-duration: 0.001ms !important;
|
|
scroll-behavior: auto !important;
|
|
}
|
|
}
|
|
}
|
|
|
|
@layer components {
|
|
/* Tabular numerals everywhere a number is shown */
|
|
.num {
|
|
font-variant-numeric: tabular-nums;
|
|
font-feature-settings: "tnum", "ss01";
|
|
}
|
|
|
|
/* Display face — Instrument Serif. Used for the moments that need
|
|
editorial weight: hero numbers, page titles in document surfaces,
|
|
and the brand mark. */
|
|
.display {
|
|
font-family: var(--font-display);
|
|
font-weight: 400;
|
|
letter-spacing: -0.015em;
|
|
font-feature-settings: "ss01";
|
|
}
|
|
|
|
/* Data mono — Geist Mono with tabular-nums. The voice of every
|
|
id, code, dollar amount, and timestamp in the app. */
|
|
.mono {
|
|
font-family: var(--font-mono);
|
|
font-variant-numeric: tabular-nums;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
/* Soft card surface — a 1px hairline + a 1px inner highlight to
|
|
give the surface a sense of depth without a heavy shadow. */
|
|
.surface {
|
|
background-color: hsl(var(--card));
|
|
border: 1px solid hsl(var(--border));
|
|
box-shadow:
|
|
inset 0 1px 0 0 hsl(0 0% 100% / 0.04),
|
|
0 1px 2px 0 hsl(0 0% 0% / 0.4);
|
|
}
|
|
|
|
/* Subtle elevated surface — used for cards that should lift a
|
|
little more than the default. */
|
|
.surface-2 {
|
|
background: linear-gradient(180deg, hsl(222 16% 9%) 0%, hsl(222 16% 7.5%) 100%);
|
|
border: 1px solid hsl(var(--border));
|
|
box-shadow:
|
|
inset 0 1px 0 0 hsl(0 0% 100% / 0.05),
|
|
0 1px 3px 0 hsl(0 0% 0% / 0.5);
|
|
}
|
|
|
|
/* Hairline — a 1px separator that reads as a divider, not a border */
|
|
.hairline {
|
|
border-color: hsl(var(--border) / 0.6);
|
|
}
|
|
|
|
/* Active nav indicator — a thin left-aligned accent line with a
|
|
subtle glow that matches the instrument aesthetic. */
|
|
.nav-active {
|
|
background-color: hsl(var(--muted) / 0.6);
|
|
color: hsl(var(--foreground));
|
|
}
|
|
.nav-active::before {
|
|
content: "";
|
|
position: absolute;
|
|
left: -0.75rem;
|
|
top: 0.5rem;
|
|
bottom: 0.5rem;
|
|
width: 2px;
|
|
border-radius: 2px;
|
|
background-color: hsl(var(--accent));
|
|
box-shadow: 0 0 12px hsl(var(--accent) / 0.5);
|
|
}
|
|
|
|
/* Skip link — invisible until focused. */
|
|
.skip-link {
|
|
position: fixed;
|
|
top: 0.75rem;
|
|
left: 0.75rem;
|
|
z-index: 100;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
height: 2.25rem;
|
|
padding: 0 0.875rem;
|
|
border-radius: 0.625rem;
|
|
background-color: hsl(var(--card));
|
|
color: hsl(var(--foreground));
|
|
border: 1px solid hsl(var(--border));
|
|
box-shadow:
|
|
inset 0 1px 0 0 hsl(0 0% 100% / 0.04),
|
|
0 8px 24px hsl(0 0% 0% / 0.45);
|
|
font-size: 12.5px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.01em;
|
|
transform: translateY(-200%);
|
|
transition: transform 150ms ease-out;
|
|
}
|
|
.skip-link:focus-visible {
|
|
transform: translateY(0);
|
|
outline: none;
|
|
box-shadow:
|
|
inset 0 1px 0 0 hsl(0 0% 100% / 0.04),
|
|
0 0 0 2px hsl(var(--background)),
|
|
0 0 0 4px hsl(var(--ring)),
|
|
0 8px 24px hsl(0 0% 0% / 0.45);
|
|
}
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.skip-link {
|
|
transition: none;
|
|
}
|
|
}
|
|
|
|
/* Keyboard hint chip */
|
|
.kbd {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 0.15rem;
|
|
height: 1.375rem;
|
|
min-width: 1.375rem;
|
|
padding: 0 0.4rem;
|
|
border-radius: 0.375rem;
|
|
border: 1px solid hsl(var(--border));
|
|
background: hsl(var(--muted) / 0.5);
|
|
color: hsl(var(--muted-foreground));
|
|
font-family: var(--font-mono);
|
|
font-size: 10.5px;
|
|
font-weight: 500;
|
|
letter-spacing: 0.04em;
|
|
line-height: 1;
|
|
}
|
|
|
|
/* Section label — the all-caps eyebrow used everywhere */
|
|
.eyebrow {
|
|
font-size: 10.5px;
|
|
font-weight: 600;
|
|
letter-spacing: 0.18em;
|
|
text-transform: uppercase;
|
|
color: hsl(var(--muted-foreground));
|
|
}
|
|
|
|
/* Editorial serif headline — for hero numbers and document
|
|
surfaces. A single line height that breathes. */
|
|
.editorial {
|
|
font-family: var(--font-display);
|
|
font-weight: 400;
|
|
letter-spacing: -0.02em;
|
|
line-height: 1.05;
|
|
}
|
|
|
|
/* Row hover state — slightly more refined than the default
|
|
table hover. A subtle tint + a left accent strip. */
|
|
.row-hover {
|
|
transition: background-color 150ms ease;
|
|
}
|
|
.row-hover:hover {
|
|
background-color: hsl(var(--muted) / 0.4);
|
|
}
|
|
}
|
|
|
|
@layer utilities {
|
|
.text-balance {
|
|
text-wrap: balance;
|
|
}
|
|
.text-pretty {
|
|
text-wrap: pretty;
|
|
}
|
|
.ring-inset-hairline {
|
|
box-shadow: inset 0 0 0 1px hsl(var(--border) / 0.6);
|
|
}
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
Print styles — a clean paper-record rendering of detail drawers.
|
|
---------------------------------------------------------------------- */
|
|
@media print {
|
|
aside, header, [data-print="hide"], button[aria-label^="Close"] {
|
|
display: none !important;
|
|
}
|
|
:root {
|
|
--background: #ffffff;
|
|
--foreground: #000000;
|
|
--card: #ffffff;
|
|
--card-foreground: #000000;
|
|
--muted: #f5f5f5;
|
|
--muted-foreground: #444444;
|
|
--border: #cccccc;
|
|
--accent: #1a1a1a;
|
|
}
|
|
body {
|
|
background: #ffffff !important;
|
|
color: #000000 !important;
|
|
}
|
|
[role="dialog"] {
|
|
position: static !important;
|
|
inset: auto !important;
|
|
width: 100% !important;
|
|
max-width: 100% !important;
|
|
height: auto !important;
|
|
transform: none !important;
|
|
background: #ffffff !important;
|
|
box-shadow: none !important;
|
|
border: none !important;
|
|
}
|
|
[data-state="open"][data-radix-dialog-overlay],
|
|
.animate-fade-in,
|
|
.animate-shimmer,
|
|
.animate-scan {
|
|
animation: none !important;
|
|
transition: none !important;
|
|
}
|
|
[role="dialog"] * {
|
|
overflow: visible !important;
|
|
}
|
|
table { page-break-inside: avoid; }
|
|
section, h1, h2, h3 { page-break-after: avoid; }
|
|
*, *::before, *::after {
|
|
animation-duration: 0s !important;
|
|
}
|
|
}
|