diff --git a/README.md b/README.md
index 4a5a9db..8df529b 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,7 @@ link's build current automatically.
- [Architecture](docs/ARCHITECTURE.md) — how the pieces fit, selection, reminders, security
- [Roadmap](docs/ROADMAP.md) — shipped phases and what's next
- [Backend](backend/README.md) — API endpoints, auth, running locally
+- [Email templates](docs/EMAIL_TEMPLATES.md) — branded Supabase emails and installation
- [Deployment](mobile/DEPLOYMENT.md) — EAS builds, OTA updates, release runbook
## Contributing
diff --git a/backend/README.md b/backend/README.md
index 0bcd6bb..fd723d0 100644
--- a/backend/README.md
+++ b/backend/README.md
@@ -29,6 +29,7 @@ backend/
│ │ └── users.py profile bootstrap (safety net for the DB trigger)
│ └── api/v1/ health, topics, daily
├── migrations/ # plain SQL, applied in filename order
+├── email-templates/ # account email HTML installed manually in Supabase Auth
├── tests/ # 25 tests: token verification, selection, HTTP
├── Dockerfile # what Railway builds
└── .env.example # copy to .env — never commit the filled copy
@@ -106,6 +107,11 @@ confusion attacks, both of which are covered by tests.
`user_id` is taken from the verified token's `sub` claim and from nowhere else.
No endpoint accepts a user id as a parameter.
+Supabase Auth sends signup, recovery, and enabled security notifications using
+the project's configured sender. See [Email templates](../docs/EMAIL_TEMPLATES.md)
+for the three branded HTML files and manual installation steps. An app deployment
+does not publish these templates or change SMTP settings.
+
## Content generation
Gemini writes lessons. It does **not** choose subjects.
diff --git a/backend/email-templates/confirm-signup.html b/backend/email-templates/confirm-signup.html
new file mode 100644
index 0000000..784094f
--- /dev/null
+++ b/backend/email-templates/confirm-signup.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+ Confirm your email — One Concept
+
+
+
+ One last step to finish setting up your account.
+
+
+
+
+ |
+ One Concept.
+ by Coding Moves
+ |
+
+ Confirm your email.
+ Confirm this address to finish setting up your account.
+
+ Then return to the app and sign in.
+ |
+ |
+ If you didn’t sign up, you can ignore this email.
+ Button not working? Copy this link into your browser:
+
+ {{ .ConfirmationURL }}
+
+ |
+
+
+ |
+
+
+
diff --git a/backend/email-templates/password-changed.html b/backend/email-templates/password-changed.html
new file mode 100644
index 0000000..46897df
--- /dev/null
+++ b/backend/email-templates/password-changed.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+ Your password was changed — One Concept
+
+
+
+ A security update for your One Concept account.
+
+
+
+
+ |
+ One Concept.
+ by Coding Moves
+ |
+
+ Password changed.
+ Your One Concept password was changed.
+ If you made this change, no further action is needed.
+ |
+
+ Didn’t make this change?
+ Open One Concept and use Forgot password on the sign-in screen to reset your password.
+ Contact support immediately.
+ |
+
+
+ |
+
+
+
diff --git a/backend/email-templates/reset-password.html b/backend/email-templates/reset-password.html
new file mode 100644
index 0000000..3367efd
--- /dev/null
+++ b/backend/email-templates/reset-password.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+ Reset your password — One Concept
+
+
+
+ Choose a new password for your One Concept account.
+
+
+
+
+ |
+ One Concept.
+ by Coding Moves
+ |
+
+ Reset your password.
+ A password reset was requested for your account. Choose a new password below.
+
+ Once it’s saved, return to the app and sign in.
+ |
+ |
+ If you didn’t request this, ignore this email. Your password won’t change.
+ Button not working? Copy this link into your browser:
+
+ {{ .ConfirmationURL }}
+
+ |
+
+
+ |
+
+
+
diff --git a/docs/CODEBASE_MAP.md b/docs/CODEBASE_MAP.md
index 84e0c03..6063f16 100644
--- a/docs/CODEBASE_MAP.md
+++ b/docs/CODEBASE_MAP.md
@@ -18,6 +18,7 @@ learned history, streaks, likes, saved concepts, and push reminders.
| Operations | `.github/workflows/`, `backend/railway.json`, `backend/Dockerfile`, `mobile/eas.json`, `mobile/app.config.js`. |
| Documentation | Root `README.md`, `RELEASING.md`, `CONTRIBUTING.md`, `docs/ARCHITECTURE.md`, `docs/ROADMAP.md`, and the backend/mobile guides. |
| Agent guidance | Root `AGENTS.md`; `mobile/AGENTS.md` adds Expo documentation requirements and `mobile/CLAUDE.md` references it. |
+| Authentication email | `backend/email-templates/` contains branded signup, recovery, and password-changed HTML; `docs/EMAIL_TEMPLATES.md` covers manual Supabase installation and activation checks. Templates use the configured sender and are not installed by app deployment. |
## Mobile navigation and presentation
diff --git a/docs/EMAIL_TEMPLATES.md b/docs/EMAIL_TEMPLATES.md
new file mode 100644
index 0000000..4e429d9
--- /dev/null
+++ b/docs/EMAIL_TEMPLATES.md
@@ -0,0 +1,68 @@
+# One Concept email templates
+
+These three templates customize emails sent by Supabase Auth. They work with
+the project's configured sender; installing the HTML does not require Resend,
+a purchased domain, or an app update. Provider setup remains separate in
+[draft PR #187](https://github.com/Coding-Moves/one-concept/pull/187).
+
+**Merging or releasing the app does not install these files in Supabase.**
+Paste the templates into the dashboard to change future emails. The repository
+stores their reviewed source; it does not synchronize production settings.
+
+## Install
+
+1. Open the correct Supabase project, then **Authentication → Emails → Templates**.
+2. Open each template listed below and set its subject exactly as shown.
+3. Replace the body with the entire raw HTML file, starting with ``.
+ Copy the file's source, not its rendered browser preview, and save.
+4. Under **Security → Password changed**, also enable the notification and save.
+
+| Supabase template | Subject | HTML source |
+| --- | --- | --- |
+| Confirm sign up | `Confirm your email — One Concept` | [confirm-signup.html](../backend/email-templates/confirm-signup.html) |
+| Reset password | `Reset your password — One Concept` | [reset-password.html](../backend/email-templates/reset-password.html) |
+| Password changed (Security) | `Your password was changed — One Concept` | [password-changed.html](../backend/email-templates/password-changed.html) |
+
+Keep every `{{ .ConfirmationURL }}` placeholder in signup and recovery. Supabase
+fills in the appropriate verification URL; the button and copyable fallback
+must both pass through that verification. Password changed reports a completed
+change and intentionally has no token or reset-link placeholder. It directs
+unrecognized changes to Forgot password in the app and the existing support email.
+
+Preserve the project's existing working redirect configuration. Signup uses the
+configured Site URL for `/confirmed`; recovery requests `/reset-password` on the
+app's API base URL. The corresponding HTTPS destinations must be allowed in
+Supabase's URL Configuration. Do not replace verification links with those
+landing-page URLs. See [Supabase email templates](https://supabase.com/docs/guides/auth/auth-email-templates).
+
+## Sending and activation
+
+Template customization and sending capacity are separate. Supabase's default
+sender is for testing: it currently sends only to project-team addresses and
+allows two emails per hour. Other recipients require custom SMTP, which can be
+the owner's existing Gmail setup once configured and tested. These templates
+do not remove sender limits or establish delivery. See
+[Supabase SMTP documentation](https://supabase.com/docs/guides/auth/auth-smtp)
+(checked 2026-09-12).
+
+Before announcing the new emails to users, test with accounts and inboxes you
+control under the configured sender's limits:
+
+- Confirm signup, follow the email's button, and successfully sign in to the app.
+- Request Forgot password, set a new password through the recovery email, and
+ sign in with it. Verify the separate Password changed notification arrives.
+- Check the design in a real inbox on phone and desktop, the full fallback links,
+ and the Coding Moves organization and support destinations. Use a second inbox
+ provider and a non-team recipient when custom SMTP is available.
+
+Record the results before treating production activation as complete. Local
+browser previews verify layout, not Gmail/Outlook rendering or live delivery.
+No production settings or messages are changed by the template PR itself.
+
+## Design
+
+The dark masthead uses the owner's selected One Concept text branding and links
+Coding Moves once to its GitHub organization. The app's current image assets are
+Expo starter icons, so the emails do not use them as a logo. Inline styles,
+presentation tables, system fonts, and text links need no external assets.
+Subjects are separate dashboard fields; the HTML comments do not configure them.
diff --git a/docs/WORK_LOG.md b/docs/WORK_LOG.md
index 00ba6d9..7eaae3e 100644
--- a/docs/WORK_LOG.md
+++ b/docs/WORK_LOG.md
@@ -7,6 +7,17 @@ claims as completed work.
## Current status
+- Published the three branded Supabase templates in non-draft
+ [PR #188](https://github.com/Coding-Moves/one-concept/pull/188) into `develop`,
+ from `a6e81f1` on `codex/branded-auth-email-templates`. GitHub reports the PR
+ mergeable with no conflicts; no CI checks are configured for this PR.
+- Resend delivery preparation remains in [draft PR #187](https://github.com/Coding-Moves/one-concept/pull/187).
+ Its duplicate template files are removed in a follow-up commit. Original
+ histories are intact. Template installation is independent of a domain purchase
+ or app release and still requires pasting HTML into Supabase.
+- No SMTP settings, live templates, notifications, or production release were
+ changed. Real inbox rendering and delivery remain unverified.
+
- Implemented and validated [#151](https://github.com/Coding-Moves/one-concept/issues/151),
shared daily Gemini generation budget, on `codex/151-shared-generation-budget`
from refreshed `origin/develop` (`65eb21d`). Published
@@ -21,6 +32,38 @@ claims as completed work.
- PR #185 (#150) is merged. Preserve the owner's identity and the preference for
more focused commits in this and future PRs.
+## Separate branded email templates — 2026-09-12
+
+- Owner requested the three templates in a separate non-draft PR, allowing
+ branding to merge while domain/provider setup stays deferred. Rechecked
+ Supabase documentation: customizing templates does not remove the built-in
+ sender's team-only/two-emails-per-hour restrictions. Existing configured
+ Gmail SMTP can be used separately once authenticated and tested.
+- Preserved nine original template commits from #187, in order, covering signup,
+ recovery, copy/spacing improvements, the dark text masthead, the Coding Moves
+ organization link, and the password-changed notification. Sources are byte for
+ byte identical to the previously validated versions. The owner selected text
+ branding; no custom app logo was available.
+- Added `docs/EMAIL_TEMPLATES.md` with exact subjects, manual installation,
+ confirmation placeholders, the security toggle, existing redirect contract,
+ and activation checks. The guide does not require domain purchase or Resend.
+- **Validation:** the unchanged HTML previously passed 60 Chromium scenarios:
+ 48 for signup/recovery and 12 for password changed, across four widths and
+ normal/doubled/stripped styles, plus normal/long verification URLs. Those checks
+ covered links, fallback URLs, styled overflow, spacing, action sizes, and no
+ external resources; mobile/desktop/enlarged previews were inspected. For this
+ split, verified byte equality with `b0695ca`, inspected app redirect/support
+ source, checked local Markdown paths/anchors, and ran `git diff --check`.
+ Browser scenarios were not repeated for identical HTML. Backend/mobile and
+ live-email tests were not run for this HTML/documentation-only change.
+- Commits: `245b7f6` records scope; `d88f432` through `50d065d` preserve the nine
+ template changes; `4ccba83` adds installation/navigation docs; this handoff is
+ `docs: record independent email template PR and validation`.
+- **Handoff:** merge #188 independently of #187. Then install/test templates in
+ Supabase before announcing the changed emails. Merging/releasing the app does
+ not synchronize templates or enable security notifications. Delivery issues
+ #152/#171 stay open for the remaining operational work; no release PR opened.
+
## Shared generation budget (#151) — 2026-09-12
- Confirmed both gaps before implementation against the same generation source