diff --git a/app/globals.css b/app/globals.css index 043a83f..8eabb85 100644 --- a/app/globals.css +++ b/app/globals.css @@ -40,8 +40,16 @@ --font-mono: var(--font-jetbrains-mono); } -* { - border-color: var(--border); +/* Default border color for every element. MUST stay inside `@layer base`: + Tailwind 4 emits border-color utilities into `@layer utilities`, and + unlayered CSS outranks every layer — so an unlayered `*` rule here silently + overrode `border-bitcoin/30`, `border-success/40`, `border-border-strong` + and every other accent border in the app. Inside `base` it only supersedes + preflight's `border: 0 solid` (currentColor) default, and any utility wins. */ +@layer base { + * { + border-color: var(--border); + } } html { diff --git a/app/hackathons/HackathonTimeline.tsx b/app/hackathons/HackathonTimeline.tsx index 03b93e9..66f2036 100644 --- a/app/hackathons/HackathonTimeline.tsx +++ b/app/hackathons/HackathonTimeline.tsx @@ -10,6 +10,7 @@ import { ChevronRight, Clock, Flame, + FolderGit2, Gauge, Layers, Radio, @@ -40,8 +41,32 @@ export type TimelineHackathon = { inscriptionOpen: boolean; countdown: string | null; sponsors: { name: string; logo: string }[]; + /** Projects registered for this hackathon — curated + community submissions, + * deduped the same way the detail page's list is. `null` when the relay + * snapshot came back empty, i.e. the count is unknown rather than zero. */ + projectCount: number | null; }; +/** "Sin proyectos" / "1 proyecto" / "N proyectos", or `null` when unknown — + * callers render nothing in that case rather than claiming a number. */ +function projectCountLabel(count: number | null): string | null { + if (count === null) return null; + if (count === 0) return "Sin proyectos"; + return `${count} ${count === 1 ? "proyecto" : "proyectos"}`; +} + +/** Tooltip body for the project-count chip. Spanish agreement follows the + * count, so the singular case reads "1 proyecto anotado … para verlo". */ +function projectCountTooltip(h: TimelineHackathon): string { + const n = h.projectCount ?? 0; + if (n > 0) { + return `${projectCountLabel(n)} ${n === 1 ? "anotado" : "anotados"} en este hackatón — abrí el detalle para ${n === 1 ? "verlo" : "verlos"}.`; + } + return h.status === "closed" + ? "No se anotó ningún proyecto en esta edición." + : "Todavía no se anotó ningún proyecto. Podés ser el primero."; +} + const STATUS_META: Record< TimelineHackathon["status"], { label: string; dot: string; text: string; ring: string } @@ -162,13 +187,18 @@ export default function HackathonTimeline({ {items.map((h, i) => { const meta = STATUS_META[h.status]; const selected = i === index; + const countLabel = projectCountLabel(h.projectCount); return (