Skip to content
Merged
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
30 changes: 15 additions & 15 deletions apps/web/app/home.css
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
/* Grid layout for the headline / CTAs / lede triple.
* Mobile: single column, document order = headline → CTAs (50/50 row)
* → lede. So the CTAs sit above the fold without scrolling.
* Desktop: 2-col grid headline in col 1, CTAs in col 2, lede spans
* Desktop: 2-col grid, headline in col 1, CTAs in col 2, lede spans
* full width below. (Tim 2026-05-21) */
.vt-home-hero-top {
display: grid;
Expand Down Expand Up @@ -281,7 +281,7 @@
/* Tim 2026-06-05: top + bottom hairlines removed so the stats row
* lives inside the hero rhythm with no chrome of its own. The single
* gold divider between this row and the bet feature card comes from
* the new .vt-home-stats-rule below that's the only horizontal
* the new .vt-home-stats-rule below, that's the only horizontal
* line in this area now. */
padding-block: 0;
}
Expand Down Expand Up @@ -1233,7 +1233,7 @@
}
/* The image background. image-set picks WebP first then falls back to
* JPG. If the file is missing the layer is transparent and the
* underlying #15151a + gradient takes over section still ships. */
* underlying #15151a + gradient takes over, section still ships. */
.vt-bet-feature-bg {
position: absolute;
inset: 0;
Expand Down Expand Up @@ -1294,12 +1294,12 @@
}
.vt-bet-feature-headline em {
font-style: italic;
/* Make "mental?" (the italic emphasis) WHITE per Tim 2026-06-05
* while the design is still in this state. The question mark sits
* inside the <em> so it picks up the italic + colour automatically.
* Slight WONK kicks the serif's swash details up. */
/* Gold italic, matches the /the-bet header treatment so "mental?"
* reads as the brand pun on both surfaces. Subtle text-shadow lifts
* the gold off the dark photo scrim. Tim 2026-06-05. */
font-variation-settings: "opsz" 120, "SOFT" 50, "WONK" 1;
color: #ffffff;
color: #f6c64f;
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.45);
}
.vt-bet-feature-shrug {
font-family: Fraunces, ui-serif, Georgia, serif;
Expand Down Expand Up @@ -1437,11 +1437,10 @@
column-gap: clamp(32px, 5vw, 64px);
}
}
.vt-home-stats-rule {
border: none;
border-top: 1px solid rgba(245, 197, 66, 0.22);
margin: clamp(20px, 3vw, 28px) 0 0;
}
/* .vt-home-stats-rule retired 2026-06-05, Tim wanted the divider
* between the stats row and the bet feature card gone entirely.
* Selector kept so any legacy markup still renders to nothing. */
.vt-home-stats-rule { display: none; }
.vt-home-stats-countdown {
/* The compact countdown sits in its own grid cell so it can right-
* align cleanly against the stats row on desktop. */
Expand All @@ -1457,10 +1456,11 @@
* above the fold on most desktop viewports. */
.vt-home-section--bet {
border-top: none !important;
padding-top: clamp(16px, 2vw, 24px);
padding-top: 0 !important;
margin-top: clamp(12px, 1.5vw, 20px);
}

/* Compact countdown variant used inline next to the stats row. */
/* Compact countdown variant, used inline next to the stats row. */
.vt-countdown--compact {
padding: 0;
background: none;
Expand Down
20 changes: 9 additions & 11 deletions apps/web/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-disable react/no-unescaped-entities */
/**
* Home page sales / landing flow for play.tournamental.com.
* Home page, sales / landing flow for play.tournamental.com.
*
* Tim's brief 2026-05-13: the home page must be a sales page, not a
* news feed. Flow:
* 1. Hero with the platform's one-line pitch + primary CTAs.
* 2. "Set your picks now" the core game, single big CTA into the
* 2. "Set your picks now", the core game, single big CTA into the
* bracket builder.
* 3. 3D molecule callout (watch-along + interactive bracket
* molecule) with features and benefits.
Expand Down Expand Up @@ -172,7 +172,7 @@ export default async function HomePage(): Promise<JSX.Element> {

// Split the lede on the {odds_link} placeholder so we can interpolate
// the inline <Link>. Falls back gracefully when the placeholder is
// missing render the bare translated lede.
// missing, render the bare translated lede.
const ledeParts = lede.split("{odds_link}");

return (
Expand Down Expand Up @@ -258,16 +258,14 @@ export default async function HomePage(): Promise<JSX.Element> {
/>
</div>
</div>
<hr className="vt-home-stats-rule" aria-hidden="true" />
</div>
</section>

{/* ============== BET FEATURE ============== */}
{/* Tim 2026-06-05: dramatic image-overlay feature card directly
* below the hero stats hairline. The --bet modifier kills the
* section's own border-top (the .vt-home-stats-rule above is
* the single divider) and tightens the section's top padding
* so the card lands above the fold on most viewports. */}
* below the hero stats row. The --bet modifier kills the
* default section border-top and zeroes top padding so the
* card lands tight under the stats with no divider. */}
<section className="vt-home-section vt-home-section--bet">
<article className="vt-bet-feature" aria-label="The bet">
<div className="vt-bet-feature-bg" aria-hidden="true" />
Expand Down Expand Up @@ -310,7 +308,7 @@ export default async function HomePage(): Promise<JSX.Element> {
</article>
</section>

{/* ============== STEP 1 PICKS ============== */}
{/* ============== STEP 1, PICKS ============== */}
{/* Reveal-on-scroll wrappers below ride the shared motion grammar
(8-14px rise + opacity, 600ms power3.out, light stagger). They
replace nothing visible: each section was already visible
Expand All @@ -333,11 +331,11 @@ export default async function HomePage(): Promise<JSX.Element> {
</RevealOnScroll>

{/* Step 2 (3D Molecule watch-along) and the Watch demo CTAs were
* dropped on 2026-05-21 play app is bracket-only for the
* dropped on 2026-05-21, play app is bracket-only for the
* 2026 WC push; the molecule still works on /world-cup-2026/molecule
* but it's no longer promoted from the player surfaces. */}

{/* ============== STEP 2 SYNDICATES (FRONT AND CENTRE) ============== */}
{/* ============== STEP 2, SYNDICATES (FRONT AND CENTRE) ============== */}
<RevealOnScroll as="section" className="vt-home-section vt-home-step vt-home-step-syndicates" id="syndicates">
<div className="vt-home-step-tag vt-home-step-tag-headline">{step2Tag}</div>
<h2 className="vt-home-h2">{step2Headline}</h2>
Expand Down
59 changes: 30 additions & 29 deletions apps/web/app/the-bet/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* /the-bet the house-prize promotion long-form, on the play app.
* /the-bet, the house-prize promotion long-form, on the play app.
*
* Lives on play.tournamental.com because the bet is FIFA-WC-bracket
* specific and ties to the predictions database that the play app
Expand Down Expand Up @@ -44,9 +44,8 @@ export default function TheBetPage(): JSX.Element {
Am I <em>mental</em> for betting my house on it?
</h1>
<p className="vt-bet-lede">
If you can predict every one of the 104 matches at the
2026 World Cup, I&apos;ll sign over what&apos;s left of
my equity.
If you can predict the correct outcome of all 104 matches at the
2026 World Cup, I&apos;ll give you my house.
</p>
{/* Tim 2026-06-05: press release lives in
* apps/web/public/press/. Anchor target=_blank, not next/link,
Expand All @@ -67,7 +66,7 @@ export default function TheBetPage(): JSX.Element {

<section className="vt-bet-body">
<p className="vt-bet-lead">
I&apos;m Tim Thomas. New Zealand engineer. Twenty-six years
I&apos;m Tim Thomas. New Zealand entrepreneur. Twenty-six years
building websites and apps. The last three weeks of those
years, I built a FIFA World Cup prediction game.
</p>
Expand All @@ -76,7 +75,7 @@ export default function TheBetPage(): JSX.Element {
matches at the 2026 World Cup correctly, I&apos;ll sign over
my house.
</p>
<p>It&apos;s worth NZ$1.5 million.</p>
<h2 className="vt-bet-h2">It&apos;s worth NZ$1.5 million.</h2>

<div className="vt-bet-callout">
<p className="vt-bet-callout-head">Quick honesty break.</p>
Expand All @@ -103,8 +102,7 @@ export default function TheBetPage(): JSX.Element {
</p>
<p>
If one person, anywhere in the world, predicts every one of
the 104 matches correctly through{" "}
<a href="https://play.tournamental.com">Tournamental.com</a>,
the 104 matches correctly through play.tournamental.com,
I list the house, settle the bank, and wire the rest to
their account.
</p>
Expand All @@ -121,14 +119,17 @@ export default function TheBetPage(): JSX.Element {
need every pick locked in by the kickoff of its own match.
</p>

<h2 className="vt-bet-h2">Worried? No.</h2>
<h2 className="vt-bet-h2">Worried? No.<br/>Risky? Hardly.</h2>
<p>
104 matches. Three outcomes each that count as a pick: home
win, draw, away win.
104 matches in total. The group stage has 72 matches, each
with three possible outcomes (home win, draw, away win). The
knockout rounds have 32 matches, each with two outcomes (the
team that progresses, or the team that doesn&apos;t).
</p>
<p>
Three to the power of one hundred and four is a number with{" "}
<strong>fifty digits</strong>.{" "}
Multiply that out: 3<sup>72</sup> &times; 2<sup>32</sup>. The
answer is a number with{" "}
<strong>44 digits</strong>, roughly 9.7 followed by 43 zeros.{" "}
<Link href="/odds">See the maths</Link>.
</p>
<p>
Expand Down Expand Up @@ -169,7 +170,7 @@ export default function TheBetPage(): JSX.Element {
</h2>
<p>
Smart question. You shouldn&apos;t trust me; you should trust
the code, it&apos;s 100% open-source.
the code, it&apos;s 100% open-source on <Link href="https://github.com/0800tim/tournamental" target="_blank">GitHub</Link>.
</p>
<p>
Every match kickoff, Tournamental hashes the predictions
Expand Down Expand Up @@ -197,23 +198,28 @@ export default function TheBetPage(): JSX.Element {
prediction game is the perfect engagement vehicle.
Tournamental is the best one I could possibly build.
</p>
<p>I&apos;m proud of it. I want people to play it.</p>
<p>I&apos;m proud of it. I want people to play it. </p>
<p>I've built it to handle 100,000+ concurrent users and want to put it to the test. </p>
<p>
The fastest way for one Kiwi developer to be heard above five
thousand other product launches in June 2026 is to put my
house on the line and mean it. Done.
</p>
<p>Yes, it's a publicity stunt, but it's a bloody good story isn't it?
Will it work? I don't know. We'll see.
</p>
<p>I'm a little bit torn doing this, and maybe mental. It's all in the name, I'm Tournamental.</p>
<p>
Side note: I built this in three weeks. That part
I built this in three weeks. That part
shouldn&apos;t be possible either. AI coding tools changed
what one developer can ship. The whole thing, sign-in,
brackets, leaderboards, the 3D match renderer, 21 languages,
the Bitcoin-blockchain audit trail, was one person at a laptop.
</p>
<p>
If you&apos;re in the New Zealand tech industry and
you&apos;re reading this thinking &ldquo;wait, three
weeks?&rdquo;, yes. Three weeks. Welcome to 2026.
If you&apos;re reading this thinking &ldquo;wait, three
weeks?&rdquo;, yes. Three weeks. It would have taken 6 months and 6 figures to build this for the 2022 World Cup.
Welcome to 2026. Maybe there'll be a team of Optimuls robots playing in the 2030 World Cup? Elon?
</p>

<h2 className="vt-bet-h2">How to enter</h2>
Expand Down Expand Up @@ -257,7 +263,7 @@ export default function TheBetPage(): JSX.Element {
<p>
Short version: open globally, 18+, one bracket per person.
You must register with a valid mobile phone number and
verify the one-time code we send you that&apos;s the
verify the one-time code we send you, that&apos;s the
eligibility check. Picks lock at each match&apos;s
kickoff. The prize is the{" "}
<strong>net cash proceeds from the sale of the house</strong>{" "}
Expand All @@ -267,25 +273,20 @@ export default function TheBetPage(): JSX.Element {
winner. If two people somehow both go 104-for-104, the
proceeds split.
</p>
<p>
Tournamental is run by <strong>Growth Spurt Ltd</strong>,
Auckland.
</p>


<p className="vt-bet-signoff">See you on the leaderboard.</p>
<p className="vt-bet-byline">
<strong>Tim Thomas</strong>, Tournamental
<strong>Tim Thomas</strong>,<br/>Tournamental
<br />
<a href="mailto:info@tournamental.com">info@tournamental.com</a>
</p>

<div className="vt-bet-cta-row">
<Link href="/world-cup-2026" className="vt-bet-cta-primary">
Pick your bracket →
</Link>
<Link href="/odds" className="vt-bet-cta-ghost">
Show me the maths
Pick your bracket to enter →
</Link>

</div>
</section>
</article>
Expand Down
Binary file added apps/web/public/hero/the-bet-hero.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/web/public/hero/the-bet-hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/web/public/hero/the-bet-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading