diff --git a/.gitignore b/.gitignore index 3b9513a..010da08 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,7 @@ .codex-tmp .idea tmp + +# Ignore key files for decrypting credentials and more. +/config/credentials/*.key + diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 520c942..29d5c1d 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -641,6 +641,183 @@ body { outline-offset: 2px; } +.auth-page { + align-items: start; + display: grid; + justify-items: center; + min-height: calc(100vh - 4.75rem); + padding: clamp(2rem, 7vw, 5rem) clamp(1rem, 4vw, 2rem); +} + +.auth-page__panel { + background: + linear-gradient(145deg, rgba(245, 241, 232, 0.075), rgba(245, 241, 232, 0.025)); + border: 1px solid rgba(229, 184, 91, 0.32); + border-radius: 0.75rem; + box-shadow: 0 1.5rem 3.5rem rgba(0, 0, 0, 0.32); + max-width: 34rem; + overflow-wrap: anywhere; + padding: clamp(1.5rem, 5vw, 3rem); + width: 100%; +} + +.auth-page__heading { + color: #f5f1e8; + font-size: clamp(2.5rem, 8vw, 4.5rem); + letter-spacing: -0.035em; + line-height: 1; + margin: 0 0 2rem; +} + +.auth-form { + display: grid; + gap: 1.25rem; +} + +.auth-form__field { + display: grid; + gap: 0.45rem; +} + +.auth-form__field br { + display: none; +} + +.auth-form__field label, +.auth-form__remember label { + color: #e5b85b; + font-size: 0.9rem; + font-weight: 700; +} + +.auth-form__field label { + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.auth-form__input { + appearance: none; + background: #f5f1e8; + border: 1px solid rgba(25, 23, 20, 0.28); + border-radius: 0.375rem; + color: #191714; + font: inherit; + min-height: 3rem; + padding: 0.75rem; + width: 100%; +} + +.auth-form__input::placeholder { + color: rgba(25, 23, 20, 0.62); + opacity: 1; +} + +.auth-form__input:-webkit-autofill, +.auth-form__input:-webkit-autofill:hover, +.auth-form__input:-webkit-autofill:focus { + -webkit-text-fill-color: #191714; + box-shadow: 0 0 0 1000px #f5f1e8 inset; + caret-color: #191714; +} + +.auth-form__hint { + color: rgba(245, 241, 232, 0.72); + line-height: 1.4; +} + +.auth-form__remember { + align-items: center; + display: flex; + gap: 0.65rem; +} + +.auth-form__checkbox { + accent-color: #e5b85b; + cursor: pointer; + height: 1.2rem; + margin: 0; + width: 1.2rem; +} + +.auth-form__submit { + appearance: none; + background: #e5b85b; + border: 1px solid rgba(229, 184, 91, 0.74); + border-radius: 0.375rem; + color: #191714; + cursor: pointer; + font: inherit; + font-weight: 800; + min-height: 3rem; + padding: 0.75rem 1rem; + width: 100%; +} + +.auth-form__submit:hover { + background: #f5d284; +} + +.auth-page__alternate { + color: rgba(245, 241, 232, 0.78); + margin: 1.5rem 0 0; + text-align: center; +} + +.auth-page__link { + color: #e5b85b; + font-weight: 700; + text-decoration-thickness: 0.08em; + text-underline-offset: 0.18em; +} + +.auth-page__link:hover { + color: #f5d284; +} + +.auth-form__input:focus-visible, +.auth-form__checkbox:focus-visible, +.auth-form__submit:focus-visible, +.auth-page__link:focus-visible { + outline: 3px solid #f5d284; + outline-offset: 3px; +} + +.auth-errors { + background: rgba(240, 138, 115, 0.08); + border-left: 0.25rem solid #f08a73; + color: #f5f1e8; + margin: 0 0 1.5rem; + overflow-wrap: anywhere; + padding: 0.9rem 1rem; +} + +.auth-errors__heading { + font-size: 1rem; + line-height: 1.4; + margin: 0 0 0.5rem; +} + +.auth-errors__list { + line-height: 1.5; + margin: 0; + padding-left: 1.2rem; +} + +@media (max-width: 40rem) { + .auth-page { + min-height: auto; + padding: 1.25rem 1rem 6rem; + } + + .auth-page__panel { + padding: 1.5rem; + } + + .auth-page__heading { + margin-bottom: 1.5rem; + } +} + .status-page { display: grid; min-height: calc(100vh - 4.75rem); diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb index eb8c9aa..d9009b4 100644 --- a/app/views/devise/registrations/new.html.erb +++ b/app/views/devise/registrations/new.html.erb @@ -1,34 +1,36 @@ -
-

Sign up

+
+
+

Sign up

- <%= render "devise/shared/error_messages", resource: resource %> + <%= render "devise/shared/error_messages", resource: resource %> - <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> -
- <%= f.label :email %>
- <%= f.email_field :email, autofocus: true, autocomplete: "email" %> -
+ <%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { class: "auth-form" }) do |f| %> +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "auth-form__input" %> +
-
- <%= f.label :password %>
- <%= f.password_field :password, autocomplete: "new-password" %> - <% if @minimum_password_length %> - <%= @minimum_password_length %> characters minimum - <% end %> -
+
+ <%= f.label :password %>
+ <%= f.password_field :password, autocomplete: "new-password", class: "auth-form__input" %> + <% if @minimum_password_length %> + <%= @minimum_password_length %> characters minimum + <% end %> +
-
- <%= f.label :password_confirmation %>
- <%= f.password_field :password_confirmation, autocomplete: "new-password" %> -
+
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "new-password", class: "auth-form__input" %> +
-
- <%= f.label :preferred_name, "Preferred name" %>
- <%= f.text_field :preferred_name, autocomplete: "name" %> -
+
+ <%= f.label :preferred_name, "Preferred name" %>
+ <%= f.text_field :preferred_name, autocomplete: "name", class: "auth-form__input" %> +
- <%= f.submit "Sign up" %> - <% end %> + <%= f.submit "Sign up", class: "auth-form__submit" %> + <% end %> -

<%= link_to "Log in", new_session_path(resource_name) %>

+

<%= link_to "Log in", new_session_path(resource_name), class: "auth-page__link" %>

+
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index 79f8664..2e99c70 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -1,26 +1,28 @@ -
-

Log in

+
+
+

Log in

- <%= render "devise/shared/error_messages", resource: resource %> + <%= render "devise/shared/error_messages", resource: resource %> - <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> -
- <%= f.label :email %>
- <%= f.email_field :email, autofocus: true, autocomplete: "email" %> -
+ <%= form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: "auth-form" }) do |f| %> +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "auth-form__input" %> +
-
- <%= f.label :password %>
- <%= f.password_field :password, autocomplete: "current-password" %> -
+
+ <%= f.label :password %>
+ <%= f.password_field :password, autocomplete: "current-password", class: "auth-form__input" %> +
-
- <%= f.check_box :remember_me %> - <%= f.label :remember_me, "Remember me" %> -
+
+ <%= f.check_box :remember_me, class: "auth-form__checkbox" %> + <%= f.label :remember_me, "Remember me" %> +
- <%= f.submit "Log in" %> - <% end %> + <%= f.submit "Log in", class: "auth-form__submit" %> + <% end %> -

<%= link_to "Sign up", new_registration_path(resource_name) %>

+

<%= link_to "Sign up", new_registration_path(resource_name), class: "auth-page__link" %>

+
diff --git a/app/views/devise/shared/_error_messages.html.erb b/app/views/devise/shared/_error_messages.html.erb index 28807af..1ea9f39 100644 --- a/app/views/devise/shared/_error_messages.html.erb +++ b/app/views/devise/shared/_error_messages.html.erb @@ -1,7 +1,7 @@ <% if resource.errors.any? %> -