diff --git a/src/app/page.tsx b/src/app/page.tsx
index 4f873e5..3ce6316 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,6 +1,6 @@
import { AgentDirectory } from "@/components/agent-directory";
import { Collaborators } from "@/components/collaborators";
-import { Button, SectionLabel } from "@/components/ui";
+import { Button, Hero } from "@/components/ui";
import { agents } from "@/lib/agents";
import { site } from "@/lib/site";
@@ -16,31 +16,23 @@ import { site } from "@/lib/site";
export default function HomePage() {
return (
<>
- {/* ---------------------------------------------------------------- */}
- {/* Hero */}
- {/* ---------------------------------------------------------------- */}
-
- Agent Exchange
-
- Agent Exchange.
-
- {site.tagline}
-
-
-
-
-
-
+
+
+
+ >
+ }
+ >
-
+
- {/* ---------------------------------------------------------------- */}
- {/* Agent directory — search, filters, listings */}
- {/* ---------------------------------------------------------------- */}
>
);
diff --git a/src/app/practitioners/page.tsx b/src/app/practitioners/page.tsx
index 48ec2ae..ec03070 100644
--- a/src/app/practitioners/page.tsx
+++ b/src/app/practitioners/page.tsx
@@ -1,7 +1,7 @@
import type { Metadata } from "next";
import { Collaborators } from "@/components/collaborators";
import { PractitionerDirectory } from "@/components/practitioner-directory";
-import { Button, SectionLabel } from "@/components/ui";
+import { Button, Hero } from "@/components/ui";
import { listCredentialCatalogue, listProfiles, listServiceOptions } from "@/lib/directory";
/**
@@ -73,29 +73,23 @@ export default async function PractitionersPage() {
return (
<>
- {/* ---------------------------------------------------------------- */}
- {/* Hero */}
- {/* ---------------------------------------------------------------- */}
-
- Claude and Anthropic specialists
-
- Claude Specialists.
-
-
- Claude practitioners from the Code.Sydney community. Find one, hire one.
-
-
-
-
-
-
-
+
+
+
+ >
+ }
+ >
-
+
{/* ---------------------------------------------------------------- */}
{/* Practitioner directory — search, filters, profiles */}
diff --git a/src/app/prototype/page.tsx b/src/app/prototype/page.tsx
index ef5ea72..2769c98 100644
--- a/src/app/prototype/page.tsx
+++ b/src/app/prototype/page.tsx
@@ -57,7 +57,7 @@ export default function DesignIndex() {
{design.title}
diff --git a/src/components/agent-directory.tsx b/src/components/agent-directory.tsx
index 2306742..1b0fb2d 100644
--- a/src/components/agent-directory.tsx
+++ b/src/components/agent-directory.tsx
@@ -2,7 +2,7 @@
import { useId, useMemo, useRef, useState } from "react";
import { ArrowUpRight, Close, Search, Sparkle } from "@/components/icons";
-import { Badge, Card } from "@/components/ui";
+import { GradientBand } from "@/components/ui";
import { categories as categoryOptions, primaryLink, type Agent, type Category } from "@/lib/agents";
import { countryName } from "@/lib/practitioners";
@@ -18,6 +18,9 @@ import { countryName } from "@/lib/practitioners";
* this one has no credential catalogue and no verification, because every row
* here already cleared Bluehex's review before it was committed. See
* `@/lib/agents` for what that review replaces.
+ *
+ * The listings are cards rather than table rows: that is how the Xhibiter
+ * look the site follows lays out a roster.
*/
/** Every field a query is matched against, flattened once per agent. Mirrors
@@ -102,147 +105,134 @@ export function AgentDirectory({ agents }: { agents: Agent[] }) {
};
return (
-
- Find an agent.
+
+
+
+ Find an agent.
+
+
+
+ Every listing here was built by an indie developer and reviewed by Bluehex before it
+ went live — there is no self-service publishing yet, so what you see is the whole
+ roster.
+
-
- Every listing here was built by an indie developer and reviewed by Bluehex before it
- went live — there is no self-service publishing yet, so what you see is the whole
- roster.
-
+ {/* Search ----------------------------------------------------- */}
+
+
+
+
+ setQuery(event.target.value)}
+ placeholder="Search by name, category, developer or location"
+ className="w-full rounded-2xl border border-stroke bg-white py-3 pr-12 pl-11 text-t-bright placeholder:text-t-faint focus:border-ink focus:ring-2 focus:ring-ink focus:outline-none [&::-webkit-search-cancel-button]:appearance-none"
+ />
+ {query ? (
+
+ ) : null}
+
+
+
+ {/* Filters ---------------------------------------------------- */}
+
+ {countries.length > 0 ? (
+
+ {countries.map((country) => (
+ toggleCountry(country.code)}
+ >
+ {country.name}
+
+ ))}
+
+ ) : null}
- {/* Search ------------------------------------------------------- */}
-
-
-
-
- setQuery(event.target.value)}
- placeholder="Search by name, category, developer or location"
- className="w-full bg-transparent text-base outline-none placeholder:text-t-faint md:text-lg [&::-webkit-search-cancel-button]:appearance-none"
- />
- {query ? (
+ {offered.length > 0 ? (
+
+ {offered.map((category) => (
+ toggle(setCategoryFilters)(category)}
+ >
+ {category}
+
+ ))}
+
+ ) : null}
+
+ {filtering ? (
) : null}
-
- {/* Filters ------------------------------------------------------ */}
-
- {countries.length > 0 ? (
-
- {countries.map((country) => (
- toggleCountry(country.code)}
- >
- {country.name}
-
- ))}
-
- ) : null}
+ {/* Results ---------------------------------------------------- */}
+
+ {agents.length === 0
+ ? "The first agents are being reviewed now."
+ : `${results.length} ${results.length === 1 ? "agent" : "agents"}`}
+
- {offered.length > 0 ? (
-
- {offered.map((category) => (
- toggle(setCategoryFilters)(category)}
- >
- {category}
-
+ {filtering && results.length === 0 ? (
+
+
No agent matches that yet.
+
+ {agents.length > 0
+ ? "Try a broader term, or clear the filters to see everyone in the exchange."
+ : "No agents are listed yet, so there is nothing to search — clearing this will not turn any up. Yours could be the first."}
+
+
+ ) : (
+
+ {results.map((agent) => (
+ -
+
+
))}
-
- ) : null}
- {filtering ? (
-
- ) : null}
+ {!filtering ? (
+
+
+
+
+ Your agent here
+
+ Built something on Claude? Tell us about it through{" "}
+
+ Contact
+ {" "}
+ and, once it clears review, it lists here.
+
+
+ ) : null}
+
+ )}
-
- {/* Results ------------------------------------------------------ */}
-
- {agents.length === 0
- ? "The first agents are being reviewed now."
- : `${results.length} ${results.length === 1 ? "agent" : "agents"}`}
-
-
- {filtering && results.length === 0 ? (
-
- No agent matches that yet.
-
- {agents.length > 0
- ? "Try a broader term, or clear the filters to see everyone in the exchange."
- : "No agents are listed yet, so there is nothing to search — clearing this will not turn any up. Yours could be the first."}
-
-
- ) : (
-
- {results.length > 0 ? (
- <>
-
- Agent
- Description
- Category
-
-
-
-
- {results.map((agent) => (
- -
-
-
- ))}
-
- >
- ) : null}
-
- {!filtering ? (
-
-
-
Your agent here
-
- Built something on Claude? Tell us about it through{" "}
-
- Contact
- {" "}
- and, once it clears review, it lists here.
-
-
- ) : null}
-
- )}
-
+
);
}
@@ -250,14 +240,11 @@ function FilterGroup({ label, children }: { label: string; children: React.React
const labelId = useId();
return (
-
-
+
+
{label}
-
@@ -278,10 +265,10 @@ function FilterChip({
type="button"
onClick={onClick}
aria-pressed={pressed}
- className={`inline-flex h-10 items-center rounded-full border px-4 text-sm font-medium transition-colors ${
+ className={`inline-flex h-9 items-center rounded-xl border px-4 font-display text-sm transition-colors ${
pressed
- ? "border-ink bg-ink text-t-invert"
- : "border-stroke text-t-muted hover:border-stroke-strong hover:text-t-bright"
+ ? "border-transparent bg-ink text-white"
+ : "border-stroke bg-white text-t-muted hover:border-transparent hover:bg-ink hover:text-white"
}`}
>
{children}
@@ -289,54 +276,69 @@ function FilterChip({
);
}
-function AgentRow({ agent }: { agent: Agent }) {
+function AgentCard({ agent }: { agent: Agent }) {
const link = primaryLink(agent);
return (
- <>
-
-
{agent.name}
- {agent.tagline ? (
-
{agent.tagline}
- ) : null}
-
- By {agent.developerName}
- {agent.location ? ` · ${agent.location}` : ""}
-
- {agent.pricing ? (
-
{agent.pricing}
- ) : null}
+
+
+
+ {agent.name.charAt(0).toUpperCase()}
+
+
+
+ {agent.name}
+
+
+ By {agent.developerName}
+ {agent.location ? ` · ${agent.location}` : ""}
+
+
-
- {agent.description ? (
-
{agent.description}
- ) : (
-
No description yet.
- )}
-
+ {agent.tagline ? (
+ {agent.tagline}
+ ) : null}
+
+ {agent.description ? (
+ {agent.description}
+ ) : (
+ No description yet.
+ )}
-
+
{agent.categories.map((item) => (
- {item}
+
+ {item}
+
))}
- {/* One call to action per row, an external link rather than a `Link` —
- there is no `/agent/
` page yet, so the row sends a visitor
- straight to the agent's own site. See `primaryLink`. */}
- {link ? (
-
- Visit
- {agent.name}, opens in a new tab
-
-
- ) : null}
- >
+
+
{agent.pricing ?? ""}
+
+ {/* One call to action per card, an external link rather than a `Link` —
+ there is no `/agent/
` page yet, so the card sends a visitor
+ straight to the agent's own site. See `primaryLink`. */}
+ {link ? (
+
+ Visit
+ {agent.name}, opens in a new tab
+
+
+ ) : null}
+
+
);
}
diff --git a/src/components/collaborators.tsx b/src/components/collaborators.tsx
index 40a38a4..026e3c4 100644
--- a/src/components/collaborators.tsx
+++ b/src/components/collaborators.tsx
@@ -1,5 +1,4 @@
import Image from "next/image";
-import { Card } from "@/components/ui";
/* Communities Bluehex runs alongside. Logos are the collaborators' own
artwork, trimmed to their bounding box and given a transparent
@@ -28,30 +27,39 @@ const collaborators = [
},
];
-/** The "In collaboration with" strip that closes a page hero. */
+/** The "In collaboration with" strip that closes a page hero. Deliberately
+ quiet — a row of greyscale logos, like Xhibiter's partner strip — so it
+ credits the collaborators without competing with the page's own actions.
+ Each one still links out, and comes up to full strength on hover. */
export function Collaborators() {
return (
- <>
-
+
+
In collaboration with
-
- >
+
+
);
}
diff --git a/src/components/meetup-events.tsx b/src/components/meetup-events.tsx
index 6401193..1eb4462 100644
--- a/src/components/meetup-events.tsx
+++ b/src/components/meetup-events.tsx
@@ -76,7 +76,7 @@ export function MeetupEvents({ events }: { events: Event[] }) {
{upcoming.length > 0 ? (
-