Skip to content
KR.

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.

Design · Front-end · MotionInternal — not public

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.

ShortsE-booksPrompts
Mobile-first: the whole library on one scroll.
deep linkCampaign ad#ebooksShortsE-booksPromptsRegisterPlayerown view
Three content types stacked on one page rather than split across routes — so the whole offer is visible by scrolling — while the anchors stay deep-linkable, so a campaign can point an ad straight at the e-books.

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.

  1. 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
  2. 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.