Open to product and project roles

Hello,

Hello,

Harsh Upadhyay

Harsh here!

Harsh here!

Product and project manager who designs and builds

Product and project manager who designs and builds

Twenty seven course pages, and one template behind all of them.

The course pages for an HSC tutoring centre in Sydney, built in Framer on one CMS template. Most of the work was deciding what belonged in the CMS, and then writing the few things Framer couldn't do on its own.

Role

Design and build

Timeline

2026

Team

Two of us in the same Framer project

Live

proed.framer.website ↗

A ProEd course page, Year 10 Maths Tutoring, with the sticky section nav sitting under the hero

01

The problem

ProEd teaches Years 7 to 12 across English, maths and the sciences, out of more than one campus in Sydney. Every course needs a page of its own, and twenty seven pages maintained by hand drift apart inside a term.

The harder part was that the pages had to stay editable by the people who run the centre. Anything hard-coded would need a developer again later, so the real question on every section was whether it belonged in the CMS or in the furniture around it.

02

What I did

I built one template rather than twenty seven pages

Every course page runs off a single CMS template, with courses sitting alongside years, tutors, campuses and subjects, so a new course is a row rather than a page. Twenty nine of the text nodes on the page are bound to the CMS, and the fifteen that aren't are section furniture. That was the line I drew: if the centre would ever want to change it, it goes in the CMS.

I wrote the filters in code, because the canvas can't compare two values

The class finder has three dropdowns, for year, subject and campus. Framer's conditional visibility can ask whether a value is set and it can negate that, but it can't ask whether two values match, so a checked state was impossible to build on the canvas. I wrote a small checkbox component that takes the row's value and the current filter, normalises the case and the spacing, and draws the tick itself. Year and subject store the chosen name while campus stores the item id, so campus has to compare against its label instead.

I fixed the dropdowns that wouldn't close

Each field's tap set its own menu to open, and Framer has no toggle action, so nothing ever closed it again. A close layer inside the field didn't work either, because the click bubbled straight back to the field that had opened it. The fix was one backdrop per menu, sitting under the menu and over the page, which gives you both click again to close and click outside to dismiss.

I made the optional fields actually optional

Framer marks a new CMS field required by default, and that quietly broke every conditional section, because the centre couldn't leave a term, a holiday note, an FAQ or a testimonial empty without the page complaining. Re-adding each field with the same id and required set to false fixes it in place rather than creating a duplicate. Only the name, the year and the subject link are required now.

I missed a mobile frame that was already drawn

I built the mobile layout responsively from the desktop frame, and the Figma file had a mobile frame sitting in it the whole time that I never opened. It cost a rebuild. I check for a mobile frame before assuming a responsive pass will do now, because a designer who has drawn one has already made decisions I'd otherwise be guessing at.

Framer's conditional visibility can ask whether a value is set, but never whether two values match, so the comparison had to move into code.

03

How I ran it

Two of us worked inside the same Framer project, which sounds simple and isn't. Every write from my side forked a new auto-named branch off whatever branch I happened to be on, so the work scattered across branches called things like coral-ripple and ivory-shore, until I started checking the active branch after each session and handing the name over to be merged.

Early on I read those forks as somebody editing over me, and I said so. They were all mine, forked off my own branch, and the branch list showed it plainly. Checking what a branch is based on before blaming anyone is now the first thing I do.

Review came back as written notes against specific nodes, and the useful ones changed how the page was built rather than how it looked. The highlight behind a heading became a text style with an existing override on it rather than the code component I'd written for it, which left one less thing in the project to maintain.

04

The journey

A parent or a student arrives already knowing the year and roughly the subject, so the listing leads with that rather than with the centre. There are twenty seven cards, each naming its year and its subject, with a class finder above them for narrowing by year, subject and campus.

The course page itself is one scroll with a nav pill stuck to the top, so the features, the schedule, the week, the timetable, the pricing and the FAQ are each one tap away rather than six pages. That nav scrolls with JavaScript rather than native anchors, so every section carries a scroll margin matching the nav's own offset and nothing lands underneath it.

The week is the part that does the convincing. It shows the tutors with their results, what a lesson actually contains, and the practice resources behind it, which is the question a parent is really asking when they put one centre next to another.

05

What shipped

Twenty seven course pages across Years 7 to 12 in English, maths and the sciences, all running off one template, and each one carrying a sticky section nav, the weekly journey, the prices, the timetable and an FAQ. Desktop and mobile were merged and handed over in August 2026, and the pages are live at proed.framer.website.

06

Impact

Course pages, all from one template

27

Collections behind them, from courses to campuses

5

Text nodes bound to the CMS, not typed in

29

Filters that needed code, because the canvas can't compare

3

07

The work

A Year 10 Maths course page, the heading with Maths picked out in yellow, a photograph of a student beside it, and the sticky section nav below
The timetable prompt and the Year 10 Maths prices, split into group and private tutoring
The course listing and a course page at phone width, the same template on a smaller screen
What a week at ProEd looks like, the tutors shown with their results next to what a lesson contains and the practice resources behind it
The course listing, every card naming its year and its subject with the subject picked out in yellow
A Year 10 Maths course page, the heading with Maths picked out in yellow, a photograph of a student beside it, and the sticky section nav below
What a week at ProEd looks like, the tutors shown with their results next to what a lesson contains and the practice resources behind it
The timetable prompt and the Year 10 Maths prices, split into group and private tutoring
The course listing, every card naming its year and its subject with the subject picked out in yellow
The course listing and a course page at phone width, the same template on a smaller screen

The course listing with its class finder, then a course page from the hero down through the week and the prices, and the same pages on a phone.

08

Go deeper

Design system and Figma

The design came out of a Figma file with a desktop and a mobile frame for every section, and the build follows it rather than reinterpreting it. The shadows are the Figma values rather than something close to them, so a course card carries nine pixels of blur, the schedule card carries four, and the hero images carry none at all, because the design doesn't put one there.

Build and handover

One Framer project with five collections behind it, two small code components for the things the canvas can't do, and desktop and mobile merged into main. It went over in August 2026 with the branch names still to merge and a written list of what was open, including the content the centre owns, such as the real tutors, the campus data and the term dates.

More

All work

→