Skip to main content
The board you finish this part with looks like the real thing. Three columns, cards inside them, a dark mode toggle that works. None of the buttons do anything, because there’s nowhere yet to put the data. That comes next. Starting here means you learn the template layer on its own, without a database, a migration or a service in the way. You’ll use: project scaffolding, Jinja2 template inheritance, the icon component macro, Tailwind with @apply, and Vite’s hot reload.

Create the project

Press Enter at every prompt. The defaults are what you want here:
A simple app with no database is all this part needs. Background jobs cost nothing at the default, since the thread backend requires no Redis.
Open http://localhost:5173 and you’ll get the welcome page.

Step 1: The project structure

Four of these directories matter for this part:

Step 2: The board route

Replace routes/pages/home.py:
routes/pages/home.py

Step 3: The board template

Create templates/pages/board.html:
templates/pages/board.html
Five Jinja2 constructs are doing the work:

Step 4: The CSS

Add this to static/css/app.css, after the existing content:
static/css/app.css
Feather prefers CSS classes with @apply. Templates stay readable, styles get reused across templates, and a restyle happens in one file rather than twenty. feather check reports utility classes in markup as the inline-tailwind warning.
Every colour-related @apply carries a dark: variant. The scaffolded base.html loads Feather’s dark-mode.js, which toggles a .dark class on <html> when anything with data-toggle-dark-mode is clicked.The toggle button holds two icon spans, icon-light and icon-dark, and CSS decides which is visible. No custom JavaScript.

Step 5: Run it

Open http://localhost:5173 and you should see the board. Worth trying while you’re here, because it’s the difference between the two reload paths:
  1. Change a column title in home.py, and watch the browser reload.
  2. Change a colour in app.css, and watch it update without a reload.

Prompt Claude

Run this from inside the kanban directory after scaffolding.
If the assistant reaches for utility classes in the template, feather check flags it as the inline-tailwind warning. Asking it to run the check catches this without you having to review the markup yourself.

Checkpoint

You’re done when:
  • Three columns render, each with its cards
  • The page is styled in both light and dark mode
  • The toggle in the header switches between them
  • Material icons render on the header and the buttons
  • feather check passes
The buttons don’t work yet. That’s expected.
Files you touched

What you learned

  • Scaffolding a project with feather new
  • Template inheritance with extends and block
  • Importing and calling component macros
  • The icon macro and its sizes
  • Writing Tailwind as @apply classes instead of markup utilities
  • Dark mode through dark: variants
  • Jinja2 loops, including the {% else %} branch for an empty list

Next: make it persist

Add models, migrations and services, then wire the buttons up with HTMX.