BrainTrade
2026
Learning Shorts
Three content types stacked on a single page, each deep-linkable, so a campaign can point straight at the part it paid for.
Delivered to
Retail trading education
Learning Shorts
Delivery
Static page, live content
Backend: Hosted Postgres with object storage
Techniques
2
4 constants, formulas and guards
A mobile-first landing page for a trading academy's short-form learning — video shorts, downloadable e-books and prompt libraries — wired to a live content backend so the catalogue updates without a deploy. Its structural decision is to refuse navigation: every category is on one page, stacked, and the menu scrolls rather than routes.
Internal — not public
A learning section wired to a live content backend. Not linked from this page, and no project identifier, table or bucket name appears on it — the entry describes structure and decisions only.
A whole library on one scroll, with every part of it still addressable.
What was built, and for whom.
Learning Shorts
Retail trading education
en
Three content sections plus a registration band on one page, with a separate view for the course player only.
Each one starts with something that was broken.
- 01
Everything is on one page, and every part of it is still addressable
The failure
Splitting a small library into routes means a visitor has to guess which category holds what they want before they have seen any of it, and it means three pages to maintain for a section that is one screen's worth of content per type.
The decision
Stack all three categories on a single page so the whole offer is visible by scrolling, and keep the menu as scroll targets rather than links to routes — while preserving the hashes, so a campaign can still point an ad directly at the e-books and land the visitor on them. One page, three entry points. Only the course player, which genuinely needs the screen, is a separate view.
- constantapp.js
SECTIONS — the page's section identifiers declared once at the top of the script - constantapp.js
#shorts / #ebooks / #prompts remain deep-linkable anchors
- 02
The downloads bucket is public on purpose, and the reason is written down
The failure
Private object storage is the reflexively correct choice, and here it is the wrong one: signed URLs require a signer, and the visitors this page is built for are anonymous. Making the e-books private would mean either authenticating readers to download a lead magnet, or building a signing endpoint for files whose entire purpose is to be given away.
The decision
Keep the downloadable material in public storage deliberately, and record in the repository that it is deliberate so nobody 'fixes' it later. Separately, force the browser to download rather than preview, because a PDF that opens in a viewer tab is a PDF the visitor has not actually kept.
- guardREADME.md
“The bucket is public on purpose — anon visitors can’t sign a URL.” - constantapp.js
downloadUrl() appends a download parameter so the button saves rather than opens a viewer
What it cost
Public means enumerable, which is acceptable for material intended as a lead magnet and would not be for anything else. The distinction is the reason the note exists.
Every animation, with what it does when asked for less.
The last column is the one worth reading. “Respects reduced motion” is easy to assert and easy to skip, so where it is not true here, it says so.
Scroll to section
Smooth scroll from the menu
Ease-in-out
Falls back to the browser's own behaviour.
Card reveal
On intersection
Ease-out
Settled state is the default.
What it was built on, what is claimed, and what is not.
Delivery
Static page, live content
No build step for the page; the catalogue is fetched at runtime so publishing content is not a deployment.
Backend
Hosted Postgres with object storage
Named at the level a reader needs. No project identifier, table or bucket name appears on this page.
Structure
Section identifiers in one constant
The page's anchors are declared once at the top of the script rather than spread through markup.
Claimed — and how to check it
Three content categories live on one page with deep-linkable anchors
The SECTIONS constant and the anchors in app.js.
Public download storage is a recorded decision, not an oversight
The note in the repository README giving the reason.
Downloads save rather than open a viewer
The download-parameter helper in app.js.
Not claimed
- No enrolment, download or engagement figure.
- No backend project identifier, table, bucket name or key — none appears on this page.
- No claim over the learning content itself. The courses, e-books and prompts are the client's.
- Nothing here can be opened or verified by a reader.
Structure and decisions read from the repository. No backend identifier, table, bucket name or key appears on this page in any form.