---
phase: 14-auth-pages
plan: "02"
subsystem: ui
tags: [go, templ, htmx, auth, google-oauth, design-system, css]

# Dependency graph
requires:
  - phase: 14-auth-pages/14-01
    provides: AuthLayout, GoogleButton, AuthDivider, auth.css, logo assets

provides:
  - backend/templates/auth_login.templ — migrated to AuthLayout + GoogleButton + ui.FormField inputs + signup nav link
  - backend/templates/auth_signup.templ — migrated to AuthLayout + GoogleButton + ui.FormField inputs + login nav link
  - Google button: Roboto font loaded, SVG icon sized correctly, width max-content per Google spec

affects: [any future phase touching auth page templates or layout]

# Tech tracking
tech-stack:
  added: []
  patterns:
    - "Auth page migration: replace @Layout(...) with @AuthLayout(title, csrfToken); remove raw <input> elements in favour of @ui.FormField/@ui.Input"
    - "Google button width: max-content (natural width per Google branding guidelines), not 100%"
    - "Roboto font: loaded from Google Fonts CDN in auth_layout.templ for gsi-material-button typography"
    - "Air dev workflow: .css files watched alongside .go/.templ; Tailwind runs on each rebuild"

key-files:
  created: []
  modified:
    - backend/templates/auth_login.templ
    - backend/templates/auth_signup.templ
    - backend/templates/auth_layout.templ
    - .air.toml

key-decisions:
  - "Button label: 'Sign in to Xtablo' (not 'Sign in') on login submit per copywriting contract"
  - "Signup password placeholder: '12 characters minimum' (different from login 'Your password')"
  - "Password autocomplete: 'new-password' on signup, 'current-password' on login"
  - "Google button width: max-content, not 100% — matches Google Material Design branding guidelines"
  - "Roboto font loaded in auth_layout.templ (not a global stylesheet) — auth pages only"
  - "AuthProviderButtonsBlock and AuthProviderButtonControl removed from auth_login.templ — superseded by GoogleButton from auth_components.templ"

patterns-established:
  - "FormField pattern: @ui.FormField(ui.FormFieldProps{Label, For, Field: ui.Input(ui.InputProps{...}), Error}) replaces raw <input> + FieldError"
  - "Auth page nav link: <p class='signup-copy'> ... <a class='signup-link' href='...'> ... </a></p>"

requirements-completed: [AUTH-UI-01, AUTH-UI-02, AUTH-UI-03]

# Metrics
duration: ~30min
completed: 2026-05-16
---

# Phase 14 Plan 02: Auth Pages Migration Summary

**Login and signup pages migrated to AuthLayout with ui.FormField inputs, Google sign-in button (Roboto font, correct icon sizing, max-content width), HTMX swap preserved, and CSS dev-watch wired into air**

## Performance

- **Duration:** ~30 min
- **Started:** 2026-05-16T17:07:00Z
- **Completed:** 2026-05-16T17:40:00Z
- **Tasks:** 2 (+ post-checkpoint bug fixes)
- **Files modified:** 4

## Accomplishments
- Replaced auth_login.templ and auth_signup.templ with AuthLayout-based structure: gradient animated background, brand logo, GoogleButton, AuthDivider, and ui.FormField/ui.Input fields
- HTMX swap preserved exactly: `hx-post="/login" hx-target="#login-form" hx-swap="outerHTML"` on login; `hx-post="/signup" hx-target="#signup-form" hx-swap="outerHTML"` on signup
- Google sign-in button corrected post-checkpoint: Roboto font loaded from Google Fonts CDN, SVG icon sized to 18x18px, button width set to max-content (natural width per Google Material Design spec)
- Cross-page navigation links added: login page links to /signup; signup page links to /login
- Air dev config updated to watch .css files and run Tailwind CLI on every rebuild, closing the hot-reload gap for CSS changes

## Task Commits

1. **Task 1: Migrate auth_login.templ to AuthLayout** - `808eaec` (feat)
2. **Task 2: Migrate auth_signup.templ to AuthLayout** - `65e3dbf` (feat)
3. **Post-checkpoint fix: Roboto font + SVG icon sizing** - `4624fb3` (fix)
4. **Post-checkpoint fix: Google button max-content width** - `70fe384` (fix)
5. **Dev tooling: air CSS watch + Tailwind rebuild** - `6e64cfb` (chore)

## Files Created/Modified
- `backend/templates/auth_login.templ` — Migrated to AuthLayout, GoogleButton, AuthDivider, ui.FormField email+password, signup nav link; AuthProviderButtonsBlock removed
- `backend/templates/auth_signup.templ` — Migrated to AuthLayout, GoogleButton, AuthDivider, ui.FormField email+password (new-password autocomplete, "12 characters minimum" placeholder), login nav link; signupCardBody removed
- `backend/templates/auth_layout.templ` — Roboto font loaded from Google Fonts; Google button width set to max-content
- `.air.toml` — .css added to include_ext; Tailwind CLI added to cmd so CSS rebuilds on every file change

## Decisions Made
- Google button set to `max-content` width (not `100%`) — matches Google Material Design branding guidelines; the pill button should be naturally sized, not stretched to fill the card
- Roboto font loaded only in auth_layout.templ — auth pages are the only context that renders the gsi-material-button, so global stylesheet pollution is avoided
- Auth handler test label `"Sign in with Google"` preserved — handlers were not changed; the label string already matched after Plan 01 established English labels in auth_components.templ
- `.air.toml` CSS watching added as a dev-workflow fix — without it, CSS edits required a manual restart; adding `.css` to include_ext with Tailwind in the rebuild command closes the gap

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 1 - Bug] Google button font and icon sizing incorrect after initial migration**
- **Found during:** Human-verify checkpoint (post-approval)
- **Issue:** gsi-material-button was rendering without Roboto font (fallback sans-serif), SVG icon was oversized, and button stretched to 100% of card width instead of natural pill width
- **Fix:** Added Roboto font `<link>` in auth_layout.templ; corrected SVG width/height to 18px; added `width: max-content` to `.gsi-material-button` CSS
- **Files modified:** backend/templates/auth_layout.templ
- **Verification:** Visual inspection confirmed correct rendering
- **Committed in:** `4624fb3`, `70fe384`

**2. [Rule 3 - Blocking] CSS edits not triggering air rebuild**
- **Found during:** Post-checkpoint dev workflow testing
- **Issue:** .air.toml did not include `.css` in `include_ext`, so editing auth.css did not trigger a server restart or Tailwind recompile during development
- **Fix:** Added `css` to `include_ext` and included the Tailwind CLI compile command in the air `cmd` field
- **Files modified:** .air.toml
- **Verification:** CSS edits now cause air to rebuild and serve updated styles
- **Committed in:** `6e64cfb`

---

**Total deviations:** 2 auto-fixed (1 bug post-checkpoint, 1 dev-workflow blocking issue)
**Impact on plan:** Both fixes necessary for correct visual output and development ergonomics. No scope creep.

## Issues Encountered
- Initial Google button appearance did not match Material Design spec (font, icon, width) — caught at visual verification and fixed post-checkpoint before marking plan complete.

## User Setup Required
None - no external service configuration required.

## Known Stubs
None. Both auth pages render real provider data (`providers.Google.Configured`, `providers.Google.StartURL`) passed from the handler. FormField inputs are wired to real form values and error strings. No placeholder data flows to the UI.

## Threat Flags
None. Changes are template-only. CSRF token placement (`@ui.CSRFField(csrfToken)`) preserved in both form fragments. GoogleButton href uses `templ.SafeURL` (established in Plan 01). No new trust boundaries introduced.

## Next Phase Readiness
- Phase 14 execution is complete. Both auth pages show the full visual redesign: animated gradient background, brand logo, Google sign-in button (Material Design), design-system form fields, and cross-page navigation links.
- HTMX swap behavior is intact — submitting either form triggers an inline fragment swap, not a full page reload.
- No blockers for future phases. The auth CSS classes and AuthLayout pattern are stable for any subsequent auth-page iteration.

---
*Phase: 14-auth-pages*
*Completed: 2026-05-16*
