Bump typography ~1.5× across the app

Producers were reading the UI at a squint. Two pieces:

1. @theme in globals.css now overrides every --text-* token (xs
   through 7xl) to 1.5× the Tailwind v4 default, with matching
   line-heights. This covers everything using the named classes
   (text-xs / text-sm / text-base / …) without touching markup.
   Also bumped .label-upper from 10px → 15px.

2. Scripted sweep of every arbitrary text-[Npx], fontSize={N}, and
   inline `fontSize: N` (recharts ticks) — 421 occurrences across
   82 files. Each N was rounded to round(N × 1.5). Idempotency is
   NOT preserved; running the sweep twice would scale twice.

Script lives at /tmp/scale-text-sizes.mjs for reference — not
committed. If we need to roll back, `git revert` this commit is
safe (pure display change, no schema/service impact).
This commit is contained in:
DJP 2026-04-21 13:42:54 -04:00
parent f2cdd8bd4c
commit ffd91cea04
82 changed files with 450 additions and 421 deletions

View file

@ -177,7 +177,7 @@ export default function BriefsPage() {
</Button>
)}
<div className="ml-auto text-[11px] text-[var(--muted-foreground)]">
<div className="ml-auto text-[17px] text-[var(--muted-foreground)]">
{filtered.length} of {rows.length} brief{rows.length === 1 ? "" : "s"}
</div>
</div>
@ -252,14 +252,14 @@ function BriefRowView({
return (
<tr className="border-b transition-colors hover:bg-[var(--muted)]/40">
<td className="px-3 py-2">
<span className="font-mono text-[10px] text-[var(--muted-foreground)]">
<span className="font-mono text-[15px] text-[var(--muted-foreground)]">
{brief.source}
</span>
</td>
<td className="px-3 py-2">
<div className="font-semibold">{brief.title}</div>
{brief.description && (
<div className="mt-0.5 line-clamp-1 text-[10px] text-[var(--muted-foreground)]">
<div className="mt-0.5 line-clamp-1 text-[15px] text-[var(--muted-foreground)]">
{brief.description}
</div>
)}
@ -269,7 +269,7 @@ function BriefRowView({
<div>
<div>{brief.requestorName}</div>
{brief.requestorEmail && (
<div className="text-[10px] text-[var(--muted-foreground)]">
<div className="text-[15px] text-[var(--muted-foreground)]">
{brief.requestorEmail}
</div>
)}
@ -282,7 +282,7 @@ function BriefRowView({
</td>
<td className="px-3 py-2">
{brief.clientTeam ? (
<Badge variant="outline" className="text-[10px]">
<Badge variant="outline" className="text-[15px]">
{brief.clientTeam.name}
</Badge>
) : (
@ -313,7 +313,7 @@ function BriefRowView({
>
<SelectTrigger
className={cn(
"h-7 border-0 text-[10px] font-bold uppercase tracking-wider",
"h-7 border-0 text-[15px] font-bold uppercase tracking-wider",
STATUS_STYLES[brief.status]
)}
>
@ -341,7 +341,7 @@ function BriefRowView({
<Button
size="sm"
variant="outline"
className="h-6 text-[10px]"
className="h-6 text-[15px]"
onClick={onPromote}
disabled={brief.status === "REJECTED" || brief.status === "ARCHIVED"}
>
@ -539,7 +539,7 @@ function PromoteBriefDialog({
placeholder="DJ-2026-001"
autoFocus
/>
<p className="mt-1 text-[10px] text-[var(--muted-foreground)]">
<p className="mt-1 text-[15px] text-[var(--muted-foreground)]">
Must be unique. Used as the short-form handle for the project.
</p>
</div>
@ -571,7 +571,7 @@ function Th({ label, className }: { label: string; className?: string }) {
return (
<th
className={cn(
"px-3 py-2 text-left text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]",
"px-3 py-2 text-left text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]",
className
)}
>

View file

@ -89,7 +89,7 @@ function KpiCard({
<p className="text-2xl font-bold tracking-tight">{value}</p>
<p className="text-xs text-[var(--muted-foreground)]">{title}</p>
{subtitle && (
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
{subtitle}
</p>
)}
@ -237,13 +237,13 @@ export default function DashboardPage() {
>
<XAxis
dataKey="name"
tick={{ fontSize: 10 }}
tick={{ fontSize: 15 }}
interval={0}
angle={-45}
textAnchor="end"
height={60}
/>
<YAxis tick={{ fontSize: 10 }} allowDecimals={false} />
<YAxis tick={{ fontSize: 15 }} allowDecimals={false} />
<RTooltip
contentStyle={{
fontSize: "12px",
@ -310,7 +310,7 @@ export default function DashboardPage() {
>
{deliv.name}
</Link>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
{deliv.project.name}
</p>
</div>

View file

@ -424,7 +424,7 @@ export default function DeliverablesPage() {
className="border-b transition-colors hover:bg-[var(--muted)]/40"
>
<td className="px-3 py-2 align-middle">
<span className="font-mono text-[11px] tabular-nums text-[var(--muted-foreground)]">
<span className="font-mono text-[17px] tabular-nums text-[var(--muted-foreground)]">
{r.project.omgJobNumber ?? "—"}
</span>
</td>
@ -435,7 +435,7 @@ export default function DeliverablesPage() {
>
<span className="font-medium">{r.project.name}</span>
{r.project.clientTeam && (
<span className="ml-1.5 text-[10px] text-[var(--muted-foreground)]">
<span className="ml-1.5 text-[15px] text-[var(--muted-foreground)]">
· {r.project.clientTeam.name}
</span>
)}
@ -467,12 +467,12 @@ export default function DeliverablesPage() {
{due ? format(due, "MMM d") : <span className="text-[var(--muted-foreground)]"></span>}
</td>
<td className="px-3 py-2 align-middle">
<Badge variant="outline" className={cn("text-[10px]", PRIORITY_COLORS[r.priority])}>
<Badge variant="outline" className={cn("text-[15px]", PRIORITY_COLORS[r.priority])}>
{r.priority}
</Badge>
</td>
<td className="px-3 py-2 align-middle">
<span className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
{r.status.replace(/_/g, " ")}
</span>
</td>
@ -494,7 +494,7 @@ function Th({ label, className }: { label: string; className?: string }) {
return (
<th
className={cn(
"px-3 py-2 text-left text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]",
"px-3 py-2 text-left text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]",
className
)}
>
@ -522,7 +522,7 @@ function SortableTh({
return (
<th
className={cn(
"cursor-pointer select-none px-3 py-2 text-left text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)] hover:text-[var(--foreground)]",
"cursor-pointer select-none px-3 py-2 text-left text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)] hover:text-[var(--foreground)]",
className
)}
onClick={() => onClick(sortKey)}

View file

@ -118,7 +118,7 @@ export default function NotificationsPage() {
<p className="mt-0.5 text-xs text-[var(--muted-foreground)]">
{notif.message}
</p>
<p className="mt-1 text-[10px] text-[var(--muted-foreground)]">
<p className="mt-1 text-[15px] text-[var(--muted-foreground)]">
{formatDistanceToNow(new Date(notif.createdAt), {
addSuffix: true,
})}

View file

@ -160,7 +160,7 @@ export default function DeliverableDetailPage() {
<div className="grid gap-x-6 gap-y-2 rounded-xl border p-4 text-sm shadow-[var(--shadow-xs)] sm:grid-cols-2 md:grid-cols-3">
{deliverable.cmfSku && (
<div className="sm:col-span-2 md:col-span-3">
<p className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
CMF / SKU
</p>
<p className="whitespace-pre-line">{deliverable.cmfSku}</p>
@ -168,7 +168,7 @@ export default function DeliverableDetailPage() {
)}
{deliverable.assetCount != null && (
<div>
<p className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Asset Count
</p>
<p>{deliverable.assetCount}</p>
@ -176,7 +176,7 @@ export default function DeliverableDetailPage() {
)}
{deliverable.requestedDueDate && (
<div>
<p className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Requested Due Date
</p>
<p>{format(new Date(deliverable.requestedDueDate), "MMM d, yyyy")}</p>
@ -184,7 +184,7 @@ export default function DeliverableDetailPage() {
)}
{deliverable.plannedDeliveryDate && (
<div>
<p className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Planned Delivery
</p>
<p>{format(new Date(deliverable.plannedDeliveryDate), "MMM d, yyyy")}</p>
@ -192,7 +192,7 @@ export default function DeliverableDetailPage() {
)}
{deliverable.actualDeliveryDate && (
<div>
<p className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Actual Delivery
</p>
<p>{format(new Date(deliverable.actualDeliveryDate), "MMM d, yyyy")}</p>
@ -200,7 +200,7 @@ export default function DeliverableDetailPage() {
)}
{deliverable.wfInputDate && (
<div>
<p className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
WF Input Date
</p>
<p>{format(new Date(deliverable.wfInputDate), "MMM d, yyyy")}</p>
@ -261,14 +261,14 @@ export default function DeliverableDetailPage() {
{/* Row 1 — step number · name · badges | status */}
<div className="flex items-center gap-2">
<span className="font-mono text-[11px] tabular-nums text-[var(--muted-foreground)] min-w-[1.5rem]">
<span className="font-mono text-[17px] tabular-nums text-[var(--muted-foreground)] min-w-[1.5rem]">
{stageOrder}.
</span>
<span className="text-sm font-semibold">{stageName}</span>
{isGate && (
<Badge
variant="outline"
className="h-4 gap-0.5 border-[var(--accent)] text-[9px] text-[var(--accent)] px-1"
className="h-4 gap-0.5 border-[var(--accent)] text-[14px] text-[var(--accent)] px-1"
>
<Shield className="h-2.5 w-2.5" />
GATE
@ -277,7 +277,7 @@ export default function DeliverableDetailPage() {
{isOptional && (
<Badge
variant="outline"
className="h-4 text-[9px] text-[var(--muted-foreground)] px-1"
className="h-4 text-[14px] text-[var(--muted-foreground)] px-1"
>
Optional
</Badge>
@ -327,7 +327,7 @@ export default function DeliverableDetailPage() {
size="sm"
variant={isSkip || isReopen ? "outline" : "default"}
className={cn(
"h-6 text-[11px] px-2",
"h-6 text-[17px] px-2",
(isSkip || isReopen) && "text-[var(--muted-foreground)]"
)}
disabled={updateStage.isPending}
@ -350,12 +350,12 @@ export default function DeliverableDetailPage() {
{/* Sub-status + blocked hint on their own third line only when present */}
{stage.subStatus && (
<div className="mt-1 text-[11px] italic text-[var(--muted-foreground)]">
<div className="mt-1 text-[17px] italic text-[var(--muted-foreground)]">
{stage.subStatus}
</div>
)}
{stage.status === "BLOCKED" && (
<div className="mt-1 flex items-center gap-1 text-[11px] text-[var(--status-blocked)]">
<div className="mt-1 flex items-center gap-1 text-[17px] text-[var(--status-blocked)]">
<Lock className="h-3 w-3" />
Waiting for prerequisite stages
</div>

View file

@ -59,7 +59,7 @@ const PRIORITY_STYLES: Record<string, string> = {
function MetaField({ label, value }: { label: string; value: string }) {
return (
<div>
<p className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
{label}
</p>
<p className="text-sm">{value}</p>
@ -280,7 +280,7 @@ export default function ProjectDetailPage() {
<Badge
key={a.id}
variant="secondary"
className="text-[10px]"
className="text-[15px]"
>
{a.user?.name ?? a.user?.email ?? "Unknown"}
</Badge>

View file

@ -345,7 +345,7 @@ export default function ProjectsPage() {
</SelectContent>
</Select>
)}
<div className="ml-auto text-[11px] tabular-nums text-[var(--muted-foreground)]">
<div className="ml-auto text-[17px] tabular-nums text-[var(--muted-foreground)]">
{filtered.length}
{projects && filtered.length !== projects.length
? ` of ${projects.length}`
@ -368,7 +368,7 @@ export default function ProjectsPage() {
<div className="overflow-auto rounded-lg border bg-[var(--card)]">
<table className="w-full min-w-[1100px] text-xs tabular-nums">
<thead>
<tr className="border-b bg-[var(--muted)]/30 text-left text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<tr className="border-b bg-[var(--muted)]/30 text-left text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<Th label="Owner" sortKey="owner" sort={sort} onSort={toggleSort} />
<Th label="Risk" sortKey="priority" sort={sort} onSort={toggleSort} />
<Th label="OMG #" sortKey="omgJobNumber" sort={sort} onSort={toggleSort} />
@ -456,19 +456,19 @@ function ProjectRow({ project, onDelete }: { project: Project; onDelete: () => v
<td className="px-2 py-1.5">
<Badge
variant="secondary"
className={cn("h-4 px-1.5 text-[9px]", PRIORITY_STYLES[project.priority])}
className={cn("h-4 px-1.5 text-[14px]", PRIORITY_STYLES[project.priority])}
>
{project.priority}
</Badge>
</td>
<td className="px-2 py-1.5 font-mono text-[11px]">
<td className="px-2 py-1.5 font-mono text-[17px]">
{project.omgJobNumber ?? (
<span className="text-[var(--muted-foreground)]"></span>
)}
</td>
<td className="px-2 py-1.5">
{project.clientTeam ? (
<span className="rounded-md bg-[var(--muted)] px-1.5 py-0.5 text-[10px] font-medium">
<span className="rounded-md bg-[var(--muted)] px-1.5 py-0.5 text-[15px] font-medium">
{project.clientTeam.name}
</span>
) : (
@ -478,7 +478,7 @@ function ProjectRow({ project, onDelete }: { project: Project; onDelete: () => v
<td className="px-2 py-1.5">
<Badge
variant="secondary"
className={cn("h-4 px-1.5 text-[9px]", STATUS_STYLES[project.status])}
className={cn("h-4 px-1.5 text-[14px]", STATUS_STYLES[project.status])}
>
{project.status.replace("_", " ")}
</Badge>
@ -551,7 +551,7 @@ function PipelineProgressCell({ progress }: { progress?: PipelineProgress }) {
if (completedDeliverables === totalDeliverables && totalDeliverables > 0) {
return (
<span className="inline-flex items-center gap-1 rounded-md bg-emerald-100 px-1.5 py-0.5 text-[10px] font-semibold text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300">
<span className="inline-flex items-center gap-1 rounded-md bg-emerald-100 px-1.5 py-0.5 text-[15px] font-semibold text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300">
Done
</span>
);
@ -565,7 +565,7 @@ function PipelineProgressCell({ progress }: { progress?: PipelineProgress }) {
return (
<div className="flex min-w-[140px] flex-col gap-0.5">
<div className="flex items-center gap-1.5 text-[10px]">
<div className="flex items-center gap-1.5 text-[15px]">
<span className="font-semibold">{dominantStage.name}</span>
<span className="text-[var(--muted-foreground)] tabular-nums">
{dominantStage.count}/{totalDeliverables}

View file

@ -95,7 +95,7 @@ export default function WeeklyReportPage() {
<p className="label-upper text-[var(--primary)]">
Dow Jones Studio Tracker
</p>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Confidential Oliver Agency
</p>
</div>

View file

@ -289,7 +289,7 @@ export default function ResourcesPage() {
{/* Filter bar */}
<div className="flex flex-wrap items-center gap-2 rounded-lg border bg-[var(--card)] p-3">
<div className="flex items-center gap-1.5">
<span className="text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
Role
</span>
<Select value={roleFilter} onValueChange={setRoleFilter}>
@ -307,7 +307,7 @@ export default function ResourcesPage() {
</div>
<div className="flex items-center gap-1.5">
<span className="text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
Team
</span>
<Select value={teamFilter} onValueChange={setTeamFilter}>
@ -326,7 +326,7 @@ export default function ResourcesPage() {
</div>
<div className="flex items-center gap-1.5">
<span className="text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
Group by
</span>
<Select value={groupBy} onValueChange={(v) => setGroupBy(v as GroupBy)}>
@ -343,7 +343,7 @@ export default function ResourcesPage() {
</div>
<div className="flex items-center gap-1.5">
<span className="text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
Sort
</span>
<Select
@ -393,7 +393,7 @@ export default function ResourcesPage() {
</colgroup>
<thead className="sticky top-0 z-10 bg-[var(--muted)]/60">
<tr className="border-b-2 border-[var(--border)]">
<th className="px-3 py-2 text-left text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
<th className="px-3 py-2 text-left text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
Resource
</th>
{weekDays.map((d) => {
@ -403,7 +403,7 @@ export default function ResourcesPage() {
key={d.toISOString()}
className="px-2 py-2 text-center"
>
<div className="text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
<div className="text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
{format(d, "EEE")}
</div>
<div
@ -417,7 +417,7 @@ export default function ResourcesPage() {
</th>
);
})}
<th className="px-2 py-2 text-center text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
<th className="px-2 py-2 text-center text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
Week
</th>
</tr>
@ -484,14 +484,14 @@ export default function ResourcesPage() {
>
<td className="border-r border-[var(--border)] px-3 py-2.5 align-top">
<div className="flex items-center gap-2.5">
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-[var(--primary)] to-[var(--primary)]/70 text-[11px] font-bold text-white">
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-[var(--primary)] to-[var(--primary)]/70 text-[17px] font-bold text-white">
{initialsOf(user.name, user.email)}
</div>
<div className="min-w-0">
<div className="truncate text-xs font-semibold">
{user.name ?? user.email}
</div>
<div className="text-[10px] text-[var(--muted-foreground)]">
<div className="text-[15px] text-[var(--muted-foreground)]">
{user.maxCapacity}h/day
</div>
</div>
@ -531,7 +531,7 @@ export default function ResourcesPage() {
date: day,
});
}}
className="flex items-center gap-1 rounded border border-dashed border-[var(--border)] px-1.5 py-0.5 text-[10px] font-semibold text-[var(--muted-foreground)] transition-colors hover:border-[var(--primary)] hover:text-[var(--primary)]"
className="flex items-center gap-1 rounded border border-dashed border-[var(--border)] px-1.5 py-0.5 text-[15px] font-semibold text-[var(--muted-foreground)] transition-colors hover:border-[var(--primary)] hover:text-[var(--primary)]"
>
<Plus className="h-2.5 w-2.5" />
Assign
@ -556,7 +556,7 @@ export default function ResourcesPage() {
>
{weekTotal}h
</div>
<div className="text-[10px] text-[var(--muted-foreground)]">
<div className="text-[15px] text-[var(--muted-foreground)]">
/ {weekCap}h
</div>
<div className="mt-1 h-1 overflow-hidden rounded bg-[var(--border)]">
@ -617,7 +617,7 @@ function FragmentRows({
>
<td
colSpan={7}
className="border-b border-[var(--border)] px-3 py-1.5 text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]"
className="border-b border-[var(--border)] px-3 py-1.5 text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]"
>
<span className="mr-2 opacity-60">{collapsed ? "▶" : "▼"}</span>
{group} · {count} {count === 1 ? "person" : "people"}
@ -642,7 +642,7 @@ function JobChip({
const color = jobColor(jobNumber);
return (
<div
className="group flex items-center gap-1 rounded border px-1.5 py-0.5 text-[10px] font-semibold tabular-nums transition-colors"
className="group flex items-center gap-1 rounded border px-1.5 py-0.5 text-[15px] font-semibold tabular-nums transition-colors"
style={{
borderColor: `${color}55`,
background: `${color}15`,
@ -687,7 +687,7 @@ function CapBar({ booked, capacity }: { booked: number; capacity: number }) {
</div>
<div
className={cn(
"mt-0.5 text-[9px] font-bold tabular-nums",
"mt-0.5 text-[14px] font-bold tabular-nums",
over ? "text-red-600" : warn ? "text-amber-600" : "text-emerald-600"
)}
>
@ -761,7 +761,7 @@ function AssignPopover({
</div>
<div className="flex min-h-0 flex-1 flex-col gap-3 p-3">
<div className="flex min-h-0 flex-col">
<label className="mb-1 block text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
<label className="mb-1 block text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
Job Number
</label>
<Input
@ -778,19 +778,19 @@ function AssignPopover({
producers can pick by context, not just by number. */}
<div className="mt-2 min-h-0 flex-1 overflow-y-auto rounded border">
{knownJobs.length === 0 ? (
<div className="px-3 py-4 text-center text-[10px] text-[var(--muted-foreground)]">
<div className="px-3 py-4 text-center text-[15px] text-[var(--muted-foreground)]">
No known jobs yet.
<br />
Upload the XLSX tracker in <span className="font-semibold">Projects Import XLSX</span> first,
or type a freeform number above.
</div>
) : suggestions.length === 0 ? (
<div className="px-3 py-4 text-center text-[10px] text-[var(--muted-foreground)]">
<div className="px-3 py-4 text-center text-[15px] text-[var(--muted-foreground)]">
No matches for &ldquo;{jobNumber}&rdquo;. Press Enter to assign it anyway.
</div>
) : (
<div>
<div className="sticky top-0 border-b bg-[var(--muted)]/40 px-2 py-1 text-[9px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
<div className="sticky top-0 border-b bg-[var(--muted)]/40 px-2 py-1 text-[14px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
{suggestions.length} available
</div>
{suggestions.map((j) => {
@ -814,12 +814,12 @@ function AssignPopover({
style={{ background: color }}
/>
<span
className="w-16 shrink-0 font-mono text-[11px] font-bold tabular-nums"
className="w-16 shrink-0 font-mono text-[17px] font-bold tabular-nums"
style={{ color }}
>
{j.jobNumber}
</span>
<span className="flex-1 truncate text-[10px] text-[var(--foreground)]">
<span className="flex-1 truncate text-[15px] text-[var(--foreground)]">
{j.name}
</span>
</button>
@ -830,7 +830,7 @@ function AssignPopover({
</div>
</div>
<div>
<label className="mb-1 block text-[10px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
<label className="mb-1 block text-[15px] font-bold uppercase tracking-wider text-[var(--muted-foreground)]">
Hours
</label>
<div className="flex gap-1">
@ -851,7 +851,7 @@ function AssignPopover({
))}
</div>
<div className="mt-1.5 flex items-center gap-1.5">
<span className="text-[10px] text-[var(--muted-foreground)]">Custom:</span>
<span className="text-[15px] text-[var(--muted-foreground)]">Custom:</span>
<Input
type="number"
min={0.5}
@ -864,11 +864,11 @@ function AssignPopover({
placeholder="—"
className="h-6 w-16 text-xs"
/>
<span className="text-[10px] text-[var(--muted-foreground)]">hrs</span>
<span className="text-[15px] text-[var(--muted-foreground)]">hrs</span>
</div>
</div>
{hours > 8 && (
<div className="flex items-center gap-1.5 rounded border border-amber-400/40 bg-amber-400/10 px-2 py-1 text-[10px] text-amber-700 dark:text-amber-400">
<div className="flex items-center gap-1.5 rounded border border-amber-400/40 bg-amber-400/10 px-2 py-1 text-[15px] text-amber-700 dark:text-amber-400">
<AlertCircle className="h-3 w-3" />
{hours}h will likely push this person over their daily cap.
</div>

View file

@ -245,7 +245,7 @@ function ActionRow({
{/* Action-specific params */}
{action.type === "update_stage_status" && (
<div className="space-y-1.5">
<Label className="label-upper text-[9px]">New Status</Label>
<Label className="label-upper text-[14px]">New Status</Label>
<Select
value={action.params.status || ""}
onValueChange={(v) => updateParam("status", v)}
@ -267,7 +267,7 @@ function ActionRow({
{action.type === "send_notification" && (
<div className="space-y-2">
<div className="space-y-1.5">
<Label className="label-upper text-[9px]">Title</Label>
<Label className="label-upper text-[14px]">Title</Label>
<Input
className="h-8 text-xs"
placeholder="e.g. {stageName} approved"
@ -276,7 +276,7 @@ function ActionRow({
/>
</div>
<div className="space-y-1.5">
<Label className="label-upper text-[9px]">Message</Label>
<Label className="label-upper text-[14px]">Message</Label>
<Textarea
className="min-h-[60px] text-xs"
placeholder="Use {fieldName} for event data..."
@ -285,7 +285,7 @@ function ActionRow({
/>
</div>
<div className="space-y-1.5">
<Label className="label-upper text-[9px]">Notify Roles</Label>
<Label className="label-upper text-[14px]">Notify Roles</Label>
<div className="flex gap-3">
{["ADMIN", "PRODUCER", "ARTIST"].map((role) => (
<label
@ -310,7 +310,7 @@ function ActionRow({
</div>
</div>
<div className="space-y-1.5">
<Label className="label-upper text-[9px]">
<Label className="label-upper text-[14px]">
Link (optional)
</Label>
<Input
@ -326,7 +326,7 @@ function ActionRow({
{action.type === "create_assignment" && (
<div className="space-y-2">
<div className="flex items-center gap-2">
<Label className="label-upper text-[9px]">
<Label className="label-upper text-[14px]">
Auto (skill-based)
</Label>
<Switch
@ -338,7 +338,7 @@ function ActionRow({
</div>
{action.params.userId !== "auto" && (
<div className="space-y-1.5">
<Label className="label-upper text-[9px]">User ID</Label>
<Label className="label-upper text-[14px]">User ID</Label>
<Input
className="h-8 text-xs"
placeholder="User ID to assign..."
@ -352,14 +352,14 @@ function ActionRow({
{action.type === "send_webhook" && (
<div className="space-y-1.5">
<Label className="label-upper text-[9px]">Webhook URL</Label>
<Label className="label-upper text-[14px]">Webhook URL</Label>
<Input
className="h-8 text-xs"
placeholder="https://..."
value={action.params.url || ""}
onChange={(e) => updateParam("url", e.target.value)}
/>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Microsoft Teams incoming webhook URLs are auto-detected and
formatted as Adaptive Cards.
</p>
@ -546,12 +546,12 @@ export default function AutomationRulesPage() {
</span>
<Badge
variant="outline"
className="text-[9px] h-4 px-1.5 shrink-0"
className="text-[14px] h-4 px-1.5 shrink-0"
>
{getEventLabel(trigger?.event)}
</Badge>
</div>
<div className="flex items-center gap-1.5 text-[10px] text-[var(--muted-foreground)] flex-wrap">
<div className="flex items-center gap-1.5 text-[15px] text-[var(--muted-foreground)] flex-wrap">
{condCount > 0 && (
<span>
{condCount} condition{condCount !== 1 ? "s" : ""}
@ -562,7 +562,7 @@ export default function AutomationRulesPage() {
<Badge
key={i}
variant="secondary"
className="text-[9px] h-4 px-1.5"
className="text-[14px] h-4 px-1.5"
>
{getActionLabel(a.type)}
</Badge>
@ -655,7 +655,7 @@ export default function AutomationRulesPage() {
<Badge
variant="secondary"
className={cn(
"text-[9px] h-4 px-1.5 shrink-0",
"text-[14px] h-4 px-1.5 shrink-0",
statusBadgeClass(exec.status)
)}
>
@ -663,7 +663,7 @@ export default function AutomationRulesPage() {
</Badge>
</button>
{expandedExec === exec.id && (
<div className="ml-8 mb-2 rounded border bg-[var(--muted)]/30 p-2 text-[10px]">
<div className="ml-8 mb-2 rounded border bg-[var(--muted)]/30 p-2 text-[15px]">
<div className="space-y-1">
<div>
<span className="font-medium">Event:</span>{" "}
@ -679,7 +679,7 @@ export default function AutomationRulesPage() {
<summary className="font-medium text-[var(--muted-foreground)]">
Payload &amp; Results
</summary>
<pre className="mt-1 overflow-auto rounded bg-[var(--muted)] p-1.5 text-[9px] max-h-[200px]">
<pre className="mt-1 overflow-auto rounded bg-[var(--muted)] p-1.5 text-[14px] max-h-[200px]">
{JSON.stringify(
{
payload: (exec.triggeredBy as any)?.payload,
@ -715,7 +715,7 @@ export default function AutomationRulesPage() {
<div className="space-y-5">
{/* Name */}
<div className="space-y-1.5">
<Label className="label-upper text-[10px]">Name</Label>
<Label className="label-upper text-[15px]">Name</Label>
<Input
placeholder="e.g. Auto-notify on approval"
value={formName}
@ -726,7 +726,7 @@ export default function AutomationRulesPage() {
{/* Description */}
<div className="space-y-1.5">
<Label className="label-upper text-[10px]">
<Label className="label-upper text-[15px]">
Description (optional)
</Label>
<Input
@ -739,7 +739,7 @@ export default function AutomationRulesPage() {
{/* Trigger Event */}
<div className="space-y-1.5">
<Label className="label-upper text-[10px]">
<Label className="label-upper text-[15px]">
Trigger Event
</Label>
<Select
@ -765,7 +765,7 @@ export default function AutomationRulesPage() {
{/* Conditions */}
{formEvent && (
<div className="space-y-2">
<Label className="label-upper text-[10px]">
<Label className="label-upper text-[15px]">
Conditions{" "}
<span className="font-normal normal-case text-[var(--muted-foreground)]">
(all must match)
@ -799,7 +799,7 @@ export default function AutomationRulesPage() {
{/* Actions */}
<div className="space-y-2">
<Label className="label-upper text-[10px]">Actions</Label>
<Label className="label-upper text-[15px]">Actions</Label>
{formActions.map((action, i) => (
<ActionRow
key={i}
@ -826,7 +826,7 @@ export default function AutomationRulesPage() {
{/* Enabled */}
<div className="flex items-center justify-between">
<Label className="label-upper text-[10px]">Enabled</Label>
<Label className="label-upper text-[15px]">Enabled</Label>
<Switch checked={formEnabled} onCheckedChange={setFormEnabled} />
</div>
</div>

View file

@ -156,7 +156,7 @@ export default function ClientTeamsSettingsPage() {
<div className="flex items-center gap-2">
<Users className="h-4 w-4" />
<span>{team.name}</span>
<Badge variant="outline" className="h-4 px-1 text-[9px]">
<Badge variant="outline" className="h-4 px-1 text-[14px]">
{team.slug}
</Badge>
</div>
@ -171,7 +171,7 @@ export default function ClientTeamsSettingsPage() {
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div className="flex gap-3 text-[11px] text-[var(--muted-foreground)]">
<div className="flex gap-3 text-[17px] text-[var(--muted-foreground)]">
<span>
{team._count?.userMemberships ?? 0} member
{(team._count?.userMemberships ?? 0) !== 1 ? "s" : ""}
@ -221,7 +221,7 @@ export default function ClientTeamsSettingsPage() {
<div className="space-y-1">
{(team.userMemberships ?? []).length === 0 ? (
<p className="py-2 text-[11px] text-[var(--muted-foreground)]">
<p className="py-2 text-[17px] text-[var(--muted-foreground)]">
No members. Users without a team membership won't see any
projects on this team.
</p>
@ -236,12 +236,12 @@ export default function ClientTeamsSettingsPage() {
{m.user.isExternal && (
<Badge
variant="outline"
className="h-4 px-1 text-[9px] text-amber-600"
className="h-4 px-1 text-[14px] text-amber-600"
>
client
</Badge>
)}
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
{m.user.email}
</span>
</div>

View file

@ -203,7 +203,7 @@ function FieldSection({ entityType, label }: { entityType: EntityType; label: st
))}
</SelectContent>
</Select>
<label className="flex shrink-0 items-center gap-1 text-[10px] text-[var(--muted-foreground)]">
<label className="flex shrink-0 items-center gap-1 text-[15px] text-[var(--muted-foreground)]">
<Checkbox
checked={editRequired}
onCheckedChange={(v) => setEditRequired(v === true)}
@ -236,19 +236,19 @@ function FieldSection({ entityType, label }: { entityType: EntityType; label: st
<span className="text-sm font-medium">{field.fieldName}</span>
<Badge
variant="secondary"
className={cn("text-[9px] h-4 px-1.5", getFieldTypeStyle(field.fieldType))}
className={cn("text-[14px] h-4 px-1.5", getFieldTypeStyle(field.fieldType))}
>
{getFieldTypeLabel(field.fieldType)}
</Badge>
{field.isRequired && (
<Badge
variant="outline"
className="text-[9px] h-4 px-1 text-red-500 border-red-200 dark:border-red-800"
className="text-[14px] h-4 px-1 text-red-500 border-red-200 dark:border-red-800"
>
Required
</Badge>
)}
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
#{field.order}
</span>
</div>

View file

@ -190,7 +190,7 @@ export default function NotificationRulesPage() {
<span className="text-sm font-medium truncate">
{rule.name}
</span>
<Badge variant="outline" className="text-[9px] h-4 px-1.5 shrink-0">
<Badge variant="outline" className="text-[14px] h-4 px-1.5 shrink-0">
{getEventLabel(rule.event)}
</Badge>
</div>
@ -200,7 +200,7 @@ export default function NotificationRulesPage() {
key={ch}
variant="secondary"
className={cn(
"text-[9px] h-4 px-1.5",
"text-[14px] h-4 px-1.5",
ch === "IN_APP"
? "bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300"
: "bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300"
@ -213,7 +213,7 @@ export default function NotificationRulesPage() {
<Badge
key={role}
variant="outline"
className="text-[9px] h-4 px-1.5"
className="text-[14px] h-4 px-1.5"
>
{role}
</Badge>
@ -257,7 +257,7 @@ export default function NotificationRulesPage() {
<div className="space-y-4">
{/* Name */}
<div className="space-y-1.5">
<Label className="label-upper text-[10px]">Name</Label>
<Label className="label-upper text-[15px]">Name</Label>
<Input
placeholder="Rule name..."
value={formName}
@ -268,7 +268,7 @@ export default function NotificationRulesPage() {
{/* Event */}
<div className="space-y-1.5">
<Label className="label-upper text-[10px]">Event</Label>
<Label className="label-upper text-[15px]">Event</Label>
<Select value={formEvent} onValueChange={setFormEvent}>
<SelectTrigger className="h-8 text-sm">
<SelectValue placeholder="Select an event..." />
@ -285,7 +285,7 @@ export default function NotificationRulesPage() {
{/* Channels */}
<div className="space-y-1.5">
<Label className="label-upper text-[10px]">Channels</Label>
<Label className="label-upper text-[15px]">Channels</Label>
<div className="flex gap-4">
{CHANNELS.map((ch) => (
<label
@ -304,7 +304,7 @@ export default function NotificationRulesPage() {
{/* Recipient Roles */}
<div className="space-y-1.5">
<Label className="label-upper text-[10px]">
<Label className="label-upper text-[15px]">
Recipient Roles
</Label>
<div className="flex flex-wrap gap-4">
@ -325,7 +325,7 @@ export default function NotificationRulesPage() {
{/* Enabled toggle */}
<div className="flex items-center justify-between">
<Label className="label-upper text-[10px]">Enabled</Label>
<Label className="label-upper text-[15px]">Enabled</Label>
<Switch checked={formEnabled} onCheckedChange={setFormEnabled} />
</div>
</div>

View file

@ -157,19 +157,19 @@ export default function PermissionsPage() {
<table className="w-full text-sm">
<thead>
<tr className="border-b">
<th className="label-upper pb-2 pr-4 text-left text-[10px] tracking-wider text-[var(--muted-foreground)]">
<th className="label-upper pb-2 pr-4 text-left text-[15px] tracking-wider text-[var(--muted-foreground)]">
Permission
</th>
{ROLES.map((role) => (
<th key={role} className="pb-2 px-3 text-center min-w-[100px]">
<div className="flex flex-col items-center gap-1.5">
<Badge className={cn("text-[10px] px-2", ROLE_COLORS[role])}>
<Badge className={cn("text-[15px] px-2", ROLE_COLORS[role])}>
{role}
</Badge>
{dirty.has(role) && role !== "ADMIN" && (
<Button
size="sm"
className="h-5 px-2 text-[10px]"
className="h-5 px-2 text-[15px]"
onClick={() => saveRole(role)}
disabled={updatePerms.isPending}
>
@ -188,7 +188,7 @@ export default function PermissionsPage() {
<tr>
<td
colSpan={ROLES.length + 1}
className="label-upper pt-4 pb-1 text-[10px] font-semibold tracking-wider text-[var(--primary)]"
className="label-upper pt-4 pb-1 text-[15px] font-semibold tracking-wider text-[var(--primary)]"
>
{group.label}
</td>
@ -252,7 +252,7 @@ export default function PermissionsPage() {
<div className="mt-4 flex items-center gap-2 rounded-lg border border-[var(--border)] bg-[var(--muted)]/30 px-3 py-2">
<Shield className="h-3.5 w-3.5 text-purple-500 shrink-0" />
<p className="text-[11px] text-[var(--muted-foreground)]">
<p className="text-[17px] text-[var(--muted-foreground)]">
Admin role always has all permissions and cannot be modified.
Changes are saved per-role and take effect immediately.
</p>

View file

@ -192,7 +192,7 @@ export default function PipelineEditorPage({ params }: PageProps) {
)}
</div>
{pl.isDefault && (
<Badge className="bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300 text-[9px] h-4 px-1.5">
<Badge className="bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300 text-[14px] h-4 px-1.5">
<Star className="mr-0.5 h-2.5 w-2.5" />
Default
</Badge>
@ -208,7 +208,7 @@ export default function PipelineEditorPage({ params }: PageProps) {
<Star className="mr-1 h-3 w-3" />
{pl.isDefault ? "Remove Default" : "Set Default"}
</Button>
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
{pl._count?.projects ?? 0} projects
</span>
</div>
@ -227,10 +227,10 @@ export default function PipelineEditorPage({ params }: PageProps) {
{/* Left: Stage list */}
<div className="rounded-lg border bg-[var(--card)] p-3">
<div className="mb-2 flex items-center justify-between">
<span className="label-upper text-[10px] font-semibold tracking-wider text-[var(--muted-foreground)]">
<span className="label-upper text-[15px] font-semibold tracking-wider text-[var(--muted-foreground)]">
Stages
</span>
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
{stages.length} total
</span>
</div>
@ -246,7 +246,7 @@ export default function PipelineEditorPage({ params }: PageProps) {
{/* Right: Dependency + rework graph */}
<div className="rounded-lg border bg-[var(--card)] overflow-hidden" style={{ minHeight: 500 }}>
<div className="flex items-center justify-between border-b px-3 py-2">
<span className="label-upper text-[10px] font-semibold tracking-wider text-[var(--muted-foreground)]">
<span className="label-upper text-[15px] font-semibold tracking-wider text-[var(--muted-foreground)]">
Workflow Graph
</span>
<div className="flex items-center gap-0.5 rounded-md border bg-[var(--muted)]/40 p-0.5">
@ -254,7 +254,7 @@ export default function PipelineEditorPage({ params }: PageProps) {
type="button"
size="sm"
variant={graphMode === "dependency" ? "default" : "ghost"}
className="h-6 gap-1 px-2 text-[10px]"
className="h-6 gap-1 px-2 text-[15px]"
onClick={() => setGraphMode("dependency")}
title="Drag between stages to create forward dependencies"
>
@ -265,7 +265,7 @@ export default function PipelineEditorPage({ params }: PageProps) {
type="button"
size="sm"
variant={graphMode === "rework" ? "default" : "ghost"}
className="h-6 gap-1 px-2 text-[10px]"
className="h-6 gap-1 px-2 text-[15px]"
onClick={() => setGraphMode("rework")}
title="Drag backward (higher → lower order) to allow pushing work back on failure"
>
@ -274,7 +274,7 @@ export default function PipelineEditorPage({ params }: PageProps) {
</Button>
</div>
</div>
<div className="border-b bg-[var(--muted)]/20 px-3 py-1.5 text-[10px] text-[var(--muted-foreground)]">
<div className="border-b bg-[var(--muted)]/20 px-3 py-1.5 text-[15px] text-[var(--muted-foreground)]">
{graphMode === "dependency" ? (
<>Drag from one stage to another to add a <strong>forward prerequisite</strong>. Click the × on a solid line to remove.</>
) : (

View file

@ -117,7 +117,7 @@ export default function PipelinesPage() {
<CardTitle className="flex items-center gap-2 text-sm">
{pipeline.name}
{pipeline.isDefault && (
<Badge className="bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300 text-[9px] h-4 px-1.5">
<Badge className="bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300 text-[14px] h-4 px-1.5">
<Star className="mr-0.5 h-2.5 w-2.5" />
Default
</Badge>
@ -130,7 +130,7 @@ export default function PipelinesPage() {
{pipeline.description}
</p>
)}
<div className="flex items-center gap-3 text-[10px] text-[var(--muted-foreground)]">
<div className="flex items-center gap-3 text-[15px] text-[var(--muted-foreground)]">
<span className="label-upper">
{pipeline.stages?.length ?? 0} stages
</span>

View file

@ -170,7 +170,7 @@ export default function PodsSettingsPage() {
<div className="flex items-center gap-2">
<Users2 className="h-4 w-4" />
<span>{pod.name}</span>
<Badge variant="outline" className="h-4 px-1 text-[9px]">
<Badge variant="outline" className="h-4 px-1 text-[14px]">
{pod.slug}
</Badge>
</div>
@ -187,7 +187,7 @@ export default function PodsSettingsPage() {
<CardContent className="space-y-3">
{/* Lead selector */}
<div className="space-y-1">
<label className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<label className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Pod lead
</label>
<Select
@ -247,7 +247,7 @@ export default function PodsSettingsPage() {
{/* Member list */}
<div className="space-y-1">
{(pod.members ?? []).length === 0 ? (
<p className="py-2 text-[11px] text-[var(--muted-foreground)]">
<p className="py-2 text-[17px] text-[var(--muted-foreground)]">
No members yet.
</p>
) : (
@ -262,7 +262,7 @@ export default function PodsSettingsPage() {
)}
<span>{u.name || u.email}</span>
{u.department && (
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
· {u.department}
</span>
)}

View file

@ -190,7 +190,7 @@ export default function SkillsSettingsPage() {
>
<div className="flex items-center gap-2">
<span className="text-sm font-medium">{skill.name}</span>
<Badge variant="outline" className="text-[9px] h-4 px-1">
<Badge variant="outline" className="text-[14px] h-4 px-1">
<Users className="mr-0.5 h-2.5 w-2.5" />
{skill._count?.users ?? 0}
</Badge>
@ -278,7 +278,7 @@ export default function SkillsSettingsPage() {
{hasSkill && (
<Badge
variant="secondary"
className={cn("text-[9px] h-4 px-1.5", getSkillLevelStyle(currentLevel))}
className={cn("text-[14px] h-4 px-1.5", getSkillLevelStyle(currentLevel))}
>
{SKILL_LEVELS.find((l) => l.value === currentLevel)?.label}
</Badge>
@ -294,7 +294,7 @@ export default function SkillsSettingsPage() {
}
}}
>
<SelectTrigger className="h-6 w-[110px] text-[10px] border-none bg-transparent">
<SelectTrigger className="h-6 w-[110px] text-[15px] border-none bg-transparent">
<SelectValue placeholder="Not set" />
</SelectTrigger>
<SelectContent>

View file

@ -168,12 +168,12 @@ export default function TeamSettingsPage() {
</span>
<Badge
variant="secondary"
className={cn("text-[9px] h-4 shrink-0 px-1.5", ROLE_STYLES[user.role] || "")}
className={cn("text-[14px] h-4 shrink-0 px-1.5", ROLE_STYLES[user.role] || "")}
>
{user.role}
</Badge>
</div>
<div className="flex items-center gap-2 text-[11px] text-[var(--muted-foreground)]">
<div className="flex items-center gap-2 text-[17px] text-[var(--muted-foreground)]">
<Mail className="h-3 w-3 shrink-0" />
<span className="truncate">{user.email}</span>
{user.department && (
@ -235,30 +235,30 @@ export default function TeamSettingsPage() {
{lastInvite && (
<div className="rounded-md border border-[var(--primary)]/30 bg-[var(--primary)]/5 p-3">
<div className="mb-1.5 flex items-center justify-between gap-2">
<p className="text-[10px] font-semibold uppercase tracking-wider text-[var(--primary)]">
<p className="text-[15px] font-semibold uppercase tracking-wider text-[var(--primary)]">
Invite link for {lastInvite.email}
</p>
<button
onClick={() => setLastInvite(null)}
className="text-[10px] text-[var(--muted-foreground)] hover:text-[var(--foreground)]"
className="text-[15px] text-[var(--muted-foreground)] hover:text-[var(--foreground)]"
>
dismiss
</button>
</div>
<div className="flex items-center gap-2">
<code className="flex-1 truncate rounded bg-[var(--background)] px-2 py-1 font-mono text-[11px]">
<code className="flex-1 truncate rounded bg-[var(--background)] px-2 py-1 font-mono text-[17px]">
{lastInvite.url}
</code>
<Button
size="sm"
variant="outline"
className="h-7 shrink-0 text-[11px]"
className="h-7 shrink-0 text-[17px]"
onClick={copyAcceptUrl}
>
Copy
</Button>
</div>
<p className="mt-1.5 text-[10px] text-[var(--muted-foreground)]">
<p className="mt-1.5 text-[15px] text-[var(--muted-foreground)]">
Share this link with the user it lets them set a password
and sign in. Valid for 7 days.
</p>
@ -293,19 +293,19 @@ export default function TeamSettingsPage() {
<span className="truncate text-sm font-medium">{inv.email}</span>
<Badge
variant="secondary"
className={cn("text-[9px] h-4 shrink-0 px-1.5", ROLE_STYLES[inv.role] || "")}
className={cn("text-[14px] h-4 shrink-0 px-1.5", ROLE_STYLES[inv.role] || "")}
>
{inv.role}
</Badge>
<Badge
variant="secondary"
className={cn("text-[9px] h-4 shrink-0 px-1.5", status.className)}
className={cn("text-[14px] h-4 shrink-0 px-1.5", status.className)}
>
<StatusIcon className="mr-0.5 h-2.5 w-2.5" />
{status.label}
</Badge>
</div>
<p className="text-[11px] text-[var(--muted-foreground)]">
<p className="text-[17px] text-[var(--muted-foreground)]">
Invited by {inv.invitedBy?.name || inv.invitedBy?.email || "Unknown"}
</p>
</div>

View file

@ -108,7 +108,7 @@ export default function TimelinePage() {
<p className="text-xl font-bold">
{isLoading ? "—" : totalProjects}
</p>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Projects
</p>
</div>
@ -124,7 +124,7 @@ export default function TimelinePage() {
<p className="text-xl font-bold">
{isLoading ? "—" : totalDeliverables}
</p>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Deliverables
</p>
</div>
@ -140,7 +140,7 @@ export default function TimelinePage() {
<p className="text-xl font-bold">
{isLoading ? "—" : `${avgCompletion}%`}
</p>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Avg Completion
</p>
</div>
@ -163,7 +163,7 @@ export default function TimelinePage() {
<p className="text-xl font-bold">
{isLoading ? "—" : totalOverdue}
</p>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Overdue Deliverables
</p>
</div>

View file

@ -85,7 +85,7 @@ export default function WorkloadPage() {
</div>
<div>
<p className="text-xl font-bold">{isLoading ? "—" : totalMembers}</p>
<p className="text-[10px] text-[var(--muted-foreground)]">Team Members</p>
<p className="text-[15px] text-[var(--muted-foreground)]">Team Members</p>
</div>
</CardContent>
</Card>
@ -97,7 +97,7 @@ export default function WorkloadPage() {
</div>
<div>
<p className="text-xl font-bold">{isLoading ? "—" : totalActiveAssignments}</p>
<p className="text-[10px] text-[var(--muted-foreground)]">Active Assignments</p>
<p className="text-[15px] text-[var(--muted-foreground)]">Active Assignments</p>
</div>
</CardContent>
</Card>
@ -109,7 +109,7 @@ export default function WorkloadPage() {
</div>
<div>
<p className="text-xl font-bold">{isLoading ? "—" : `${avgUtilization}%`}</p>
<p className="text-[10px] text-[var(--muted-foreground)]">Avg Utilization</p>
<p className="text-[15px] text-[var(--muted-foreground)]">Avg Utilization</p>
</div>
</CardContent>
</Card>
@ -128,7 +128,7 @@ export default function WorkloadPage() {
</div>
<div>
<p className="text-xl font-bold">{isLoading ? "—" : overloadedCount}</p>
<p className="text-[10px] text-[var(--muted-foreground)]">Overloaded</p>
<p className="text-[15px] text-[var(--muted-foreground)]">Overloaded</p>
</div>
</CardContent>
</Card>

View file

@ -105,7 +105,7 @@ function ChangePasswordForm() {
onChange={(e) => setNewPassword(e.target.value)}
className="h-9 text-sm"
/>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Minimum 10 characters.
</p>
</div>

View file

@ -81,10 +81,10 @@ export default function ForgotPasswordPage() {
</p>
{devResetUrl && (
<div className="rounded-md border border-[var(--border)] bg-[var(--muted)]/40 p-3">
<p className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Dev mode copy this link
</p>
<p className="mt-1 break-all font-mono text-[11px]">
<p className="mt-1 break-all font-mono text-[17px]">
{devResetUrl}
</p>
</div>
@ -92,7 +92,7 @@ export default function ForgotPasswordPage() {
</div>
)}
<div className="mt-8 text-[11px] text-[var(--muted-foreground)]">
<div className="mt-8 text-[17px] text-[var(--muted-foreground)]">
<Link href="/login" className="underline hover:text-[var(--foreground)]">
Back to sign in
</Link>

View file

@ -72,7 +72,7 @@ export function CredentialsLogin() {
</Label>
<Link
href="/forgot-password"
className="text-[10px] text-[var(--muted-foreground)] hover:text-[var(--foreground)]"
className="text-[15px] text-[var(--muted-foreground)] hover:text-[var(--foreground)]"
>
Forgot?
</Link>

View file

@ -113,7 +113,7 @@ export function MsalLogin({ config }: { config: MsalLoginConfig }) {
<Button
variant="outline"
disabled
className="w-full h-11 rounded-xl border-[var(--border)] text-[11px] font-semibold tracking-[0.06em] uppercase shadow-[var(--shadow-sm)]"
className="w-full h-11 rounded-xl border-[var(--border)] text-[17px] font-semibold tracking-[0.06em] uppercase shadow-[var(--shadow-sm)]"
>
<MicrosoftIcon />
Signing in
@ -130,7 +130,7 @@ export function MsalLogin({ config }: { config: MsalLoginConfig }) {
<Button
variant="outline"
onClick={() => { setErrorMsg(null); setState("idle"); }}
className="w-full h-11 rounded-xl border-[var(--border)] text-[11px] font-semibold tracking-[0.06em] uppercase shadow-[var(--shadow-sm)]"
className="w-full h-11 rounded-xl border-[var(--border)] text-[17px] font-semibold tracking-[0.06em] uppercase shadow-[var(--shadow-sm)]"
>
Try again
</Button>
@ -142,7 +142,7 @@ export function MsalLogin({ config }: { config: MsalLoginConfig }) {
<Button
variant="outline"
onClick={handleLogin}
className="w-full h-11 rounded-xl border-[var(--border)] text-[11px] font-semibold tracking-[0.06em] uppercase hover:bg-[var(--foreground)] hover:text-[var(--background)] transition-all shadow-[var(--shadow-sm)] hover:shadow-[var(--shadow-md)]"
className="w-full h-11 rounded-xl border-[var(--border)] text-[17px] font-semibold tracking-[0.06em] uppercase hover:bg-[var(--foreground)] hover:text-[var(--background)] transition-all shadow-[var(--shadow-sm)] hover:shadow-[var(--shadow-md)]"
>
<MicrosoftIcon />
Continue with Microsoft

View file

@ -27,7 +27,7 @@ export default async function LoginPage() {
{/* Left panel — green brand block */}
<div className="hidden w-[40%] flex-col justify-between bg-[var(--primary)] p-10 md:flex">
<div>
<p className="text-[9px] font-bold tracking-[0.2em] uppercase text-[var(--primary-foreground)]/60">
<p className="text-[14px] font-bold tracking-[0.2em] uppercase text-[var(--primary-foreground)]/60">
Oliver Agency
</p>
</div>
@ -35,12 +35,12 @@ export default async function LoginPage() {
<h1 className="font-heading text-4xl font-black leading-[1.05] tracking-[-0.03em] text-[var(--primary-foreground)]">
Dow Jones<br />Studio<br />Tracker
</h1>
<p className="mt-4 text-[11px] font-medium tracking-[0.06em] uppercase text-[var(--primary-foreground)]/60">
<p className="mt-4 text-[17px] font-medium tracking-[0.06em] uppercase text-[var(--primary-foreground)]/60">
Production pipeline for Dow Jones studio
</p>
</div>
<div>
<p className="text-[9px] font-semibold tracking-[0.15em] uppercase text-[var(--primary-foreground)]/40">
<p className="text-[14px] font-semibold tracking-[0.15em] uppercase text-[var(--primary-foreground)]/40">
Brandtech Group
</p>
</div>
@ -54,7 +54,7 @@ export default async function LoginPage() {
<h1 className="font-heading text-2xl font-black tracking-[-0.02em]">
Dow Jones Studio Tracker
</h1>
<p className="mt-1 text-[10px] font-semibold tracking-[0.1em] uppercase text-[var(--muted-foreground)]">
<p className="mt-1 text-[15px] font-semibold tracking-[0.1em] uppercase text-[var(--muted-foreground)]">
Oliver Agency
</p>
</div>
@ -74,7 +74,7 @@ export default async function LoginPage() {
<>
<div className="my-6 flex items-center gap-3">
<div className="h-px flex-1 bg-[var(--border)]" />
<span className="text-[10px] font-semibold uppercase tracking-[0.1em] text-[var(--muted-foreground)]">
<span className="text-[15px] font-semibold uppercase tracking-[0.1em] text-[var(--muted-foreground)]">
or
</span>
<div className="h-px flex-1 bg-[var(--border)]" />
@ -88,7 +88,7 @@ export default async function LoginPage() {
)}
<div className="mt-10 border-t pt-6">
<p className="text-[9px] font-semibold tracking-[0.12em] uppercase text-[var(--muted-foreground)]/60">
<p className="text-[14px] font-semibold tracking-[0.12em] uppercase text-[var(--muted-foreground)]/60">
&copy; {new Date().getFullYear()} Oliver Agency &middot; Brandtech Group
</p>
</div>

View file

@ -25,7 +25,7 @@ export default async function PendingPage() {
{/* Left panel — green brand block */}
<div className="hidden w-[40%] flex-col justify-between bg-[var(--primary)] p-10 md:flex">
<div>
<p className="text-[9px] font-bold tracking-[0.2em] uppercase text-[var(--primary-foreground)]/60">
<p className="text-[14px] font-bold tracking-[0.2em] uppercase text-[var(--primary-foreground)]/60">
Oliver Agency
</p>
</div>
@ -33,12 +33,12 @@ export default async function PendingPage() {
<h1 className="font-heading text-4xl font-black leading-[1.05] tracking-[-0.03em] text-[var(--primary-foreground)]">
HP CG<br />Production<br />Tracker
</h1>
<p className="mt-4 text-[11px] font-medium tracking-[0.06em] uppercase text-[var(--primary-foreground)]/60">
<p className="mt-4 text-[17px] font-medium tracking-[0.06em] uppercase text-[var(--primary-foreground)]/60">
Pipeline management for CG production
</p>
</div>
<div>
<p className="text-[9px] font-semibold tracking-[0.15em] uppercase text-[var(--primary-foreground)]/40">
<p className="text-[14px] font-semibold tracking-[0.15em] uppercase text-[var(--primary-foreground)]/40">
Brandtech Group
</p>
</div>
@ -52,7 +52,7 @@ export default async function PendingPage() {
<h1 className="font-heading text-2xl font-black tracking-[-0.02em]">
Dow Jones Studio Tracker
</h1>
<p className="mt-1 text-[10px] font-semibold tracking-[0.1em] uppercase text-[var(--muted-foreground)]">
<p className="mt-1 text-[15px] font-semibold tracking-[0.1em] uppercase text-[var(--muted-foreground)]">
Oliver Agency
</p>
</div>
@ -75,7 +75,7 @@ export default async function PendingPage() {
</p>
<div className="mt-3 rounded-lg border border-[var(--border)] bg-[var(--card)] p-3">
<p className="text-[10px] font-semibold tracking-[0.08em] uppercase text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold tracking-[0.08em] uppercase text-[var(--muted-foreground)]">
Signed in as
</p>
<p className="mt-1 text-sm font-medium">{session.user.email}</p>
@ -91,14 +91,14 @@ export default async function PendingPage() {
<Button
type="submit"
variant="outline"
className="h-10 rounded-xl border-[var(--border)] text-[11px] font-semibold tracking-[0.06em] uppercase"
className="h-10 rounded-xl border-[var(--border)] text-[17px] font-semibold tracking-[0.06em] uppercase"
>
Sign out
</Button>
</form>
<div className="mt-10 border-t pt-6">
<p className="text-[9px] font-semibold tracking-[0.12em] uppercase text-[var(--muted-foreground)]/60">
<p className="text-[14px] font-semibold tracking-[0.12em] uppercase text-[var(--muted-foreground)]/60">
&copy; {new Date().getFullYear()} Oliver Agency &middot; Brandtech Group
</p>
</div>

View file

@ -76,7 +76,7 @@ export default function ResetPasswordPage({ params }: Props) {
onChange={(e) => setNewPassword(e.target.value)}
className="h-9 text-sm"
/>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Minimum 10 characters.
</p>
</div>
@ -110,7 +110,7 @@ export default function ResetPasswordPage({ params }: Props) {
</Button>
</form>
<div className="mt-8 text-[11px] text-[var(--muted-foreground)]">
<div className="mt-8 text-[17px] text-[var(--muted-foreground)]">
<Link href="/login" className="underline hover:text-[var(--foreground)]">
Back to sign in
</Link>

View file

@ -7,6 +7,35 @@
--font-sans: "Public Sans", ui-sans-serif, system-ui, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, monospace;
/*
* Text scale every named size (text-xs / text-sm / text-base )
* is overridden 1.5× from the Tailwind v4 defaults. Producers were
* consistently reading the app at a squint; this pushes everything
* up without having to edit each utility class on the page.
*
* Arbitrary sizes like `text-[15px]` bypass this scale entirely
* and are handled by a separate sweep in the source files.
*/
--text-xs: 1.125rem; /* 18px (was 12) */
--text-xs--line-height: 1.5rem;
--text-sm: 1.3125rem; /* 21px (was 14) */
--text-sm--line-height: 1.875rem;
--text-base: 1.5rem; /* 24px (was 16) */
--text-base--line-height: 2.25rem;
--text-lg: 1.6875rem; /* 27px (was 18) */
--text-lg--line-height: 2.625rem;
--text-xl: 1.875rem; /* 30px (was 20) */
--text-xl--line-height: 2.625rem;
--text-2xl: 2.25rem; /* 36px (was 24) */
--text-2xl--line-height: 3rem;
--text-3xl: 2.8125rem; /* 45px (was 30) */
--text-3xl--line-height: 3.375rem;
--text-4xl: 3.375rem; /* 54px (was 36) */
--text-4xl--line-height: 3.75rem;
--text-5xl: 4.5rem; /* 72px (was 48) */
--text-6xl: 5.625rem; /* 90px (was 60) */
--text-7xl: 6.75rem; /* 108px (was 72) */
/* Border radius — modern soft corners, still geometric/professional */
--radius-sm: 6px;
--radius-md: 8px;
@ -189,7 +218,7 @@
* uppercase + wide tracking for labels, nav, section headers
*/
.label-upper {
font-size: 10px;
font-size: 15px; /* was 10px — scaled 1.5× with the rest of the type system */
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;

View file

@ -95,7 +95,7 @@ export function AssignArtistPopover({
<Badge
key={a.id}
variant="secondary"
className="gap-1 pr-1 text-[10px]"
className="gap-1 pr-1 text-[15px]"
>
{label}
{a.role && (
@ -121,7 +121,7 @@ export function AssignArtistPopover({
<Button
size="sm"
variant="ghost"
className="h-6 gap-1 px-1.5 text-[10px] text-[var(--muted-foreground)] hover:text-[var(--foreground)]"
className="h-6 gap-1 px-1.5 text-[15px] text-[var(--muted-foreground)] hover:text-[var(--foreground)]"
>
<UserPlus className="h-3 w-3" />
Assign
@ -178,7 +178,7 @@ export function AssignArtistPopover({
<div>
<p className="font-medium">{u.name ?? u.email}</p>
{u.name && (
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
{u.email}
</p>
)}

View file

@ -87,7 +87,7 @@ export function SkillMatchSuggestions({
{/* Avatar + Info */}
<Avatar className="h-7 w-7 shrink-0">
{s.userImage && <AvatarImage src={s.userImage} />}
<AvatarFallback className="text-[9px] font-semibold">
<AvatarFallback className="text-[14px] font-semibold">
{(s.userName || "?")
.split(" ")
.map((n: string) => n[0])
@ -103,7 +103,7 @@ export function SkillMatchSuggestions({
{s.userName}
</span>
{isAssigned && (
<Badge variant="outline" className="text-[8px] h-3.5 px-1 text-emerald-600">
<Badge variant="outline" className="text-[12px] h-3.5 px-1 text-emerald-600">
Assigned
</Badge>
)}
@ -114,10 +114,10 @@ export function SkillMatchSuggestions({
{s.matchedSkills?.map((ms: any) => (
<Tooltip key={ms.skillName} delayDuration={100}>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-0.5 text-[9px] text-emerald-600 dark:text-emerald-400">
<span className="inline-flex items-center gap-0.5 text-[14px] text-emerald-600 dark:text-emerald-400">
<CheckCircle2 className="h-2.5 w-2.5" />
{ms.skillName}
<span className="text-[8px] text-[var(--muted-foreground)]">
<span className="text-[12px] text-[var(--muted-foreground)]">
({SKILL_LEVEL_LABELS[ms.userLevel] || ms.userLevel})
</span>
</span>
@ -130,7 +130,7 @@ export function SkillMatchSuggestions({
{s.missingSkills?.map((ms: any) => (
<span
key={ms.skillName}
className="inline-flex items-center gap-0.5 text-[9px] text-[var(--muted-foreground)]"
className="inline-flex items-center gap-0.5 text-[14px] text-[var(--muted-foreground)]"
>
<Minus className="h-2.5 w-2.5" />
{ms.skillName}
@ -147,7 +147,7 @@ export function SkillMatchSuggestions({
<div className="flex flex-col items-center">
<span
className={cn(
"text-[10px] font-bold",
"text-[15px] font-bold",
s.utilizationPercent > 100
? "text-red-500"
: s.utilizationPercent > 75
@ -157,7 +157,7 @@ export function SkillMatchSuggestions({
>
{s.activeAssignments}/{s.maxCapacity}
</span>
<span className="text-[8px] text-[var(--muted-foreground)]">
<span className="text-[12px] text-[var(--muted-foreground)]">
load
</span>
</div>
@ -172,7 +172,7 @@ export function SkillMatchSuggestions({
<TooltipTrigger asChild>
<div
className={cn(
"flex h-7 w-7 items-center justify-center rounded-full text-[10px] font-bold",
"flex h-7 w-7 items-center justify-center rounded-full text-[15px] font-bold",
s.overallScore >= 70
? "bg-emerald-500/15 text-emerald-600 dark:text-emerald-400"
: s.overallScore >= 40

View file

@ -69,7 +69,7 @@ export function CalendarDayDetail({
<h3 className="text-sm font-bold tracking-tight">
{format(date, "EEEE, MMMM d")}
</h3>
<p className="text-[10px] font-semibold tracking-[0.1em] text-muted-foreground/70 uppercase mt-0.5">
<p className="text-[15px] font-semibold tracking-[0.1em] text-muted-foreground/70 uppercase mt-0.5">
{events.length} {events.length === 1 ? "stage" : "stages"} active
</p>
</div>

View file

@ -41,7 +41,7 @@ export function CalendarEventPill({
<Link
href={`/projects/${event.deliverable.project.id}/deliverables/${event.deliverable.id}`}
className={cn(
"group flex items-center gap-1.5 text-[11px] leading-tight",
"group flex items-center gap-1.5 text-[17px] leading-tight",
"pl-0 pr-1 py-[3px] rounded-sm",
"hover:bg-accent/60 transition-colors cursor-pointer",
"truncate"
@ -71,7 +71,7 @@ export function CalendarEventPill({
<span className="font-semibold text-sm truncate">
{event.deliverable.project.projectCode}
</span>
<StageStatusBadge status={event.status} className="text-[10px] shrink-0" />
<StageStatusBadge status={event.status} className="text-[15px] shrink-0" />
</div>
<div className="text-xs text-muted-foreground mt-0.5 truncate">
{event.deliverable.project.name}
@ -136,12 +136,12 @@ export function CalendarEventPill({
<span className="text-xs font-bold tracking-wide text-foreground">
{event.deliverable.project.projectCode}
</span>
<StageStatusBadge status={event.status} className="text-[10px]" />
<StageStatusBadge status={event.status} className="text-[15px]" />
</div>
<div className="text-xs text-muted-foreground mt-0.5 truncate">
{event.deliverable.name}
</div>
<div className="text-[10px] text-muted-foreground/70 mt-0.5">
<div className="text-[15px] text-muted-foreground/70 mt-0.5">
{event.stageDefinition?.name ?? event.template.name}
{event.assignments.length > 0 &&
` \u00b7 ${event.assignments.map((a) => a.user.name).join(", ")}`}

View file

@ -295,7 +295,7 @@ export function CalendarGrid({
{["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"].map((day) => (
<div
key={day}
className="py-2.5 text-center text-[10px] font-semibold tracking-[0.1em] text-muted-foreground/70"
className="py-2.5 text-center text-[15px] font-semibold tracking-[0.1em] text-muted-foreground/70"
>
{day}
</div>
@ -360,7 +360,7 @@ export function CalendarGrid({
{dayEvents.length > 0 && isCurrentMonth && (
<span
className={cn(
"text-[9px] font-bold tracking-wider tabular-nums rounded-full px-1.5 py-0.5 leading-none",
"text-[14px] font-bold tracking-wider tabular-nums rounded-full px-1.5 py-0.5 leading-none",
dayEvents.length <= 3 &&
"text-muted-foreground/60",
dayEvents.length > 3 &&
@ -381,7 +381,7 @@ export function CalendarGrid({
<CalendarEventPill key={event.id} event={event} />
))}
{overflow > 0 && (
<div className="text-[10px] font-semibold text-muted-foreground/60 pl-[11px] py-0.5 tracking-wide">
<div className="text-[15px] font-semibold text-muted-foreground/60 pl-[11px] py-0.5 tracking-wide">
+{overflow} more
</div>
)}
@ -468,7 +468,7 @@ export function CalendarGrid({
{dayEvents.length > 0 && isCurrentMonth && (
<span
className={cn(
"text-[9px] font-bold tracking-wider tabular-nums rounded-full px-1.5 py-0.5 leading-none",
"text-[14px] font-bold tracking-wider tabular-nums rounded-full px-1.5 py-0.5 leading-none",
dayEvents.length <= 3 &&
"text-muted-foreground/60",
dayEvents.length > 3 &&
@ -530,7 +530,7 @@ export function CalendarGrid({
href={`/projects/${seg.event.deliverable.project.id}/deliverables/${seg.event.deliverable.id}`}
className={cn(
"absolute flex items-center gap-1.5 px-2 h-[18px]",
"text-[10px] font-semibold leading-none truncate",
"text-[15px] font-semibold leading-none truncate",
"transition-all duration-150",
"hover:brightness-110 hover:shadow-sm",
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
@ -578,7 +578,7 @@ export function CalendarGrid({
</span>
<StageStatusBadge
status={seg.event.status}
className="text-[10px] shrink-0"
className="text-[15px] shrink-0"
/>
</div>
<div className="text-xs text-muted-foreground mt-0.5 truncate">
@ -647,7 +647,7 @@ export function CalendarGrid({
{/* Overflow indicator */}
{overflowCount > 0 && (
<div
className="absolute left-2 text-[9px] font-semibold text-muted-foreground/60 tracking-wide"
className="absolute left-2 text-[14px] font-semibold text-muted-foreground/60 tracking-wide"
style={{ top: MAX_VISIBLE_LANES * 22 + 3 }}
>
+{overflowCount} more

View file

@ -78,7 +78,7 @@ export function CalendarHeatmapToggle({
/>
<label
htmlFor="heatmap-toggle"
className="text-[10px] font-semibold tracking-[0.1em] uppercase text-muted-foreground/70 cursor-pointer select-none"
className="text-[15px] font-semibold tracking-[0.1em] uppercase text-muted-foreground/70 cursor-pointer select-none"
>
Heatmap
</label>
@ -142,7 +142,7 @@ export function CalendarHeatmapBar({
<div className="pb-2 pt-1">
{/* Legend labels */}
<div className="flex items-center justify-between mb-1.5 px-0.5">
<span className="text-[9px] font-semibold tracking-[0.1em] uppercase text-muted-foreground/50">
<span className="text-[14px] font-semibold tracking-[0.1em] uppercase text-muted-foreground/50">
{format(currentDate, "MMM")} Workload
</span>
<div className="flex items-center gap-2">
@ -151,7 +151,7 @@ export function CalendarHeatmapBar({
className="w-2 h-2 rounded-sm"
style={{ backgroundColor: heatColor(0.1) }}
/>
<span className="text-[8px] text-muted-foreground/40 font-medium">
<span className="text-[12px] text-muted-foreground/40 font-medium">
Light
</span>
</div>
@ -160,7 +160,7 @@ export function CalendarHeatmapBar({
className="w-2 h-2 rounded-sm"
style={{ backgroundColor: heatColor(0.5) }}
/>
<span className="text-[8px] text-muted-foreground/40 font-medium">
<span className="text-[12px] text-muted-foreground/40 font-medium">
Moderate
</span>
</div>
@ -169,7 +169,7 @@ export function CalendarHeatmapBar({
className="w-2 h-2 rounded-sm"
style={{ backgroundColor: heatColor(1) }}
/>
<span className="text-[8px] text-muted-foreground/40 font-medium">
<span className="text-[12px] text-muted-foreground/40 font-medium">
Heavy
</span>
</div>
@ -205,7 +205,7 @@ export function CalendarHeatmapBar({
>
<span
className={cn(
"text-[8px] font-bold leading-none tabular-nums",
"text-[12px] font-bold leading-none tabular-nums",
ratio > 0.5
? "text-white/90"
: ratio > 0
@ -218,7 +218,7 @@ export function CalendarHeatmapBar({
{count > 0 && (
<span
className={cn(
"text-[7px] font-bold leading-none mt-0.5 tabular-nums",
"text-[11px] font-bold leading-none mt-0.5 tabular-nums",
ratio > 0.5
? "text-white/70"
: "text-foreground/50"
@ -233,7 +233,7 @@ export function CalendarHeatmapBar({
className={cn(
"absolute -bottom-8 left-1/2 -translate-x-1/2 z-50",
"px-1.5 py-0.5 rounded bg-foreground text-background",
"text-[9px] font-medium whitespace-nowrap",
"text-[14px] font-medium whitespace-nowrap",
"opacity-0 scale-95 group-hover:opacity-100 group-hover:scale-100",
"transition-all duration-150 pointer-events-none"
)}

View file

@ -107,7 +107,7 @@ export function CalendarView() {
<div className="flex items-center gap-3">
{!isLoading && events.length > 0 && (
<>
<span className="text-[10px] font-semibold tracking-[0.1em] text-muted-foreground/70 uppercase tabular-nums">
<span className="text-[15px] font-semibold tracking-[0.1em] text-muted-foreground/70 uppercase tabular-nums">
{events.length} stages
</span>
<div className="w-px h-3.5 bg-border/40" />
@ -123,7 +123,7 @@ export function CalendarView() {
type="button"
onClick={() => setViewMode("bars")}
className={cn(
"flex items-center gap-1.5 px-2.5 py-1 rounded-md text-[10px] font-semibold tracking-[0.08em] uppercase transition-all duration-150",
"flex items-center gap-1.5 px-2.5 py-1 rounded-md text-[15px] font-semibold tracking-[0.08em] uppercase transition-all duration-150",
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/40",
viewMode === "bars"
? "bg-background text-foreground shadow-sm"
@ -139,7 +139,7 @@ export function CalendarView() {
type="button"
onClick={() => setViewMode("pills")}
className={cn(
"flex items-center gap-1.5 px-2.5 py-1 rounded-md text-[10px] font-semibold tracking-[0.08em] uppercase transition-all duration-150",
"flex items-center gap-1.5 px-2.5 py-1 rounded-md text-[15px] font-semibold tracking-[0.08em] uppercase transition-all duration-150",
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/40",
viewMode === "pills"
? "bg-background text-foreground shadow-sm"
@ -201,7 +201,7 @@ function StatusLegend() {
className="w-2 h-2 rounded-full shrink-0"
style={{ backgroundColor: `var(${item.var})` }}
/>
<span className="text-[9px] text-muted-foreground/60 font-medium">
<span className="text-[14px] text-muted-foreground/60 font-medium">
{item.label}
</span>
</div>

View file

@ -75,7 +75,7 @@ function ProviderBadge({ provider }: { provider: "claude" | "ollama" | "none" })
if (provider === "ollama") {
return (
<div className="flex items-center gap-1 rounded-full bg-orange-100 px-2 py-0.5 text-[10px] font-medium text-orange-700 dark:bg-orange-900/50 dark:text-orange-300">
<div className="flex items-center gap-1 rounded-full bg-orange-100 px-2 py-0.5 text-[15px] font-medium text-orange-700 dark:bg-orange-900/50 dark:text-orange-300">
<Zap className="h-2.5 w-2.5" />
Ollama
</div>
@ -83,7 +83,7 @@ function ProviderBadge({ provider }: { provider: "claude" | "ollama" | "none" })
}
return (
<div className="flex items-center gap-1 rounded-full bg-purple-100 px-2 py-0.5 text-[10px] font-medium text-purple-700 dark:bg-purple-900/50 dark:text-purple-300">
<div className="flex items-center gap-1 rounded-full bg-purple-100 px-2 py-0.5 text-[15px] font-medium text-purple-700 dark:bg-purple-900/50 dark:text-purple-300">
<Zap className="h-2.5 w-2.5" />
Claude
</div>
@ -98,7 +98,7 @@ function ToolCallIndicator({ toolCalls }: { toolCalls: ToolStatus[] }) {
{toolCalls.map((tc) => (
<div
key={tc.toolCallId}
className="flex items-center gap-1.5 text-[11px] text-[var(--muted-foreground)]"
className="flex items-center gap-1.5 text-[17px] text-[var(--muted-foreground)]"
>
{tc.status === "running" ? (
<Loader2 className="h-3 w-3 animate-spin text-blue-500" />
@ -168,10 +168,10 @@ function MutationConfirmCard({
</p>
{/* Show input details for transparency */}
<details className="mt-1.5">
<summary className="cursor-pointer text-[10px] text-amber-600 dark:text-amber-400 hover:underline">
<summary className="cursor-pointer text-[15px] text-amber-600 dark:text-amber-400 hover:underline">
Details
</summary>
<pre className="mt-1 max-h-24 overflow-auto rounded bg-amber-100 p-1.5 text-[10px] text-amber-900 dark:bg-amber-900/40 dark:text-amber-100">
<pre className="mt-1 max-h-24 overflow-auto rounded bg-amber-100 p-1.5 text-[15px] text-amber-900 dark:bg-amber-900/40 dark:text-amber-100">
{JSON.stringify(pending.input, null, 2)}
</pre>
</details>
@ -233,7 +233,7 @@ function SuggestionChips({
>
<span
className={cn(
"flex h-4 w-4 shrink-0 items-center justify-center rounded text-[9px] font-bold",
"flex h-4 w-4 shrink-0 items-center justify-center rounded text-[14px] font-bold",
s.type === "project" && "bg-blue-100 text-blue-700 dark:bg-blue-900/50 dark:text-blue-300",
s.type === "deliverable" && "bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-300",
s.type === "user" && "bg-purple-100 text-purple-700 dark:bg-purple-900/50 dark:text-purple-300",
@ -245,7 +245,7 @@ function SuggestionChips({
<span className="flex flex-col leading-tight">
<span className="font-medium">{s.label}</span>
{s.description && (
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
{s.description}
</span>
)}
@ -304,12 +304,12 @@ function EntityResultCard({
<p className="text-xs font-medium truncate">{entity.name}</p>
<div className="flex items-center gap-1.5 mt-0.5">
{entity.code && (
<span className="font-mono text-[9px] text-[var(--muted-foreground)]">
<span className="font-mono text-[14px] text-[var(--muted-foreground)]">
{entity.code}
</span>
)}
{entity.projectName && !isProject && (
<span className="text-[9px] text-[var(--muted-foreground)] truncate">
<span className="text-[14px] text-[var(--muted-foreground)] truncate">
in {entity.projectName}
</span>
)}
@ -320,7 +320,7 @@ function EntityResultCard({
{entity.status && !isUser && (
<Badge
className={cn(
"text-[8px] px-1.5 py-0 h-3.5 font-semibold",
"text-[12px] px-1.5 py-0 h-3.5 font-semibold",
statusColor(entity.status)
)}
>
@ -332,16 +332,16 @@ function EntityResultCard({
</div>
<div className="mt-1.5 flex items-center gap-2">
<span className="label-upper !text-[8px]">
<span className="label-upper !text-[12px]">
{isProject ? "Project" : isUser ? "Artist" : "Deliverable"}
</span>
{isUser && entity.status && (
<span className="text-[9px] text-[var(--muted-foreground)]">
<span className="text-[14px] text-[var(--muted-foreground)]">
{entity.status}
</span>
)}
{entity.priority && !isUser && (
<Badge variant="outline" className="text-[7px] px-1 py-0 h-3">
<Badge variant="outline" className="text-[11px] px-1 py-0 h-3">
{entity.priority}
</Badge>
)}
@ -455,7 +455,7 @@ function MessageBubble({
{message.isLoading && message.toolCalls && message.toolCalls.length > 0 && !message.content && (
<div className="mt-1.5 flex items-center gap-2">
<Loader2 className="h-3 w-3 animate-spin" />
<span className="text-[11px] text-[var(--muted-foreground)]">Composing response...</span>
<span className="text-[17px] text-[var(--muted-foreground)]">Composing response...</span>
</div>
)}
</>
@ -555,7 +555,7 @@ export function ChatPanel() {
<Bot className="h-4 w-4" />
AI Assistant
{pageContext.activeProjectId && (
<span className="flex items-center gap-1 rounded-full bg-blue-100 px-2 py-0.5 text-[10px] font-medium text-blue-700 dark:bg-blue-900/50 dark:text-blue-300">
<span className="flex items-center gap-1 rounded-full bg-blue-100 px-2 py-0.5 text-[15px] font-medium text-blue-700 dark:bg-blue-900/50 dark:text-blue-300">
<MapPin className="h-2.5 w-2.5" />
Project context active
</span>

View file

@ -70,7 +70,7 @@ export function CommandPalette() {
>
<Bot className="mr-2 h-4 w-4" />
AI Assistant
<span className="ml-auto text-[10px] text-[var(--muted-foreground)]">
<span className="ml-auto text-[15px] text-[var(--muted-foreground)]">
Ask anything
</span>
</CommandItem>

View file

@ -55,7 +55,7 @@ function CommentItem({
<div className="flex gap-2.5">
<Avatar className="h-7 w-7 shrink-0">
<AvatarImage src={comment.author?.image} />
<AvatarFallback className="text-[10px]">
<AvatarFallback className="text-[15px]">
{getInitials(comment.author?.name, comment.author?.email)}
</AvatarFallback>
</Avatar>
@ -64,7 +64,7 @@ function CommentItem({
<span className="text-xs font-medium">
{comment.author?.name ?? comment.author?.email ?? "Unknown"}
</span>
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
{formatDistanceToNow(new Date(comment.createdAt), {
addSuffix: true,
})}
@ -78,7 +78,7 @@ function CommentItem({
<Button
size="sm"
variant="ghost"
className="h-6 px-1.5 text-[10px] text-[var(--muted-foreground)]"
className="h-6 px-1.5 text-[15px] text-[var(--muted-foreground)]"
onClick={() => setShowReply(!showReply)}
>
<Reply className="mr-0.5 h-3 w-3" />
@ -88,7 +88,7 @@ function CommentItem({
<Button
size="sm"
variant="ghost"
className="h-6 px-1.5 text-[10px] text-[var(--muted-foreground)] hover:text-[var(--destructive)]"
className="h-6 px-1.5 text-[15px] text-[var(--muted-foreground)] hover:text-[var(--destructive)]"
onClick={() =>
deleteComment.mutate(comment.id, {
onError: (e) =>
@ -111,7 +111,7 @@ function CommentItem({
<div className="flex gap-1.5">
<Button
size="sm"
className="h-6 text-[10px]"
className="h-6 text-[15px]"
disabled={createComment.isPending || !replyText.trim()}
onClick={handleReply}
>
@ -120,7 +120,7 @@ function CommentItem({
<Button
size="sm"
variant="ghost"
className="h-6 text-[10px]"
className="h-6 text-[15px]"
onClick={() => setShowReply(false)}
>
Cancel

View file

@ -149,11 +149,11 @@ export function DeliverableBoard({
className="h-2 w-2 rounded-full"
style={{ background: col.accent }}
/>
<span className="text-[11px] font-bold uppercase tracking-wider">
<span className="text-[17px] font-bold uppercase tracking-wider">
{col.label}
</span>
</div>
<span className="rounded-full bg-[var(--card)] px-2 py-0.5 text-[10px] font-semibold tabular-nums text-[var(--muted-foreground)]">
<span className="rounded-full bg-[var(--card)] px-2 py-0.5 text-[15px] font-semibold tabular-nums text-[var(--muted-foreground)]">
{col.deliverables.length}
</span>
</div>
@ -169,7 +169,7 @@ export function DeliverableBoard({
)}
>
{col.deliverables.length === 0 && !snapshot.isDraggingOver && (
<div className="py-6 text-center text-[10px] text-[var(--muted-foreground)]/60">
<div className="py-6 text-center text-[15px] text-[var(--muted-foreground)]/60">
</div>
)}
@ -303,7 +303,7 @@ function DeliverableCard({ deliverable: d }: { deliverable: AllDeliverableRow })
className="block rounded-md border bg-[var(--card)] p-2.5 text-left shadow-[var(--shadow-xs)] transition-all hover:border-[var(--primary)] hover:shadow-[var(--shadow-sm)]"
>
{/* Top row: OMG #, priority dot, team */}
<div className="mb-1.5 flex items-center gap-1.5 text-[10px]">
<div className="mb-1.5 flex items-center gap-1.5 text-[15px]">
{d.project.omgJobNumber && (
<span className="font-mono tabular-nums text-[var(--muted-foreground)]">
#{d.project.omgJobNumber}
@ -316,7 +316,7 @@ function DeliverableCard({ deliverable: d }: { deliverable: AllDeliverableRow })
{d.project.clientTeam && (
<Badge
variant="outline"
className="ml-auto h-4 px-1 text-[9px] uppercase tracking-wider"
className="ml-auto h-4 px-1 text-[14px] uppercase tracking-wider"
>
{d.project.clientTeam.name}
</Badge>
@ -327,12 +327,12 @@ function DeliverableCard({ deliverable: d }: { deliverable: AllDeliverableRow })
<div className="mb-1 line-clamp-2 text-xs font-semibold leading-snug">{d.name}</div>
{/* Project name (smaller, muted) */}
<div className="mb-1.5 line-clamp-1 text-[10px] text-[var(--muted-foreground)]">
<div className="mb-1.5 line-clamp-1 text-[15px] text-[var(--muted-foreground)]">
{d.project.name}
</div>
{/* Assignee + deadline */}
<div className="flex items-center justify-between text-[10px] text-[var(--muted-foreground)]">
<div className="flex items-center justify-between text-[15px] text-[var(--muted-foreground)]">
<span className="truncate">
{primary ?? <span className="italic">Unassigned</span>}
</span>

View file

@ -280,13 +280,13 @@ export function BulkImportDialog({
<tbody>
{preview.rows.map((row, i) => (
<tr key={i} className="border-t hover:bg-[var(--muted)]/40">
<td className="whitespace-nowrap px-2 py-1 font-mono text-[10px] text-[var(--muted-foreground)]">
<td className="whitespace-nowrap px-2 py-1 font-mono text-[15px] text-[var(--muted-foreground)]">
{row.sourceSheet === "Q1_2026" ? "Q1" : "Q2"}
</td>
<td className="max-w-[220px] px-2 py-1">
<p className="truncate font-medium leading-tight">{row.name}</p>
{row.deliverableName !== row.name && (
<p className="truncate text-[10px] text-[var(--muted-foreground)]">
<p className="truncate text-[15px] text-[var(--muted-foreground)]">
{row.deliverableName}
</p>
)}
@ -310,7 +310,7 @@ export function BulkImportDialog({
</td>
<td className="px-2 py-1">
<span
className={`inline-block rounded-full px-2 py-0.5 text-[10px] font-medium ${STATUS_COLORS[row.deliverableStatus] ?? ""}`}
className={`inline-block rounded-full px-2 py-0.5 text-[15px] font-medium ${STATUS_COLORS[row.deliverableStatus] ?? ""}`}
>
{STATUS_LABELS[row.deliverableStatus] ?? row.deliverableStatus}
</span>

View file

@ -45,7 +45,7 @@ export function Breadcrumbs() {
<ChevronRight className="h-3 w-3 text-[var(--border)]" aria-hidden="true" />
{crumb.isLast ? (
<span
className="text-[11px] font-semibold tracking-[0.04em] uppercase text-[var(--foreground)]"
className="text-[17px] font-semibold tracking-[0.04em] uppercase text-[var(--foreground)]"
aria-current="page"
>
{crumb.label}
@ -53,7 +53,7 @@ export function Breadcrumbs() {
) : (
<Link
href={crumb.href}
className="text-[11px] font-semibold tracking-[0.04em] uppercase text-[var(--muted-foreground)] transition-colors hover:text-[var(--foreground)]"
className="text-[17px] font-semibold tracking-[0.04em] uppercase text-[var(--muted-foreground)] transition-colors hover:text-[var(--foreground)]"
>
{crumb.label}
</Link>

View file

@ -68,7 +68,7 @@ function NavLinks({
href={item.href}
onClick={onNavigate}
className={cn(
"flex items-center gap-3 rounded-lg px-3 py-2 text-[11px] font-semibold tracking-[0.08em] uppercase transition-all duration-150",
"flex items-center gap-3 rounded-lg px-3 py-2 text-[17px] font-semibold tracking-[0.08em] uppercase transition-all duration-150",
isActive
? "bg-[var(--primary)] text-[var(--primary-foreground)] shadow-[var(--shadow-sm)]"
: "text-[var(--muted-foreground)] hover:bg-[var(--background)] hover:text-[var(--foreground)]",
@ -105,7 +105,7 @@ function NavLinks({
href={item.href}
onClick={onNavigate}
className={cn(
"flex items-center gap-3 rounded-lg px-3 py-2 text-[11px] font-semibold tracking-[0.08em] uppercase transition-all duration-150",
"flex items-center gap-3 rounded-lg px-3 py-2 text-[17px] font-semibold tracking-[0.08em] uppercase transition-all duration-150",
isActive
? "bg-[var(--primary)] text-[var(--primary-foreground)] shadow-[var(--shadow-sm)]"
: "text-[var(--muted-foreground)] hover:bg-[var(--background)] hover:text-[var(--foreground)]",
@ -137,7 +137,7 @@ function NavLinks({
<form action={signOutAction}>
<button
type="submit"
className="flex w-full items-center justify-center rounded-lg px-2 py-2 text-[11px] font-semibold tracking-[0.08em] uppercase transition-all duration-150 text-[var(--muted-foreground)] hover:bg-[var(--background)] hover:text-destructive"
className="flex w-full items-center justify-center rounded-lg px-2 py-2 text-[17px] font-semibold tracking-[0.08em] uppercase transition-all duration-150 text-[var(--muted-foreground)] hover:bg-[var(--background)] hover:text-destructive"
aria-label="Sign out"
>
<LogOut className="h-4 w-4 shrink-0" />
@ -150,7 +150,7 @@ function NavLinks({
<form action={signOutAction}>
<button
type="submit"
className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-[11px] font-semibold tracking-[0.08em] uppercase transition-all duration-150 text-[var(--muted-foreground)] hover:bg-[var(--background)] hover:text-destructive"
className="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-[17px] font-semibold tracking-[0.08em] uppercase transition-all duration-150 text-[var(--muted-foreground)] hover:bg-[var(--background)] hover:text-destructive"
>
<LogOut className="h-4 w-4 shrink-0" />
<span>Sign out</span>

View file

@ -86,7 +86,7 @@ export function Topbar() {
{unreadCount > 0 && (
<Badge
variant="destructive"
className="absolute -right-1 -top-1 h-4 min-w-4 rounded-full p-0 text-[10px] leading-4"
className="absolute -right-1 -top-1 h-4 min-w-4 rounded-full p-0 text-[15px] leading-4"
aria-hidden="true"
>
{unreadCount > 99 ? "99+" : unreadCount}
@ -99,14 +99,14 @@ export function Topbar() {
</PopoverTrigger>
<PopoverContent align="end" className="w-80 p-0 rounded-xl shadow-[var(--shadow-lg)]">
<div className="flex items-center justify-between border-b px-3 py-2.5">
<span className="text-[10px] font-semibold tracking-[0.1em] uppercase text-[var(--muted-foreground)]">
<span className="text-[15px] font-semibold tracking-[0.1em] uppercase text-[var(--muted-foreground)]">
Notifications
</span>
{unreadCount > 0 && (
<Button
size="sm"
variant="ghost"
className="h-6 text-[10px]"
className="h-6 text-[15px]"
onClick={() => markAllRead.mutate()}
disabled={markAllRead.isPending}
>
@ -144,10 +144,10 @@ export function Topbar() {
) : (
<p className="text-xs font-medium">{notif.title}</p>
)}
<p className="mt-0.5 truncate text-[10px] text-[var(--muted-foreground)]">
<p className="mt-0.5 truncate text-[15px] text-[var(--muted-foreground)]">
{notif.message}
</p>
<p className="mt-0.5 text-[10px] text-[var(--muted-foreground)]">
<p className="mt-0.5 text-[15px] text-[var(--muted-foreground)]">
{formatDistanceToNow(new Date(notif.createdAt), {
addSuffix: true,
})}

View file

@ -88,7 +88,7 @@ export function PipelineStageList({
{stage.isCriticalGate && (
<Badge
variant="outline"
className="h-4 gap-0.5 border-amber-500/60 text-amber-600 dark:text-amber-400 text-[9px] px-1.5 shrink-0"
className="h-4 gap-0.5 border-amber-500/60 text-amber-600 dark:text-amber-400 text-[14px] px-1.5 shrink-0"
>
<Shield className="size-2.5" />
GATE
@ -98,7 +98,7 @@ export function PipelineStageList({
{stage.isOptional && (
<Badge
variant="secondary"
className="h-4 text-[9px] px-1.5 shrink-0"
className="h-4 text-[14px] px-1.5 shrink-0"
>
Optional
</Badge>
@ -107,7 +107,7 @@ export function PipelineStageList({
{/* Estimated days */}
{stage.estimatedDays != null && (
<span className="flex items-center gap-0.5 text-[10px] text-[var(--muted-foreground)] shrink-0">
<span className="flex items-center gap-0.5 text-[15px] text-[var(--muted-foreground)] shrink-0">
<Clock className="size-2.5" />
{stage.estimatedDays}d
</span>

View file

@ -26,7 +26,7 @@ export function PipelineValidationBanner({
>
<AlertCircle className="size-4 shrink-0 mt-0.5" />
<div className="flex flex-col gap-1 min-w-0">
<span className="label-upper text-[10px] font-semibold">
<span className="label-upper text-[15px] font-semibold">
Errors
</span>
<ul className="list-disc list-inside text-sm space-y-0.5">
@ -48,7 +48,7 @@ export function PipelineValidationBanner({
>
<AlertTriangle className="size-4 shrink-0 mt-0.5" />
<div className="flex flex-col gap-1 min-w-0">
<span className="label-upper text-[10px] font-semibold">
<span className="label-upper text-[15px] font-semibold">
Warnings
</span>
<ul className="list-disc list-inside text-sm space-y-0.5">

View file

@ -128,7 +128,7 @@ export function StageEditSheet({
<div className="flex flex-col gap-5 px-4">
{/* Name */}
<div className="flex flex-col gap-1.5">
<Label htmlFor="stage-name" className="label-upper text-[10px]">
<Label htmlFor="stage-name" className="label-upper text-[15px]">
Name
</Label>
<Input
@ -141,7 +141,7 @@ export function StageEditSheet({
{/* Slug */}
<div className="flex flex-col gap-1.5">
<Label htmlFor="stage-slug" className="label-upper text-[10px]">
<Label htmlFor="stage-slug" className="label-upper text-[15px]">
Slug
</Label>
<Input
@ -157,7 +157,7 @@ export function StageEditSheet({
<div className="flex flex-col gap-1.5">
<Label
htmlFor="stage-description"
className="label-upper text-[10px]"
className="label-upper text-[15px]"
>
Description
</Label>
@ -172,7 +172,7 @@ export function StageEditSheet({
{/* Estimated Days */}
<div className="flex flex-col gap-1.5">
<Label htmlFor="stage-days" className="label-upper text-[10px]">
<Label htmlFor="stage-days" className="label-upper text-[15px]">
Estimated Days
</Label>
<Input
@ -188,7 +188,7 @@ export function StageEditSheet({
{/* Color */}
<div className="flex flex-col gap-1.5">
<Label htmlFor="stage-color" className="label-upper text-[10px]">
<Label htmlFor="stage-color" className="label-upper text-[15px]">
Color
</Label>
<div className="flex items-center gap-2">
@ -220,7 +220,7 @@ export function StageEditSheet({
>
Critical Gate
</Label>
<span className="text-[11px] text-[var(--muted-foreground)]">
<span className="text-[17px] text-[var(--muted-foreground)]">
Requires approval before proceeding
</span>
</div>
@ -239,7 +239,7 @@ export function StageEditSheet({
>
Optional
</Label>
<span className="text-[11px] text-[var(--muted-foreground)]">
<span className="text-[17px] text-[var(--muted-foreground)]">
Can be skipped in the pipeline
</span>
</div>

View file

@ -54,7 +54,7 @@ export function StageNode({ data, selected }: NodeProps) {
{isOptional && (
<Badge
variant="secondary"
className="h-3.5 text-[8px] px-1 w-fit"
className="h-3.5 text-[12px] px-1 w-fit"
>
Optional
</Badge>

View file

@ -143,11 +143,11 @@ export function ProjectBoard({ projects, groupBy, pipelineStages }: ProjectBoard
className="h-2 w-2 rounded-full"
style={{ background: col.accent }}
/>
<span className="text-[11px] font-bold uppercase tracking-wider">
<span className="text-[17px] font-bold uppercase tracking-wider">
{col.label}
</span>
</div>
<span className="rounded-full bg-[var(--card)] px-2 py-0.5 text-[10px] font-semibold tabular-nums text-[var(--muted-foreground)]">
<span className="rounded-full bg-[var(--card)] px-2 py-0.5 text-[15px] font-semibold tabular-nums text-[var(--muted-foreground)]">
{col.projects.length}
</span>
</div>
@ -165,7 +165,7 @@ export function ProjectBoard({ projects, groupBy, pipelineStages }: ProjectBoard
)}
>
{col.projects.length === 0 && !snapshot.isDraggingOver && (
<div className="py-6 text-center text-[10px] text-[var(--muted-foreground)]/60">
<div className="py-6 text-center text-[15px] text-[var(--muted-foreground)]/60">
</div>
)}
@ -190,7 +190,7 @@ export function ProjectBoard({ projects, groupBy, pipelineStages }: ProjectBoard
) : (
<div className="flex flex-1 flex-col gap-2 p-2">
{col.projects.length === 0 ? (
<div className="py-6 text-center text-[10px] text-[var(--muted-foreground)]/60">
<div className="py-6 text-center text-[15px] text-[var(--muted-foreground)]/60">
</div>
) : (
@ -308,7 +308,7 @@ function ProjectCard({ project: p }: { project: BoardProject }) {
className="block rounded-md border bg-[var(--card)] p-2.5 text-left shadow-[var(--shadow-xs)] transition-all hover:border-[var(--primary)] hover:shadow-[var(--shadow-sm)]"
>
{/* Top row: OMG # + priority dot + team */}
<div className="mb-1.5 flex items-center gap-1.5 text-[10px]">
<div className="mb-1.5 flex items-center gap-1.5 text-[15px]">
{p.omgJobNumber && (
<span className="font-mono tabular-nums text-[var(--muted-foreground)]">
#{p.omgJobNumber}
@ -321,7 +321,7 @@ function ProjectCard({ project: p }: { project: BoardProject }) {
{p.clientTeam && (
<Badge
variant="outline"
className="ml-auto h-4 px-1 text-[9px] uppercase tracking-wider"
className="ml-auto h-4 px-1 text-[14px] uppercase tracking-wider"
>
{p.clientTeam.name}
</Badge>
@ -332,7 +332,7 @@ function ProjectCard({ project: p }: { project: BoardProject }) {
<div className="mb-2 line-clamp-2 text-xs font-semibold leading-snug">{p.name}</div>
{/* Meta — deliverables + deadline */}
<div className="flex items-center justify-between text-[10px] text-[var(--muted-foreground)]">
<div className="flex items-center justify-between text-[15px] text-[var(--muted-foreground)]">
<span>
{p._count?.deliverables ?? 0}{" "}
deliverable{(p._count?.deliverables ?? 0) === 1 ? "" : "s"}
@ -357,7 +357,7 @@ function ProjectCard({ project: p }: { project: BoardProject }) {
{/* Current stage label (only meaningful in status-grouped view where
the column doesn't already tell you the stage) */}
{progress?.dominantStage && (
<div className="mt-1.5 text-[10px] text-[var(--muted-foreground)]">
<div className="mt-1.5 text-[15px] text-[var(--muted-foreground)]">
at {progress.dominantStage.name} ({progress.dominantStage.count}/
{progress.totalDeliverables})
</div>

View file

@ -134,7 +134,7 @@ export function ProjectFormDialog({
placeholder="e.g. 2337959"
{...register("omgJobNumber")}
/>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Canonical key matches the XLSX ingest + OMG webhook.
</p>
</div>
@ -205,7 +205,7 @@ export function ProjectFormDialog({
)}
</SelectContent>
</Select>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Drives who sees this project. Required for scoped users.
</p>
</div>
@ -300,7 +300,7 @@ export function ProjectFormDialog({
</SelectContent>
</Select>
{hasDeliverables && (
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Pipeline cannot be changed after deliverables exist.
</p>
)}
@ -318,14 +318,14 @@ export function ProjectFormDialog({
<div className="space-y-2">
<Label htmlFor="startDate">Brief Accepted Date</Label>
<Input id="startDate" type="date" {...register("startDate")} />
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Dow XLSX: &ldquo;Brief Acceptance Date&rdquo;.
</p>
</div>
<div className="space-y-2">
<Label htmlFor="dueDate">External Deadline</Label>
<Input id="dueDate" type="date" {...register("dueDate")} />
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Dow XLSX: &ldquo;External Deadline&rdquo; the client-facing one.
</p>
</div>
@ -345,7 +345,7 @@ export function ProjectFormDialog({
placeholder="e.g. Celena, Yzabella, Alexia, Majo"
{...register("requestor")}
/>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Dow XLSX: &ldquo;Owner&rdquo; the producer running this project.
</p>
</div>

View file

@ -17,7 +17,7 @@ export function AtRiskSection({ projects }: AtRiskSectionProps) {
At-Risk Projects
</h2>
{projects.length > 0 && (
<span className="ml-auto rounded-full bg-[var(--accent)]/10 px-2 py-0.5 text-[10px] font-bold text-[var(--accent)]">
<span className="ml-auto rounded-full bg-[var(--accent)]/10 px-2 py-0.5 text-[15px] font-bold text-[var(--accent)]">
{projects.length}
</span>
)}
@ -109,7 +109,7 @@ export function AtRiskSection({ projects }: AtRiskSectionProps) {
);
})}
{projects.length > 6 && (
<p className="py-2 text-center text-[10px] font-medium text-[var(--muted-foreground)]">
<p className="py-2 text-center text-[15px] font-medium text-[var(--muted-foreground)]">
+ {projects.length - 6} more at-risk project{projects.length - 6 !== 1 ? "s" : ""}
</p>
)}

View file

@ -109,7 +109,7 @@ export function DeadlinesSection({ deadlines }: DeadlinesSectionProps) {
>
<div className="min-w-0 flex-1">
<p className="text-sm font-medium truncate">{item.name}</p>
<p className="text-[10px] text-[var(--muted-foreground)] truncate">
<p className="text-[15px] text-[var(--muted-foreground)] truncate">
{item.projectName}
</p>
</div>
@ -118,7 +118,7 @@ export function DeadlinesSection({ deadlines }: DeadlinesSectionProps) {
<p className="text-xs font-semibold text-[var(--accent)]">
+{item.daysOverdue}d
</p>
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Due {format(new Date(item.dueDate), "MMM d")}
</p>
</div>
@ -126,7 +126,7 @@ export function DeadlinesSection({ deadlines }: DeadlinesSectionProps) {
))}
{missed.length > 8 && (
<div className="px-4 py-2 text-center">
<p className="text-[10px] font-medium text-[var(--muted-foreground)]">
<p className="text-[15px] font-medium text-[var(--muted-foreground)]">
+ {missed.length - 8} more overdue deliverable{missed.length - 8 !== 1 ? "s" : ""}
</p>
</div>

View file

@ -38,7 +38,7 @@ export function KpiStrip({ data }: KpiStripProps) {
color: "text-[var(--status-approved)]",
bg: "bg-[var(--status-approved)]",
detail: (
<span className={`flex items-center gap-1 text-[10px] font-medium ${trendColor}`}>
<span className={`flex items-center gap-1 text-[15px] font-medium ${trendColor}`}>
<TrendIcon className="h-3 w-3" />
{trend.trend === "flat"
? "Same as last week"
@ -61,7 +61,7 @@ export function KpiStrip({ data }: KpiStripProps) {
? "bg-[var(--status-in-review)]"
: "bg-[var(--accent)]",
detail: (
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
{data.deadlines.met.length} met, {data.deadlines.missed.length} missed
</span>
),
@ -73,7 +73,7 @@ export function KpiStrip({ data }: KpiStripProps) {
color: "text-[var(--status-in-progress)]",
bg: "bg-[var(--status-in-progress)]",
detail: (
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
Stages across active projects
</span>
),
@ -89,7 +89,7 @@ export function KpiStrip({ data }: KpiStripProps) {
? "bg-[var(--accent)]"
: "bg-[var(--muted-foreground)]",
detail: (
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
{data.atRiskProjects.length > 0
? "Require attention"
: "All projects on track"}

View file

@ -96,7 +96,7 @@ export function ReportHeader({
</div>
{/* Generated timestamp */}
<p className="mt-4 text-[10px] text-[var(--muted-foreground)] print:mt-2">
<p className="mt-4 text-[15px] text-[var(--muted-foreground)] print:mt-2">
Generated {generatedAt}
</p>
</header>

View file

@ -111,7 +111,7 @@ export function AnnotationTools({
<TooltipContent side="bottom" className="text-xs">
{tool.label}
{tool.shortcut && (
<kbd className="ml-1.5 rounded bg-black/20 px-1 py-0.5 font-mono text-[10px]">
<kbd className="ml-1.5 rounded bg-black/20 px-1 py-0.5 font-mono text-[15px]">
{tool.shortcut}
</kbd>
)}
@ -137,7 +137,7 @@ export function AnnotationTools({
side="bottom"
align="start"
>
<p className="mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<p className="mb-1.5 text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Stroke Color
</p>
<div className="grid grid-cols-4 gap-1">
@ -175,7 +175,7 @@ export function AnnotationTools({
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">
Undo <kbd className="ml-1 rounded bg-black/20 px-1 py-0.5 font-mono text-[10px]">Cmd+Z</kbd>
Undo <kbd className="ml-1 rounded bg-black/20 px-1 py-0.5 font-mono text-[15px]">Cmd+Z</kbd>
</TooltipContent>
</Tooltip>
@ -192,7 +192,7 @@ export function AnnotationTools({
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">
Redo <kbd className="ml-1 rounded bg-black/20 px-1 py-0.5 font-mono text-[10px]">Cmd+Shift+Z</kbd>
Redo <kbd className="ml-1 rounded bg-black/20 px-1 py-0.5 font-mono text-[15px]">Cmd+Shift+Z</kbd>
</TooltipContent>
</Tooltip>
@ -234,7 +234,7 @@ export function AnnotationTools({
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">
Delete selected
<kbd className="ml-1 rounded bg-black/20 px-1 py-0.5 font-mono text-[10px]">Del</kbd>
<kbd className="ml-1 rounded bg-black/20 px-1 py-0.5 font-mono text-[15px]">Del</kbd>
</TooltipContent>
</Tooltip>
)}

View file

@ -91,7 +91,7 @@ export function ComparisonToolbar({
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">
{label} <kbd className="ml-1 rounded bg-[var(--border)] px-1 font-mono text-[10px]">{shortcut}</kbd>
{label} <kbd className="ml-1 rounded bg-[var(--border)] px-1 font-mono text-[15px]">{shortcut}</kbd>
</TooltipContent>
</Tooltip>
))}
@ -140,7 +140,7 @@ export function ComparisonToolbar({
{/* Revision selectors */}
<div className="flex items-center gap-2">
<div className="flex items-center gap-1">
<span className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
A
</span>
<Select value={leftRevisionKey} onValueChange={onLeftChange}>
@ -162,7 +162,7 @@ export function ComparisonToolbar({
</div>
<div className="flex items-center gap-1">
<span className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
B
</span>
<Select value={rightRevisionKey} onValueChange={onRightChange}>
@ -199,7 +199,7 @@ export function ComparisonToolbar({
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="text-xs">
Exit comparison mode <kbd className="ml-1 rounded bg-[var(--border)] px-1 font-mono text-[10px]">Esc</kbd>
Exit comparison mode <kbd className="ml-1 rounded bg-[var(--border)] px-1 font-mono text-[15px]">Esc</kbd>
</TooltipContent>
</Tooltip>
</div>

View file

@ -284,7 +284,7 @@ export function ComparisonViewer({
<div className="flex flex-1">
{/* Left pane */}
<div className="relative flex-1 overflow-hidden border-r border-[var(--border)]">
<div className="absolute left-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
<div className="absolute left-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[15px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
A
</div>
<div
@ -306,7 +306,7 @@ export function ComparisonViewer({
{/* Right pane */}
<div className="relative flex-1 overflow-hidden">
<div className="absolute right-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
<div className="absolute right-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[15px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
B
</div>
<div
@ -407,10 +407,10 @@ export function ComparisonViewer({
/>
{/* Labels */}
<div className="absolute left-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
<div className="absolute left-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[15px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
A
</div>
<div className="absolute right-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
<div className="absolute right-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[15px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
B ({overlayOpacity}%)
</div>
@ -435,7 +435,7 @@ export function ComparisonViewer({
onFitToView={fitSharedView}
onZoomToPreset={() => {}}
/>
<span className="font-mono text-[10px] text-[var(--muted-foreground)]">
<span className="font-mono text-[15px] text-[var(--muted-foreground)]">
Press <kbd className="rounded bg-[var(--border)] px-1.5 py-0.5">Space</kbd> to toggle
</span>
</div>
@ -469,7 +469,7 @@ export function ComparisonViewer({
/>
{/* Active label */}
<div className="absolute left-1/2 top-3 z-10 -translate-x-1/2 rounded bg-black/60 px-3 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm transition-all">
<div className="absolute left-1/2 top-3 z-10 -translate-x-1/2 rounded bg-black/60 px-3 py-0.5 text-[15px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm transition-all">
{toggleShowRight ? "B" : "A"}
</div>
</div>

View file

@ -26,7 +26,7 @@ export function ImageGallery({
return (
<div className="flex items-center gap-1 overflow-x-auto rounded-lg border bg-[var(--card)] p-1.5">
<span className="shrink-0 px-1 text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="shrink-0 px-1 text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Gallery
</span>
<div className="mx-1 h-8 w-px shrink-0 bg-[var(--border)]" />
@ -48,7 +48,7 @@ export function ImageGallery({
className="h-10 w-10 object-cover"
/>
<div className="absolute bottom-0 left-0 right-0 bg-black/60 px-0.5 text-center">
<span className="text-[8px] font-medium text-white">
<span className="text-[12px] font-medium text-white">
R{img.roundNumber}
{img.type === "reference" ? " ref" : ""}
</span>

View file

@ -116,7 +116,7 @@ export function ImageUploadZone({
<Button
size="sm"
variant="ghost"
className="h-6 px-1.5 text-[10px] text-white hover:bg-white/20 hover:text-white"
className="h-6 px-1.5 text-[15px] text-white hover:bg-white/20 hover:text-white"
onClick={() => fileInputRef.current?.click()}
>
Replace
@ -124,7 +124,7 @@ export function ImageUploadZone({
<Button
size="sm"
variant="ghost"
className="h-6 px-1.5 text-[10px] text-white hover:bg-red-500/50 hover:text-white"
className="h-6 px-1.5 text-[15px] text-white hover:bg-red-500/50 hover:text-white"
onClick={handleDelete}
>
<X className="h-3 w-3" />
@ -177,10 +177,10 @@ export function ImageUploadZone({
<p className="text-xs font-medium">
{imageType === "reference" ? "Reference Image" : "Current Render"}
</p>
<p className="mt-0.5 text-[10px] text-[var(--muted-foreground)]">
<p className="mt-0.5 text-[15px] text-[var(--muted-foreground)]">
Drop file or click to browse
</p>
<p className="mt-0.5 text-[10px] text-[var(--muted-foreground)]">
<p className="mt-0.5 text-[15px] text-[var(--muted-foreground)]">
PNG, JPEG, WebP, TIFF up to 50MB
</p>
</>

View file

@ -69,7 +69,7 @@ export function ImageViewer({
onZoomToPreset={viewer.zoomToPreset}
/>
{dims && (
<span className="font-mono text-[10px] text-[var(--muted-foreground)]">
<span className="font-mono text-[15px] text-[var(--muted-foreground)]">
{dims.width} × {dims.height}
</span>
)}
@ -80,7 +80,7 @@ export function ImageViewer({
{/* Pixel info */}
{viewer.pixelInfo && (
<div className="flex items-center gap-2 font-mono text-[10px] text-[var(--muted-foreground)]">
<div className="flex items-center gap-2 font-mono text-[15px] text-[var(--muted-foreground)]">
<span>
{viewer.pixelInfo.x}, {viewer.pixelInfo.y}
</span>

View file

@ -20,7 +20,7 @@ export function OverlayControls({
return (
<div className="absolute bottom-4 left-1/2 z-20 flex -translate-x-1/2 items-center gap-3 rounded-lg border bg-[var(--card)]/90 px-4 py-2 shadow-lg backdrop-blur-sm">
<span className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Opacity
</span>
<input
@ -34,7 +34,7 @@ export function OverlayControls({
[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full
[&::-webkit-slider-thumb]:bg-[var(--primary)]"
/>
<span className="min-w-[32px] text-right font-mono text-[10px] text-[var(--muted-foreground)]">
<span className="min-w-[32px] text-right font-mono text-[15px] text-[var(--muted-foreground)]">
{opacity}%
</span>
</div>

View file

@ -143,7 +143,7 @@ export const RevisionNode = forwardRef<HTMLDivElement, RevisionNodeProps>(
<Badge
variant="secondary"
className={cn(
"h-4 px-1 text-[9px] font-medium uppercase",
"h-4 px-1 text-[14px] font-medium uppercase",
statusStyle.className
)}
>
@ -152,7 +152,7 @@ export const RevisionNode = forwardRef<HTMLDivElement, RevisionNodeProps>(
{revision.isLatest && (
<Badge
variant="secondary"
className="h-4 bg-[var(--primary)]/15 px-1 text-[9px] font-medium uppercase text-[var(--primary)]"
className="h-4 bg-[var(--primary)]/15 px-1 text-[14px] font-medium uppercase text-[var(--primary)]"
>
Latest
</Badge>
@ -160,7 +160,7 @@ export const RevisionNode = forwardRef<HTMLDivElement, RevisionNodeProps>(
{isActive && (
<Badge
variant="secondary"
className="h-4 bg-[var(--foreground)]/10 px-1 text-[9px] font-medium uppercase text-[var(--foreground)]"
className="h-4 bg-[var(--foreground)]/10 px-1 text-[14px] font-medium uppercase text-[var(--foreground)]"
>
Current
</Badge>
@ -177,7 +177,7 @@ export const RevisionNode = forwardRef<HTMLDivElement, RevisionNodeProps>(
/>
) : (
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded border border-dashed border-[var(--border)] bg-[var(--card)]">
<span className="text-[8px] text-[var(--muted-foreground)]">
<span className="text-[12px] text-[var(--muted-foreground)]">
No img
</span>
</div>
@ -185,13 +185,13 @@ export const RevisionNode = forwardRef<HTMLDivElement, RevisionNodeProps>(
<div className="min-w-0 flex-1 space-y-0.5">
{/* Timestamp */}
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
{timeAgo}
</p>
{/* Feedback preview */}
{revision.feedbackPreview && (
<p className="truncate text-[10px] text-[var(--foreground)]/70">
<p className="truncate text-[15px] text-[var(--foreground)]/70">
{revision.feedbackPreview}
</p>
)}
@ -205,7 +205,7 @@ export const RevisionNode = forwardRef<HTMLDivElement, RevisionNodeProps>(
<TooltipTrigger asChild>
<button
onClick={handleAnnotationClick}
className="inline-flex items-center gap-0.5 text-[10px] text-[var(--muted-foreground)] hover:text-[var(--foreground)] transition-colors"
className="inline-flex items-center gap-0.5 text-[15px] text-[var(--muted-foreground)] hover:text-[var(--foreground)] transition-colors"
>
<PenLine className="h-3 w-3" />
{revision.annotationCount}
@ -219,7 +219,7 @@ export const RevisionNode = forwardRef<HTMLDivElement, RevisionNodeProps>(
{/* Comment count (stage-level) */}
<Tooltip>
<TooltipTrigger asChild>
<span className="inline-flex items-center gap-0.5 text-[10px] text-[var(--muted-foreground)]">
<span className="inline-flex items-center gap-0.5 text-[15px] text-[var(--muted-foreground)]">
<MessageSquare className="h-3 w-3" />
{revision.stageCommentCount}
</span>
@ -231,13 +231,13 @@ export const RevisionNode = forwardRef<HTMLDivElement, RevisionNodeProps>(
{/* Decision record for approved/rejected */}
{revision.status === "APPROVED" && (
<span className="inline-flex items-center gap-0.5 text-[10px] text-[var(--status-approved)]">
<span className="inline-flex items-center gap-0.5 text-[15px] text-[var(--status-approved)]">
<CheckCircle2 className="h-3 w-3" />
Approved
</span>
)}
{revision.status === "CHANGES_REQUESTED" && (
<span className="inline-flex items-center gap-0.5 text-[10px] text-[var(--status-blocked)]">
<span className="inline-flex items-center gap-0.5 text-[15px] text-[var(--status-blocked)]">
<XCircle className="h-3 w-3" />
Changes
</span>

View file

@ -215,7 +215,7 @@ export function RevisionTimeline({
{/* ── Filter bar (embedded gets a compact filter row) ─────── */}
{!embedded ? null : enrichedRevisions.length > 0 ? (
<div className="flex items-center justify-between border-b px-3 py-1.5">
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
{enrichedRevisions.length} round{enrichedRevisions.length !== 1 ? "s" : ""}
</span>
<div className="flex items-center gap-1">
@ -242,7 +242,7 @@ export function RevisionTimeline({
<Button
size="sm"
variant="ghost"
className="h-6 text-[10px]"
className="h-6 text-[15px]"
onClick={onCreateRevision}
disabled={isCreatingRevision}
>
@ -300,7 +300,7 @@ export function RevisionTimeline({
New Round
</Button>
) : (
<p className="text-[10px] text-[var(--muted-foreground)]/60">
<p className="text-[15px] text-[var(--muted-foreground)]/60">
Submit a revision to start tracking history
</p>
)}
@ -316,7 +316,7 @@ export function RevisionTimeline({
<Button
size="sm"
variant="ghost"
className="h-6 text-[10px]"
className="h-6 text-[15px]"
onClick={() => setFilterMode("all")}
>
Show all rounds
@ -364,11 +364,11 @@ export function RevisionTimeline({
<div className="flex items-center justify-between border-b px-3 py-2">
<div className="flex items-center gap-1.5">
<History className="h-3.5 w-3.5 text-[var(--muted-foreground)]" />
<span className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Revision History
</span>
{enrichedRevisions.length > 0 && (
<span className="ml-1 rounded-full bg-[var(--foreground)]/10 px-1.5 text-[9px] font-medium text-[var(--muted-foreground)]">
<span className="ml-1 rounded-full bg-[var(--foreground)]/10 px-1.5 text-[14px] font-medium text-[var(--muted-foreground)]">
{enrichedRevisions.length}
</span>
)}

View file

@ -235,14 +235,14 @@ export function VideoAnnotationLayer({
<div className="flex items-center gap-1 border-l border-[var(--border)] pl-2">
<Clock className="h-3 w-3 text-[var(--muted-foreground)]" />
<span className="font-mono text-[10px] tabular-nums text-[var(--muted-foreground)]">
<span className="font-mono text-[15px] tabular-nums text-[var(--muted-foreground)]">
{formatTimecode(currentTime, fps)}
</span>
</div>
<button
onClick={() => setShowAllAnnotations((v) => !v)}
className={`rounded px-1.5 py-0.5 text-[10px] font-medium transition-colors ${
className={`rounded px-1.5 py-0.5 text-[15px] font-medium transition-colors ${
showAllAnnotations
? "bg-[var(--primary)] text-[var(--primary-foreground)]"
: "text-[var(--muted-foreground)] hover:bg-[var(--muted)]"
@ -505,10 +505,10 @@ export function VideoAnnotationLayer({
className="h-2 w-2 rounded-full"
style={{ backgroundColor: ann.color }}
/>
<span className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<span className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Add Comment
</span>
<span className="ml-auto flex items-center gap-1 font-mono text-[9px] text-[var(--muted-foreground)]">
<span className="ml-auto flex items-center gap-1 font-mono text-[14px] text-[var(--muted-foreground)]">
<Clock className="h-2.5 w-2.5" />
{currentTime.toFixed(2)}s
</span>
@ -539,12 +539,12 @@ export function VideoAnnotationLayer({
autoFocus
/>
<div className="mt-2 flex items-center justify-between">
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
Enter to save
</span>
<Button
size="sm"
className="h-6 px-2 text-[10px]"
className="h-6 px-2 text-[15px]"
onClick={() => ann.commitPendingAnnotation(ann.commentValue)}
>
<Send className="mr-1 h-2.5 w-2.5" />

View file

@ -182,7 +182,7 @@ export function VideoControls({
<Button
size="sm"
variant="ghost"
className="h-7 px-1.5 text-[10px] font-mono tabular-nums"
className="h-7 px-1.5 text-[15px] font-mono tabular-nums"
onClick={() => {
const idx = SPEED_OPTIONS.indexOf(playbackSpeed);
const next = SPEED_OPTIONS[(idx + 1) % SPEED_OPTIONS.length];

View file

@ -35,7 +35,7 @@ export function VideoFrameDisplay({
className,
}: VideoFrameDisplayProps) {
return (
<span className={`font-mono text-[10px] tabular-nums ${className ?? ""}`}>
<span className={`font-mono text-[15px] tabular-nums ${className ?? ""}`}>
{toTimecode(currentTime, fps)}
<span className="text-[var(--muted-foreground)] opacity-50"> / </span>
{toTimecode(duration, fps)}

View file

@ -87,7 +87,7 @@ export function VideoTimeline({
{/* Hover time tooltip */}
{hoverTime !== null && (
<div
className="pointer-events-none absolute -top-7 z-10 -translate-x-1/2 rounded bg-[var(--popover)] px-1.5 py-0.5 text-[10px] font-mono text-[var(--popover-foreground)] shadow-md"
className="pointer-events-none absolute -top-7 z-10 -translate-x-1/2 rounded bg-[var(--popover)] px-1.5 py-0.5 text-[15px] font-mono text-[var(--popover-foreground)] shadow-md"
style={{ left: hoverX }}
>
{formatTime(hoverTime)}

View file

@ -152,22 +152,22 @@ export function VideoUploadZone({
{/* Status badge */}
<div className="absolute bottom-1 left-1 flex items-center gap-1">
{existingVideo.status === "processing" && (
<span className="flex items-center gap-1 rounded bg-yellow-500/80 px-1.5 py-0.5 text-[9px] font-medium text-white">
<span className="flex items-center gap-1 rounded bg-yellow-500/80 px-1.5 py-0.5 text-[14px] font-medium text-white">
<Loader2 className="h-2.5 w-2.5 animate-spin" />
Processing
</span>
)}
{existingVideo.status === "ready" && (
<span className="rounded bg-green-600/80 px-1.5 py-0.5 text-[9px] font-medium text-white">
<span className="rounded bg-green-600/80 px-1.5 py-0.5 text-[14px] font-medium text-white">
Ready
</span>
)}
{existingVideo.status === "failed" && (
<span className="rounded bg-red-600/80 px-1.5 py-0.5 text-[9px] font-medium text-white">
<span className="rounded bg-red-600/80 px-1.5 py-0.5 text-[14px] font-medium text-white">
Failed
</span>
)}
<span className="rounded bg-black/60 px-1.5 py-0.5 font-mono text-[9px] text-white">
<span className="rounded bg-black/60 px-1.5 py-0.5 font-mono text-[14px] text-white">
{formatDuration(existingVideo.duration)}
</span>
</div>
@ -177,7 +177,7 @@ export function VideoUploadZone({
<Button
size="sm"
variant="ghost"
className="h-6 px-1.5 text-[10px] text-white hover:bg-white/20 hover:text-white"
className="h-6 px-1.5 text-[15px] text-white hover:bg-white/20 hover:text-white"
onClick={() => fileInputRef.current?.click()}
>
Replace
@ -185,7 +185,7 @@ export function VideoUploadZone({
<Button
size="sm"
variant="ghost"
className="h-6 px-1.5 text-[10px] text-white hover:bg-red-500/50 hover:text-white"
className="h-6 px-1.5 text-[15px] text-white hover:bg-red-500/50 hover:text-white"
onClick={handleDelete}
>
<X className="h-3 w-3" />
@ -240,10 +240,10 @@ export function VideoUploadZone({
<p className="text-xs font-medium">
{videoType === "video" ? "Video" : "Reference Video"}
</p>
<p className="mt-0.5 text-[10px] text-[var(--muted-foreground)]">
<p className="mt-0.5 text-[15px] text-[var(--muted-foreground)]">
Drop file or click to browse
</p>
<p className="mt-0.5 text-[10px] text-[var(--muted-foreground)]">
<p className="mt-0.5 text-[15px] text-[var(--muted-foreground)]">
MP4 up to 500MB
</p>
</>

View file

@ -179,10 +179,10 @@ export function WipeDivider({
</div>
{/* Labels */}
<div className="absolute left-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
<div className="absolute left-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[15px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
A
</div>
<div className="absolute right-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
<div className="absolute right-3 top-3 z-10 rounded bg-black/60 px-2 py-0.5 text-[15px] font-semibold uppercase tracking-wider text-white/90 backdrop-blur-sm">
B
</div>
</div>

View file

@ -169,7 +169,7 @@ export function RevisionList({ stageId }: { stageId: string }) {
</span>
<Badge
variant="secondary"
className={cn("text-[10px]", config.className)}
className={cn("text-[15px]", config.className)}
>
<Icon className="mr-0.5 h-3 w-3" />
{config.label}
@ -190,7 +190,7 @@ export function RevisionList({ stageId }: { stageId: string }) {
{rev.feedbackNotes && (
<div className="rounded bg-[var(--muted)] p-2">
<p className="text-[10px] font-semibold uppercase text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold uppercase text-[var(--muted-foreground)]">
Feedback
</p>
<p className="mt-0.5 text-xs">{rev.feedbackNotes}</p>
@ -214,7 +214,7 @@ export function RevisionList({ stageId }: { stageId: string }) {
<div className="flex gap-1.5">
<Button
size="sm"
className="h-6 text-[10px]"
className="h-6 text-[15px]"
disabled={updateRevision.isPending}
onClick={() => handleStatusUpdate(rev.id, "APPROVED")}
>
@ -224,7 +224,7 @@ export function RevisionList({ stageId }: { stageId: string }) {
<Button
size="sm"
variant="outline"
className="h-6 text-[10px]"
className="h-6 text-[15px]"
disabled={updateRevision.isPending}
onClick={() =>
handleStatusUpdate(rev.id, "CHANGES_REQUESTED")
@ -237,7 +237,7 @@ export function RevisionList({ stageId }: { stageId: string }) {
<Button
size="sm"
variant="ghost"
className="h-6 text-[10px]"
className="h-6 text-[15px]"
disabled={updateRevision.isPending}
onClick={() => handleStatusUpdate(rev.id, "IN_REVIEW")}
>

View file

@ -142,12 +142,12 @@ function ResultCard({
<p className="text-sm font-medium truncate">{result.name}</p>
<div className="flex items-center gap-1.5 mt-0.5">
{result.projectCode && (
<span className="font-mono text-[10px] text-[var(--muted-foreground)]">
<span className="font-mono text-[15px] text-[var(--muted-foreground)]">
{result.projectCode}
</span>
)}
{result.projectName && !isProject && (
<span className="text-[10px] text-[var(--muted-foreground)] truncate">
<span className="text-[15px] text-[var(--muted-foreground)] truncate">
in {result.projectName}
</span>
)}
@ -157,7 +157,7 @@ function ResultCard({
<div className="flex items-center gap-1.5 shrink-0">
<Badge
className={cn(
"text-[9px] px-1.5 py-0 h-4 font-semibold",
"text-[14px] px-1.5 py-0 h-4 font-semibold",
statusColor(result.status)
)}
>
@ -168,21 +168,21 @@ function ResultCard({
</div>
{result.description && (
<p className="mt-1.5 text-[11px] text-[var(--muted-foreground)] line-clamp-2">
<p className="mt-1.5 text-[17px] text-[var(--muted-foreground)] line-clamp-2">
{result.description}
</p>
)}
<div className="mt-2 flex items-center gap-2">
<span className="label-upper !text-[8px]">
<span className="label-upper !text-[12px]">
{isProject ? "Project" : "Deliverable"}
</span>
{relevancePct < 100 && (
<span className="text-[9px] text-[var(--muted-foreground)]">
<span className="text-[14px] text-[var(--muted-foreground)]">
{relevancePct}% match
</span>
)}
<Badge variant="outline" className="text-[8px] px-1 py-0 h-3.5">
<Badge variant="outline" className="text-[12px] px-1 py-0 h-3.5">
{result.priority}
</Badge>
</div>
@ -328,7 +328,7 @@ export function SmartSearchPanel({
{ollamaHealth?.available ? (
<Badge
variant="outline"
className="h-4 px-1.5 text-[8px] font-semibold border-emerald-500/30 text-emerald-600 dark:text-emerald-400"
className="h-4 px-1.5 text-[12px] font-semibold border-emerald-500/30 text-emerald-600 dark:text-emerald-400"
>
<Zap className="mr-0.5 h-2 w-2" />
AI Active
@ -336,7 +336,7 @@ export function SmartSearchPanel({
) : (
<Badge
variant="outline"
className="h-4 px-1.5 text-[8px] font-semibold border-amber-500/30 text-amber-600 dark:text-amber-400"
className="h-4 px-1.5 text-[12px] font-semibold border-amber-500/30 text-amber-600 dark:text-amber-400"
>
Text Only
</Badge>
@ -347,7 +347,7 @@ export function SmartSearchPanel({
<Button
variant="ghost"
size="sm"
className="h-7 text-[10px]"
className="h-7 text-[15px]"
onClick={handleClear}
>
Clear
@ -376,7 +376,7 @@ export function SmartSearchPanel({
<h3 className="text-sm font-semibold mb-1">
Ask anything about your projects
</h3>
<p className="text-[11px] text-[var(--muted-foreground)] max-w-xs mb-6">
<p className="text-[17px] text-[var(--muted-foreground)] max-w-xs mb-6">
Search using natural language. Ask about project status, find
deliverables, or explore your production data.
</p>
@ -415,7 +415,7 @@ export function SmartSearchPanel({
{entry.searchType && (
<div className="flex items-center gap-1.5">
{searchTypeIcon(entry.searchType)}
<span className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">
{searchTypeLabel(entry.searchType)}
</span>
</div>
@ -492,7 +492,7 @@ export function SmartSearchPanel({
)}
</Button>
</form>
<p className="mt-1.5 text-center text-[9px] text-[var(--muted-foreground)]">
<p className="mt-1.5 text-center text-[14px] text-[var(--muted-foreground)]">
{ollamaHealth?.available
? "Powered by local AI — your data never leaves the network"
: "AI unavailable — using text search fallback"}

View file

@ -159,13 +159,13 @@ export function StageDatePopover({
<PopoverContent align="start" className="w-64 space-y-3">
<div className="flex items-center justify-between">
<p className="text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<p className="text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Stage Dates
</p>
{manualSchedule && (
<Badge
variant="outline"
className="h-5 gap-0.5 border-[var(--accent)] text-[10px] text-[var(--accent)]"
className="h-5 gap-0.5 border-[var(--accent)] text-[15px] text-[var(--accent)]"
>
<Pin className="h-2.5 w-2.5" />
Pinned
@ -177,7 +177,7 @@ export function StageDatePopover({
<div>
<label
htmlFor={`start-${stageId}`}
className="mb-1 block text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
className="mb-1 block text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
>
Start
</label>
@ -192,7 +192,7 @@ export function StageDatePopover({
<div>
<label
htmlFor={`due-${stageId}`}
className="mb-1 block text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
className="mb-1 block text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
>
Due
</label>
@ -207,7 +207,7 @@ export function StageDatePopover({
</div>
{scheduleConflict && (
<div className="flex items-center gap-1.5 rounded bg-[var(--status-blocked)]/10 px-2 py-1.5 text-[10px] text-[var(--status-blocked)]">
<div className="flex items-center gap-1.5 rounded bg-[var(--status-blocked)]/10 px-2 py-1.5 text-[15px] text-[var(--status-blocked)]">
<AlertTriangle className="h-3 w-3 shrink-0" />
Schedule conflict not enough time for prerequisites
</div>
@ -244,7 +244,7 @@ export function StageDatePopover({
{scheduleDelta != null && scheduleDelta !== 0 && (
<span
className={cn(
"inline-flex items-center rounded-full px-1.5 py-0.5 text-[10px] font-semibold tabular-nums",
"inline-flex items-center rounded-full px-1.5 py-0.5 text-[15px] font-semibold tabular-nums",
scheduleDelta > 0
? "bg-[var(--status-in-review)]/15 text-[var(--status-in-review)]"
: "bg-[var(--status-blocked)]/15 text-[var(--status-blocked)]"

View file

@ -45,7 +45,7 @@ export function StageDetailSheet({
{(stage.stageDefinition?.isCriticalGate ?? stage.template.isCriticalGate) && (
<Badge
variant="outline"
className="h-5 gap-0.5 border-[var(--accent)] text-[10px] text-[var(--accent)]"
className="h-5 gap-0.5 border-[var(--accent)] text-[15px] text-[var(--accent)]"
>
<Shield className="h-3 w-3" />
GATE

View file

@ -5,7 +5,7 @@ import { Slot } from "radix-ui"
import { cn } from "@/lib/utils"
const badgeVariants = cva(
"inline-flex items-center justify-center rounded-full border border-transparent px-2.5 py-0.5 text-[10px] font-semibold tracking-[0.06em] uppercase w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
"inline-flex items-center justify-center rounded-full border border-transparent px-2.5 py-0.5 text-[15px] font-semibold tracking-[0.06em] uppercase w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
{
variants: {
variant: {

View file

@ -292,7 +292,7 @@ export function DeliverableTable({
<Users className="h-3.5 w-3.5 shrink-0 text-[var(--muted-foreground)]" />
<div className="flex flex-wrap gap-1">
{assignees.map((a) => (
<Badge key={a.id} variant="secondary" className="text-[10px]">
<Badge key={a.id} variant="secondary" className="text-[15px]">
{a.user?.name ?? a.user?.email ?? "Unknown"}
</Badge>
))}

View file

@ -211,7 +211,7 @@ export function GanttTimeline({
data-no-drag
size="sm"
variant="outline"
className="absolute top-2 right-4 z-50 h-7 text-[10px] gap-1.5 bg-[var(--card)]/90 backdrop-blur-sm shadow-lg"
className="absolute top-2 right-4 z-50 h-7 text-[15px] gap-1.5 bg-[var(--card)]/90 backdrop-blur-sm shadow-lg"
onClick={scrollToToday}
>
<CalendarDays className="h-3 w-3" />
@ -241,7 +241,7 @@ export function GanttTimeline({
style={{ height: HEADER_HEIGHT }}
>
<div
className="flex items-end px-3 pb-1 text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
className="flex items-end px-3 pb-1 text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
style={{ height: HEADER_HEIGHT }}
>
Deliverable
@ -272,7 +272,7 @@ export function GanttTimeline({
{weekHeaders.map((wh) => (
<div
key={wh.startIndex}
className="absolute flex items-center border-l border-r border-[var(--border)]/40 pl-1.5 text-[9px] font-semibold text-[var(--muted-foreground)]"
className="absolute flex items-center border-l border-r border-[var(--border)]/40 pl-1.5 text-[14px] font-semibold text-[var(--muted-foreground)]"
style={{
left: wh.startIndex * DAY_WIDTH,
width: wh.span * DAY_WIDTH,
@ -290,7 +290,7 @@ export function GanttTimeline({
<div
key={day.dayIndex}
className={cn(
"absolute flex flex-col items-center justify-center border-l text-[8px] leading-tight",
"absolute flex flex-col items-center justify-center border-l text-[12px] leading-tight",
day.isToday
? "bg-[var(--accent)]/20 font-bold text-[var(--accent)]"
: day.isWeekendDay
@ -304,7 +304,7 @@ export function GanttTimeline({
}}
>
<span className="font-semibold">{day.dayLabel}</span>
<span className="text-[7px] opacity-60">{day.dayOfWeek}</span>
<span className="text-[11px] opacity-60">{day.dayOfWeek}</span>
</div>
))}
</div>
@ -382,7 +382,7 @@ export function GanttTimeline({
>
{/* Stage name on bar (if wide enough) */}
{barPixelWidth > 60 && (
<span className="text-[8px] font-semibold text-white/90 pl-1.5 truncate">
<span className="text-[12px] font-semibold text-white/90 pl-1.5 truncate">
{stage.stageDefinition?.name ?? stage.template.name}
</span>
)}
@ -391,7 +391,7 @@ export function GanttTimeline({
{isActive && daysRemaining !== null && barPixelWidth > 35 && (
<span
className={cn(
"absolute -top-2.5 -right-1 text-[7px] font-bold px-1 rounded-full leading-none py-0.5",
"absolute -top-2.5 -right-1 text-[11px] font-bold px-1 rounded-full leading-none py-0.5",
isOverdue
? "bg-red-500 text-white"
: daysRemaining <= 2
@ -412,17 +412,17 @@ export function GanttTimeline({
<p className="font-semibold">{stage.stageDefinition?.name ?? stage.template.name}</p>
<p className="text-xs">{stage.status.replace(/_/g, " ")}</p>
{stage.startDate && (
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Started: {format(new Date(stage.startDate), "MMM d, yyyy")}
</p>
)}
{stage.dueDate && (
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Due: {format(new Date(stage.dueDate), "MMM d, yyyy")}
</p>
)}
{stage.completedDate && (
<p className="text-[10px] text-emerald-400">
<p className="text-[15px] text-emerald-400">
Completed: {format(new Date(stage.completedDate), "MMM d, yyyy")}
</p>
)}

View file

@ -180,7 +180,7 @@ export function KanbanBoard({
<Badge
variant="secondary"
className={cn(
"text-[10px]",
"text-[15px]",
PRIORITY_STYLES[deliv.priority]
)}
>
@ -205,7 +205,7 @@ export function KanbanBoard({
<Badge
key={a.id}
variant="secondary"
className="text-[10px]"
className="text-[15px]"
>
{a.user?.name ?? a.user?.email ?? "Unknown"}
</Badge>

View file

@ -296,7 +296,7 @@ export function ProductionTimeline({
data-no-drag
size="sm"
variant="outline"
className="absolute top-2 right-4 z-50 h-7 text-[10px] gap-1.5 bg-[var(--card)]/90 backdrop-blur-sm shadow-lg"
className="absolute top-2 right-4 z-50 h-7 text-[15px] gap-1.5 bg-[var(--card)]/90 backdrop-blur-sm shadow-lg"
onClick={scrollToToday}
>
<CalendarDays className="h-3 w-3" />
@ -305,7 +305,7 @@ export function ProductionTimeline({
{/* Drag hint */}
{isDragging && (
<div className="absolute top-2 left-1/2 -translate-x-1/2 z-50 text-[9px] font-medium text-[var(--muted-foreground)] bg-[var(--card)]/90 backdrop-blur-sm px-2 py-0.5 rounded-full border shadow-sm flex items-center gap-1">
<div className="absolute top-2 left-1/2 -translate-x-1/2 z-50 text-[14px] font-medium text-[var(--muted-foreground)] bg-[var(--card)]/90 backdrop-blur-sm px-2 py-0.5 rounded-full border shadow-sm flex items-center gap-1">
<GripHorizontal className="h-3 w-3" />
Drag to pan
</div>
@ -334,7 +334,7 @@ export function ProductionTimeline({
style={{ height: HEADER_HEIGHT }}
>
<div
className="flex items-end px-3 pb-1 text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
className="flex items-end px-3 pb-1 text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
style={{ height: HEADER_HEIGHT }}
>
Project / Deliverable
@ -369,24 +369,24 @@ export function ProductionTimeline({
)}
</div>
<div className="flex items-center gap-1">
<span className="text-[9px] font-mono text-[var(--muted-foreground)]">
<span className="text-[14px] font-mono text-[var(--muted-foreground)]">
{p.projectCode}
</span>
<Badge
variant="secondary"
className={cn(
"h-3.5 text-[8px] px-1",
"h-3.5 text-[12px] px-1",
PROJECT_STATUS_STYLES[p.status] || ""
)}
>
{p.status}
</Badge>
<span className="text-[8px] text-[var(--muted-foreground)]">
<span className="text-[12px] text-[var(--muted-foreground)]">
{p.completionPercent}%
</span>
</div>
</div>
<span className="text-[9px] text-[var(--muted-foreground)] shrink-0">
<span className="text-[14px] text-[var(--muted-foreground)] shrink-0">
{p.deliverableCount}
</span>
</div>
@ -402,7 +402,7 @@ export function ProductionTimeline({
>
<Link
href={`/projects/${row.project.id}/deliverables/${d.id}`}
className="text-[11px] truncate hover:underline"
className="text-[17px] truncate hover:underline"
onClick={(e) => e.stopPropagation()}
>
{d.name}
@ -424,7 +424,7 @@ export function ProductionTimeline({
{weekHeaders.map((wh) => (
<div
key={wh.startIndex}
className="absolute flex items-center border-l border-r border-[var(--border)]/40 pl-1.5 text-[9px] font-semibold text-[var(--muted-foreground)]"
className="absolute flex items-center border-l border-r border-[var(--border)]/40 pl-1.5 text-[14px] font-semibold text-[var(--muted-foreground)]"
style={{
left: wh.startIndex * DAY_WIDTH,
width: wh.span * DAY_WIDTH,
@ -443,7 +443,7 @@ export function ProductionTimeline({
<div
key={day.dayIndex}
className={cn(
"absolute flex flex-col items-center justify-center border-l text-[7px] leading-tight",
"absolute flex flex-col items-center justify-center border-l text-[11px] leading-tight",
day.isToday
? "bg-[var(--accent)]/20 font-bold text-[var(--accent)]"
: day.isWeekendDay
@ -457,7 +457,7 @@ export function ProductionTimeline({
}}
>
<span className="font-semibold">{day.dayLabel}</span>
<span className="text-[6px] opacity-60">{day.dayOfWeek}</span>
<span className="text-[9px] opacity-60">{day.dayOfWeek}</span>
</div>
))}
</div>
@ -490,7 +490,7 @@ export function ProductionTimeline({
{/* Today label */}
{todayIndex >= 0 && todayIndex < totalDays && (
<div
className="absolute z-20 text-[7px] font-bold text-[var(--accent)] bg-[var(--accent)]/15 px-1 rounded"
className="absolute z-20 text-[11px] font-bold text-[var(--accent)] bg-[var(--accent)]/15 px-1 rounded"
style={{
left: todayIndex * DAY_WIDTH + DAY_WIDTH / 2 - 12,
top: 2,
@ -686,14 +686,14 @@ export function ProductionTimeline({
>
{/* Stage name */}
{barPx > 55 && (
<span className="text-[7px] font-semibold text-white/90 pl-1 truncate">
<span className="text-[11px] font-semibold text-white/90 pl-1 truncate">
{stage.stageDefinition?.name ?? stage.template.name}
</span>
)}
{/* Artist initials */}
{barPx > 80 && stage.assignments.length > 0 && (
<span className="ml-auto text-[6px] font-bold text-white/60 pr-0.5">
<span className="ml-auto text-[9px] font-bold text-white/60 pr-0.5">
{stage.assignments.map((a) => getInitials(a.user.name)).join(" ")}
</span>
)}
@ -702,7 +702,7 @@ export function ProductionTimeline({
{isActive && daysRemaining !== null && barPx > 30 && (
<span
className={cn(
"absolute -top-2.5 -right-1 text-[6px] font-bold px-1 rounded-full leading-none py-0.5",
"absolute -top-2.5 -right-1 text-[9px] font-bold px-1 rounded-full leading-none py-0.5",
isOverdue
? "bg-red-500 text-white"
: daysRemaining <= 2
@ -723,17 +723,17 @@ export function ProductionTimeline({
<p className="font-semibold">{stage.stageDefinition?.name ?? stage.template.name}</p>
<p className="text-xs">{stage.status.replace(/_/g, " ")}</p>
{stage.assignments.length > 0 && (
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
{stage.assignments.map((a) => a.user.name).join(", ")}
</p>
)}
{stage.startDate && (
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Started: {format(new Date(stage.startDate), "MMM d")}
</p>
)}
{stage.dueDate && (
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
Due: {format(new Date(stage.dueDate), "MMM d")}
</p>
)}

View file

@ -82,7 +82,7 @@ export function CapacityCell({
>
<span>{primary}</span>
{count > 0 && bookedHours > 0 && (
<span className="text-[9px] font-normal text-[var(--muted-foreground)]">
<span className="text-[14px] font-normal text-[var(--muted-foreground)]">
+{bookedHours}h
</span>
)}
@ -108,7 +108,7 @@ export function CapacityCell({
{statusEntries.map(([status, num]) => (
<span
key={status}
className="inline-flex items-center gap-1 text-[10px]"
className="inline-flex items-center gap-1 text-[15px]"
>
<span
className={cn("h-2 w-2 rounded-full", STATUS_COLORS[status] || "bg-gray-400")}

View file

@ -80,11 +80,11 @@ export function CapacityDetailPopover({
{a.deliverableName}
</Link>
<div className="flex items-center gap-1.5 mt-0.5">
<p className="text-[10px] text-[var(--muted-foreground)]">
<p className="text-[15px] text-[var(--muted-foreground)]">
{a.stageName}
</p>
<span className="text-[10px] text-[var(--muted-foreground)]">·</span>
<p className="text-[10px] text-[var(--muted-foreground)]">
<span className="text-[15px] text-[var(--muted-foreground)]">·</span>
<p className="text-[15px] text-[var(--muted-foreground)]">
{a.projectName}
</p>
</div>
@ -92,14 +92,14 @@ export function CapacityDetailPopover({
<div className="flex items-center gap-1.5 shrink-0">
<Badge
variant="secondary"
className={`text-[10px] ${PRIORITY_STYLES[a.priority] || ""}`}
className={`text-[15px] ${PRIORITY_STYLES[a.priority] || ""}`}
>
{a.priority}
</Badge>
<StageStatusBadge status={a.stageStatus} />
</div>
{a.dueDate && (
<span className="shrink-0 text-[10px] text-[var(--muted-foreground)]">
<span className="shrink-0 text-[15px] text-[var(--muted-foreground)]">
Due {format(new Date(a.dueDate), "MMM d")}
</span>
)}

View file

@ -62,19 +62,19 @@ export function CapacityGrid({ users, weeks }: CapacityGridProps) {
<table className="w-full border-collapse text-sm">
<thead>
<tr className="bg-[var(--muted)]/50">
<th className="sticky left-0 z-10 min-w-[200px] bg-[var(--muted)]/50 px-3 py-2.5 text-left text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<th className="sticky left-0 z-10 min-w-[200px] bg-[var(--muted)]/50 px-3 py-2.5 text-left text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Team Member
</th>
<th className="min-w-[60px] px-1 py-2.5 text-center text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<th className="min-w-[60px] px-1 py-2.5 text-center text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Active
</th>
<th className="min-w-[60px] px-1 py-2.5 text-center text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<th className="min-w-[60px] px-1 py-2.5 text-center text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Cap
</th>
{weeks.map((week) => (
<th
key={week.weekStart}
className="min-w-[64px] px-1 py-2.5 text-center text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
className="min-w-[64px] px-1 py-2.5 text-center text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
>
{week.weekLabel}
</th>
@ -98,7 +98,7 @@ export function CapacityGrid({ users, weeks }: CapacityGridProps) {
<div className="flex items-center gap-2.5">
<Avatar className="h-7 w-7">
{user.userImage && <AvatarImage src={user.userImage} />}
<AvatarFallback className="text-[10px] font-semibold">
<AvatarFallback className="text-[15px] font-semibold">
{(user.userName || "?")
.split(" ")
.map((n) => n[0])
@ -110,11 +110,11 @@ export function CapacityGrid({ users, weeks }: CapacityGridProps) {
<div className="min-w-0">
<p className="text-xs font-medium truncate">{user.userName}</p>
<div className="flex items-center gap-1">
<Badge variant="outline" className="h-4 text-[9px] px-1">
<Badge variant="outline" className="h-4 text-[14px] px-1">
{user.role}
</Badge>
{user.department && (
<span className="text-[9px] text-[var(--muted-foreground)] truncate">
<span className="text-[14px] text-[var(--muted-foreground)] truncate">
{user.department}
</span>
)}

View file

@ -101,18 +101,18 @@ export function UtilizationHeatmap({
<table className="w-full border-collapse">
<thead>
<tr className="bg-[var(--muted)]/50">
<th className="sticky left-0 z-10 min-w-[160px] bg-[var(--muted)]/50 px-3 py-2.5 text-left text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<th className="sticky left-0 z-10 min-w-[160px] bg-[var(--muted)]/50 px-3 py-2.5 text-left text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Team Member
</th>
{weeks.map((week) => (
<th
key={week.weekStart}
className="min-w-[56px] px-0.5 py-2.5 text-center text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
className="min-w-[56px] px-0.5 py-2.5 text-center text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]"
>
{week.weekLabel}
</th>
))}
<th className="min-w-[60px] px-2 py-2.5 text-center text-[10px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
<th className="min-w-[60px] px-2 py-2.5 text-center text-[15px] font-semibold uppercase tracking-wider text-[var(--muted-foreground)]">
Avg
</th>
</tr>
@ -128,7 +128,7 @@ export function UtilizationHeatmap({
<tr key={user.userId} className="border-t">
<td className="sticky left-0 z-10 bg-[var(--card)] px-3 py-1.5">
<p className="text-xs font-medium truncate">{user.userName}</p>
<p className="text-[9px] text-[var(--muted-foreground)]">
<p className="text-[14px] text-[var(--muted-foreground)]">
Cap: {user.maxCapacity}
</p>
</td>
@ -144,7 +144,7 @@ export function UtilizationHeatmap({
<TooltipTrigger asChild>
<div
className={cn(
"flex h-9 items-center justify-center rounded text-[10px] font-medium",
"flex h-9 items-center justify-center rounded text-[15px] font-medium",
getHeatColor(utilization),
getTextColor(utilization)
)}
@ -173,7 +173,7 @@ export function UtilizationHeatmap({
<td className="px-1 py-1">
<div
className={cn(
"flex h-9 items-center justify-center rounded text-[10px] font-bold",
"flex h-9 items-center justify-center rounded text-[15px] font-bold",
getHeatColor(avgUtilization),
getTextColor(avgUtilization)
)}