Feature: The two transactional email templates are replaced by the design's ready-to-use files As the maintainer of RenewCMS I want the verification and password-reset emails to use the exact Go html/template files from docs/design/source/emails/, renamed to match the design's naming, instead of the old ad hoc mailValidation.html and passwordReset.html files So that account-verification and password-reset emails match the visual spec (bulletproof button, preheader, dark-mode overrides), and the template name used at the call site reflects the file it now loads Background: Given internal/infrastructure/mailer/templates/mailValidation.html is removed and replaced by internal/infrastructure/mailer/templates/verification.html, copied verbatim from docs/design/source/emails/verification.html, still driven by a Go struct with a Host field and a VerificationCode field (the existing MailValidationData shape in CreateUser.go is unchanged) And internal/infrastructure/mailer/templates/passwordReset.html is removed and replaced by internal/infrastructure/mailer/templates/password-reset.html, copied verbatim from docs/design/source/emails/password-reset.html, still driven by a Go struct with a Host field, a VerificationCode field and an Email field (the existing MailPasswordResetData shape in RequestPasswordReset.go is unchanged) And MailRepository.Send (internal/infrastructure/mailer/mailRepository.go) is unchanged code: it already loads "templates/" + templateName + ".html" via template.ParseFS, so it now resolves the templateName "verification" to the new verification.html file and "password-reset" to the new password-reset.html file, purely because of the rename, with no change to Send's own logic And CreateUserUseCase.CreateUser (internal/infrastructure/useCases/CreateUser.go) now calls mail.Repository.Send with template "verification" instead of the old "mailValidation"; nothing else about that call changes: the receiver address, and the Host/VerificationCode data, are as before And RequestPasswordResetUseCase.RequestPasswordReset (internal/infrastructure/useCases/RequestPasswordReset.go) now calls mail.Repository.Send with template "password-reset" instead of the old "passwordReset"; nothing else about that call changes: the receiver address, and the Host/VerificationCode/Email data, are as before And the verification email's link is still built as "{{.Host}}/register/validate?c={{.VerificationCode}}" and the password-reset email's link is still built as "{{.Host}}/register/reset/validate?c={{.VerificationCode}}&email={{.Email}}", matching both the old templates and the use cases that populate them, so no handler, use case or route changes as a result of this slice And MailRepository (internal/infrastructure/mailer/mailRepository.go) gains an unexported render step, e.g. render(templateName string, data any) (subject string, body string, err error), that Send calls before dialing; render selects the subject by templateName ("Verify your RenewCMS account" for "verification", "Reset your RenewCMS password" for "password-reset", matching docs/design/emails.md's suggested subjects exactly) and parses/executes the corresponding templates/.html file, returning its rendered body; Send then uses that subject and body to build and dial the message exactly as before, and any ParseFS or Execute error from render is returned by Send unchanged, with the same log.Println call sites as today And an unrecognized templateName still reaches template.ParseFS, which fails to find "templates/.html" and returns its usual error; render does not special-case unknown names beyond the two known subjects, so an unknown templateName's subject falls back to the same literal "RenewCMS | Action required" used before this slice, and Send still returns the ParseFS error without attempting to dial And the two feature files that already assert a template-name string literal, registration_gate_and_verification_email.feature and request_password_reset.feature, are updated in this same slice so every occurrence of "mailValidation" reads "verification" and every occurrence of "passwordReset" reads "password-reset"; their behaviour is otherwise unchanged Scenario: Registering a user sends the verification email under its new template name Given the user repository is empty When the client sends POST /v1/auth/register with username "alice", password "hunter2example12", email "alice@example.com" Then the response status is 200 And exactly one email was sent to "alice@example.com" using template "verification" And that email's data has Host and VerificationCode populated exactly as before this slice Scenario: Requesting a password reset sends the reset email under its new template name Given the user repository contains a user "alice" with email "alice@example.com" When the client sends POST /v1/auth/password-reset with body {"email": "alice@example.com"} Then the response status is 200 And exactly one email was sent to "alice@example.com" using template "password-reset" And that email's data has Host, VerificationCode and Email populated exactly as before this slice Scenario: render() produces the verification email's subject, link and copy Given a real *mailer.MailRepository When its render step is called with templateName "verification" and data whose Host is "https://cms.example.com" and whose VerificationCode is "abc123" Then the returned subject is "Verify your RenewCMS account" And the returned body contains the link "https://cms.example.com/register/validate?c=abc123" And the returned body contains the button text "Verify my account" And the returned body contains the text "This link expires in 2 hours." Scenario: render() produces the password-reset email's subject, link and copy Given a real *mailer.MailRepository When its render step is called with templateName "password-reset" and data whose Host is "https://cms.example.com", whose VerificationCode is "abc123" and whose Email is "alice@example.com" Then the returned subject is "Reset your RenewCMS password" And the returned body contains the link "https://cms.example.com/register/reset/validate?c=abc123&email=alice%40example.com" And the returned body contains the button text "Choose a new password" And the returned body contains the text "This link expires in 1 hour and works once." Scenario: render() falls back to the old default subject for an unrecognized template name Given a real *mailer.MailRepository When its render step is called with templateName "does-not-exist" and any data Then the returned subject is "RenewCMS | Action required" And an error is returned because templates/does-not-exist.html cannot be found And the returned body is empty Scenario: A template execution failure is returned without sending Given a real *mailer.MailRepository And data that causes Execute to fail for a known templateName (e.g. a type without the fields the template references) When its render step is called with that templateName and that data Then render returns an error and MailRepository.Send never reaches DialAndSend Scenario Outline: The old template files no longer exist under their previous names Then the file internal/infrastructure/mailer/templates/ does not exist on disk Examples: | old file | | mailValidation.html | | passwordReset.html |