Files
the-daily-epub/src/web/templates/login.html
T
thalladaandClaude Fable 5.1 12134f3596 Web dashboard v2 step 2: Tailwind design system, theme toggle, reader pages
Replaces the hand-written stylesheet with a Tailwind CSS v4 source
(src/web/tailwind.css) whose minified build is committed as
src/web/static/app.css and still embedded with include_str!, so the binary
and the test suite never need Node. package.json pins tailwindcss and
@tailwindcss/cli to 4.3.3 and adds css, css:watch and css:check.

Colours are semantic CSS variables swapped per theme and exposed to Tailwind
through @theme inline, so templates write bg-paper/text-ink/border-rule once
and both themes work. theme.js runs synchronously in <head> to set
data-theme before paint; app.js cycles the toggle system -> light -> dark and
persists the choice. Newsreader is self-hosted and served from
web::static_asset with the same ETag/304 logic as the other assets.

Every reader template is restyled: ears row, centred masthead with its rules,
tracked section labels, the drop cap on The Brief, "Why it's here" with its
accent bar, the segmented rating control, prev/next cards, and the colophon
as a two-column definition grid. Dashboard templates are untouched (step 3).

Also fixes a .block collision with Tailwind's display utility, the SVG
`hidden` property that never toggled the theme icon, and points the dev
seed's profile_path at ./dev so previewing cannot rewrite data/profile.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHyYupFdBiR4VfoUM7NjSM
2026-09-03 20:51:08 +00:00

2 lines
1.0 KiB
HTML

{% extends "layout.html" %}{% block ears %}<span>Reader access</span>{% endblock %}{% block content %}<section class="mx-auto mt-12 max-w-md px-4 sm:mt-16 sm:px-6"><p class="font-sans text-[0.72rem] uppercase tracking-[0.12em] text-muted">Reader access</p><h1 class="mt-2 text-4xl font-semibold leading-[1.1] tracking-[-0.01em]">Sign in</h1><p class="mt-4 text-ink-2">Open the full paper, article chapters, and downloads.</p>{% if !error.is_empty() %}<p class="error mt-6">{{ error }}</p>{% endif %}<form class="mt-8 grid gap-5 font-sans text-sm" method="post" action="/login"><input type="hidden" name="next" value="{{ next }}"><label class="grid gap-1.5 font-medium">Username <input class="min-h-11 w-full" name="username" autocomplete="username" required></label><label class="grid gap-1.5 font-medium">Password <input class="min-h-11 w-full" type="password" name="password" autocomplete="current-password" required></label><button class="btn-primary mt-1 w-full" type="submit">Sign in</button></form></section>{% endblock %}