Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions src/app/(app)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@ export default function AppLayout({ children }: AppLayoutProps) {
<StepUpGuard />
</Suspense>
<Navigation />
<Box flexGrow="1" m="2">
<Container size="4" py="4">
{/*
* Reconciles the user's email-verification state with Ory on every
* authenticated page load (sync + reminder/confirmation banner).
* Wrapped in Suspense so its session/DB read streams in without
* blocking the page content below.
*/}
<Suspense fallback={null}>
<VerificationBanner />
</Suspense>
{children}
</Container>
<Box flexGrow="1" m="2" asChild>
<main>
<Container size="4" py="4">
{/*
* Reconciles the user's email-verification state with Ory on every
* authenticated page load (sync + reminder/confirmation banner).
* Wrapped in Suspense so its session/DB read streams in without
* blocking the page content below.
*/}
<Suspense fallback={null}>
<VerificationBanner />
</Suspense>
{children}
</Container>
</main>
</Box>
<Footer />
</Flex>
Expand Down
237 changes: 122 additions & 115 deletions src/app/(marketing)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,126 +49,133 @@ export default async function Landing() {
<Box className={styles.landing} px={{ sm: "6", lg: "9" }}>
<Box className={styles.landingInner} mx="auto" maxWidth="1400px">
<Navigation />
<Section className={styles.heroSection} px="4">
<Container>
<Flex align="center" gap="4">
<Flex
direction="column"
gap="4"
className={styles.heroContent}
minWidth={{ sm: "60ch" }}
>
<Heading size={{ initial: "8", xs: "9" }} my="5">
The Cooperative Data Publishing Utility
</Heading>
<Text size={{ xs: "5", sm: "6" }} weight="bold">
Data publishing at any scale for everyone.
</Text>
<Text size={{ xs: "5", sm: "6" }}>
Upload, share, and access data without needing to build or
maintain your own infrastructure.
</Text>
{/* ponytail: main starts after Navigation rather than wrapping the
whole page — Landing.module.css pins the nav background with
`.landingInner > nav`, so the nav has to stay a direct child. */}
<main>
<Section className={styles.heroSection} px="4">
<Container>
<Flex align="center" gap="4">
<Flex
direction="column"
gap="4"
align={{ initial: "stretch", xs: "start" }}
direction={{ initial: "column", sm: "row" }}
className={styles.heroContent}
minWidth={{ sm: "60ch" }}
>
<Link href="https://docs.source.coop">
<Button
size="3"
className={styles.subheading}
variant="outline"
highContrast
>
Read the docs &rarr;
</Button>
</Link>
<Link href={productListUrl()}>
<Button
size="3"
className={styles.subheading}
variant="solid"
highContrast
>
Explore Data Products &rarr;
</Button>
</Link>
<Heading size={{ initial: "8", xs: "9" }} my="5">
The Cooperative Data Publishing Utility
</Heading>
<Text size={{ xs: "5", sm: "6" }} weight="bold">
Data publishing at any scale for everyone.
</Text>
<Text size={{ xs: "5", sm: "6" }}>
Upload, share, and access data without needing to build or
maintain your own infrastructure.
</Text>
<Flex
gap="4"
align={{ initial: "stretch", xs: "start" }}
direction={{ initial: "column", sm: "row" }}
>
<Link href="https://docs.source.coop">
<Button
size="3"
className={styles.subheading}
variant="outline"
highContrast
>
Read the docs &rarr;
</Button>
</Link>
<Link href={productListUrl()}>
<Button
size="3"
className={styles.subheading}
variant="solid"
highContrast
>
Explore Data Products &rarr;
</Button>
</Link>
</Flex>
</Flex>
<Flex
display={{ initial: "none", sm: "flex" }}
className={styles.heroImageContainer}
flexShrink="0"
style={{ flexBasis: "600px" }}
>
<HeroGlobe wsUrl={CONFIG.locationWs.url || ""} />
</Flex>
</Flex>
</Container>
</Section>
<Section className={styles.productsSection} px="4">
<Container>
<SectionSubheading>Explore Source Datasets</SectionSubheading>
<Heading size="8" mb="6">
Featured Products
</Heading>
<ProductsList products={products} grid />
</Container>
</Section>
<Section px="4">
<Container>
<SectionSubheading>
What is Source Cooperative?
</SectionSubheading>
<Flex
display={{ initial: "none", sm: "flex" }}
className={styles.heroImageContainer}
flexShrink="0"
style={{ flexBasis: "600px" }}
direction={{ initial: "column", sm: "row" }}
align="start"
gap="8"
>
<HeroGlobe wsUrl={CONFIG.locationWs.url || ""} />
<Box flexBasis="50%">
<Heading size="8" mb="6">
The Challenge
</Heading>
<Text>
Scientific data infrastructure wasn&apos;t built for
cross-border, cross-sector cooperation.
<br />
<br />
Addressing global challenges means combining data from
governments, research institutions, commercial providers,
and civil society—each with its own formats, access
patterns, and APIs.
<br />
<br />
Data engineers, scientists, and researchers spend more
time wrangling infrastructure than doing their actual
work, hampering collaboration and limiting informed
decision making.
</Text>
</Box>
<Box flexBasis="50%">
<Heading size="8" mb="6">
Our Solution
</Heading>
<Text>
Source is a nonprofit data publishing utility built on
commodity cloud object storage. Researchers publish data
at any scale without running servers, building portals, or
writing APIs.
<br />
<br />
Source handles cloud infrastructure so researchers can
focus on their data, not their hosting. Users access
everything through standard URLs that work with existing
tools—no custom portals, no proprietary APIs.
<br />
<br />
The service is intentionally commoditized: built to resist
lock-in and designed so that no single provider, funder,
or political decision can make research data disappear.
</Text>
</Box>
</Flex>
</Flex>
</Container>
</Section>
<Section className={styles.productsSection} px="4">
<Container>
<SectionSubheading>Explore Source Datasets</SectionSubheading>
<Heading size="8" mb="6">
Featured Products
</Heading>
<ProductsList products={products} grid />
</Container>
</Section>
<Section px="4">
<Container>
<SectionSubheading>What is Source Cooperative?</SectionSubheading>
<Flex
direction={{ initial: "column", sm: "row" }}
align="start"
gap="8"
>
<Box flexBasis="50%">
<Heading size="8" mb="6">
The Challenge
</Heading>
<Text>
Scientific data infrastructure wasn&apos;t built for
cross-border, cross-sector cooperation.
<br />
<br />
Addressing global challenges means combining data from
governments, research institutions, commercial providers,
and civil society—each with its own formats, access
patterns, and APIs.
<br />
<br />
Data engineers, scientists, and researchers spend more time
wrangling infrastructure than doing their actual work,
hampering collaboration and limiting informed decision
making.
</Text>
</Box>
<Box flexBasis="50%">
<Heading size="8" mb="6">
Our Solution
</Heading>
<Text>
Source is a nonprofit data publishing utility built on
commodity cloud object storage. Researchers publish data at
any scale without running servers, building portals, or
writing APIs.
<br />
<br />
Source handles cloud infrastructure so researchers can focus
on their data, not their hosting. Users access everything
through standard URLs that work with existing tools—no
custom portals, no proprietary APIs.
<br />
<br />
The service is intentionally commoditized: built to resist
lock-in and designed so that no single provider, funder, or
political decision can make research data disappear.
</Text>
</Box>
</Flex>
</Container>
</Section>
</Container>
</Section>
</main>
</Box>
</Box>
<ThemeInverseComponent>
Expand Down Expand Up @@ -311,9 +318,9 @@ export default async function Landing() {
</Box>
<Box flexGrow="1">
<Text size="5" mb="4" as="div">
Source Cooperative supports your data lifecycle, from prototyping
to public release, without navigating corporate cloud
policies.
Source Cooperative supports your data lifecycle, from
prototyping to public release, without navigating corporate
cloud policies.
</Text>
<Link href={productListUrl()}>
<Button className={styles.subheading} highContrast>
Expand Down
10 changes: 7 additions & 3 deletions src/components/features/products/ProductsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,16 @@ export function ProductsList({
return (
<Box>
<nav aria-label="Product list">
<ul className={grid ? styles.gridList : styles.list} role="listbox">
{/* ponytail: a plain list, not a listbox. The j/k shortcuts are a
document-level keydown handler with no focus management and no
aria-activedescendant, so listbox/option promised a widget that
isn't implemented — and role="option" may not contain the link
each item renders. aria-current carries the highlight instead. */}
<ul className={grid ? styles.gridList : styles.list}>
{products.map((product, index) => (
<li
key={`${product.account_id}/${product.product_id}`}
role="option"
aria-selected={index === selectedIndex}
aria-current={index === selectedIndex || undefined}
>
<ProductListItem
product={product}
Expand Down
9 changes: 9 additions & 0 deletions src/components/layout/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import { MonoText } from "@/components/core";
import { homeUrl, productListUrl } from "@/lib/urls";
import { Logo } from "./Logo";

// ponytail: at 0.75rem these links are ~15px tall, under the 24px WCAG 2.2
// minimum. inline-block is what makes the padding count toward the hit box —
// vertical padding on an inline element paints without growing it.
const tapTarget = { display: "inline-block", paddingBlock: "5px" } as const;

export function Footer() {
const pathname = usePathname();

Expand Down Expand Up @@ -40,6 +45,7 @@ export function Footer() {
href="https://docs.source.coop"
color="gray"
underline="always"
style={tapTarget}
>
Docs
</RadixLink>
Expand All @@ -49,6 +55,7 @@ export function Footer() {
href="https://www.youtube.com/@GreatDataProducts"
color="gray"
underline="always"
style={tapTarget}
>
YouTube
</RadixLink>
Expand All @@ -58,6 +65,7 @@ export function Footer() {
href="https://www.linkedin.com/company/sourcecooperative/"
color="gray"
underline="always"
style={tapTarget}
>
LinkedIn
</RadixLink>
Expand All @@ -67,6 +75,7 @@ export function Footer() {
href="https://github.com/source-cooperative/"
color="gray"
underline="always"
style={tapTarget}
>
Github
</RadixLink>
Expand Down
Loading