Files
cyclone/src/components/inbox/InboxHeader.tsx
T
Tyler ff0985d244 Refine Inbox with editorial hero and paper-toned queue ledger
InboxHeader:
- Editorial dark hero replaces the 30px sticky header
- Massive 'Inbox.' (clamp 48-80px) with ghost amber 'TRIAGE' watermark
- Italic subtitle: 'Five lanes, one queue. N need eyes; N done today.'
- Right column: SUN JUN 21 / 14:15 / local
- Live status row: amber pulse + counts + date

Inbox page:
- Amber fold with '↘ FIVE LANES · ONE QUEUE ↙' between header and lanes
- Lanes stay dark (working surface preserved)
- New paper-toned Queue ledger panel below lanes:
  - Title block: 'The eye-flow, at a glance.' with need-eyes total
  - 5 paper tiles (Rejected / Payer rejected / Candidates / Unmatched / Done today)
  - Each tile shows lane accent dot + count + 'Clear'/'rows' chip
- Loading and error states now also use the new InboxHeader for consistency
- SummaryTile helper with paper-toned metric cards
2026-06-21 14:15:25 -06:00

183 lines
5.5 KiB
TypeScript

// ---------------------------------------------------------------------------
// InboxHeader
//
// Editorial dark hero for the Inbox. Larger than the previous 30px title
// so it carries weight against the bright lane surface below. "Inbox."
// is the page's anchor, the day/date sits as a serif italic, and the
// "N items need eyes / N done today" line replaces the small status
// pulse with a more dramatic mono announcement.
// ---------------------------------------------------------------------------
import { fmt } from "@/lib/format";
export function InboxHeader({
needEyesCount,
doneTodayCount,
}: {
needEyesCount: number;
doneTodayCount: number;
}) {
const now = new Date();
const day = now.toLocaleDateString("en-US", { weekday: "short" }).toUpperCase();
const date = now.toLocaleDateString("en-US", {
month: "short",
day: "2-digit",
});
const time = now.toLocaleTimeString("en-US", {
hour: "2-digit",
minute: "2-digit",
hour12: false,
});
return (
<header
className="sticky top-0 z-10 px-6 lg:px-10 pt-6 pb-5"
style={{
background: "var(--tt-bg)",
borderBottom: "1px solid var(--tt-bg-elev)",
}}
>
<div className="relative">
{/* Ghost "TRIAGE" watermark — a print-shop stamp behind the title. */}
<div
aria-hidden
className="pointer-events-none select-none absolute inset-x-0 top-1/2 -translate-y-1/2 whitespace-nowrap display text-center"
style={{
fontSize: "clamp(120px, 18vw, 260px)",
letterSpacing: "-0.05em",
opacity: 0.05,
lineHeight: 1,
color: "var(--tt-amber)",
}}
>
TRIAGE
</div>
<div className="relative flex items-end justify-between gap-6 flex-wrap">
<div className="min-w-0 max-w-3xl">
<div className="flex items-center gap-3 mb-3">
<div
className="h-px w-14"
style={{ backgroundColor: "var(--tt-amber)" }}
/>
<span
className="mono uppercase"
style={{
color: "var(--tt-amber)",
fontSize: 11,
letterSpacing: "0.22em",
fontWeight: 600,
}}
>
Inbox · Working surface
</span>
</div>
<h1
className="display tracking-[-0.04em]"
style={{
color: "var(--tt-ink)",
fontSize: "clamp(48px, 6vw, 80px)",
lineHeight: 0.92,
fontWeight: 400,
}}
>
Inbox.
</h1>
<p
className="display italic mt-3"
style={{
color: "var(--tt-ink-dim)",
fontSize: "clamp(15px, 1.4vw, 19px)",
lineHeight: 1.4,
maxWidth: "44ch",
}}
>
Five lanes, one queue.{" "}
<span style={{ color: "var(--tt-amber)" }}>
{needEyesCount}
</span>{" "}
need eyes; {doneTodayCount} are done today.
</p>
</div>
<div
className="flex flex-col items-start lg:items-end gap-2"
aria-label="Day and time"
>
<div
className="mono uppercase"
style={{
color: "var(--tt-ink-dim)",
fontSize: 11,
letterSpacing: "0.22em",
fontWeight: 500,
}}
>
{day} {date}
</div>
<div
className="display tabular-nums"
style={{
color: "var(--tt-ink)",
fontSize: 26,
lineHeight: 1,
fontWeight: 400,
}}
>
{time}
</div>
<div
className="mono uppercase"
style={{
color: "var(--tt-ink-dim)",
fontSize: 10,
letterSpacing: "0.20em",
}}
>
local
</div>
</div>
</div>
{/* Live status row — a horizontal "ticker" of the lane counts so
the operator can read the queue at a glance. */}
<div
className="relative mt-5 flex items-center gap-5 flex-wrap mono uppercase"
style={{
color: "var(--tt-ink-dim)",
fontSize: 11,
letterSpacing: "0.14em",
}}
>
<div className="flex items-center gap-2">
<span
aria-hidden
className="inline-block w-1.5 h-1.5 rounded-full animate-pulse-dot"
style={{ background: "var(--tt-amber)" }}
/>
<span>Live</span>
</div>
<span className="opacity-50">·</span>
<span>
<span style={{ color: "var(--tt-amber)", fontWeight: 600 }}>
{needEyesCount}
</span>{" "}
need eyes
</span>
<span className="opacity-50">·</span>
<span>
<span style={{ color: "var(--tt-ink)", fontWeight: 600 }}>
{doneTodayCount}
</span>{" "}
done today
</span>
<span className="opacity-50 hidden sm:inline">·</span>
<span className="hidden sm:inline">
{fmt.date(new Date().toISOString())}
</span>
</div>
</div>
</header>
);
}