diff --git a/CHANGES.md b/CHANGES.md
index b6f35bad8..b8a720fb9 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -6,6 +6,7 @@
 ### :sparkles: New features
 
 - Set an artboard as the file thumbnail [Taiga #1526](https://tree.taiga.io/project/penpot/us/1526)
+- Social login redesign [Taiga #2974](https://tree.taiga.io/project/penpot/task/2974)
 - Add border radius to our artboars [Taiga #2056](https://tree.taiga.io/project/penpot/us/2056)
 - Allow send multiple team invitations at once [Taiga #2798](https://tree.taiga.io/project/penpot/us/2798)
 - Persist color palette and color picker across refresh [Taiga #1660](https://tree.taiga.io/project/penpot/issue/1660)
@@ -18,6 +19,9 @@
 - New focus mode in workspace [Taiga #2748](https://tree.taiga.io/project/penpot/us/2748)
 - Changed text shapes to be displayed as natives SVG text elements [Taiga #2759](https://tree.taiga.io/project/penpot/us/2759)
 - Texts now can have strokes, multiple fills and can be used as masks
+- Add the ability to specify the attr for retrieve the email on OIDC integration [#1460](https://github.com/penpot/penpot/issues/1460)
+- Allow registration with invitation token when registration is disabled
+- Add the ability to disable standard, password login [Taiga #2999](https://tree.taiga.io/project/penpot/us/2999)
 
 ### :bug: Bugs fixed
 
diff --git a/backend/src/app/config.clj b/backend/src/app/config.clj
index b11ceae63..6dfbfc7ae 100644
--- a/backend/src/app/config.clj
+++ b/backend/src/app/config.clj
@@ -90,7 +90,7 @@
 
 (s/def ::flags ::us/set-of-keywords)
 
-;; DEPRECATED PROPERTIES: should be removed in 1.10
+;; DEPRECATED PROPERTIES
 (s/def ::registration-enabled ::us/boolean)
 (s/def ::smtp-enabled ::us/boolean)
 (s/def ::telemetry-enabled ::us/boolean)
@@ -138,11 +138,15 @@
 (s/def ::oidc-scopes ::us/set-of-str)
 (s/def ::oidc-roles ::us/set-of-str)
 (s/def ::oidc-roles-attr ::us/keyword)
+(s/def ::oidc-email-attr ::us/keyword)
+(s/def ::oidc-name-attr ::us/keyword)
 (s/def ::host ::us/string)
 (s/def ::http-server-port ::us/integer)
 (s/def ::http-server-host ::us/string)
-(s/def ::http-server-min-threads ::us/integer)
-(s/def ::http-server-max-threads ::us/integer)
+(s/def ::http-server-max-body-size ::us/integer)
+(s/def ::http-server-max-multipart-body-size ::us/integer)
+(s/def ::http-server-io-threads ::us/integer)
+(s/def ::http-server-worker-threads ::us/integer)
 (s/def ::http-session-idle-max-age ::dt/duration)
 (s/def ::http-session-updater-batch-max-age ::dt/duration)
 (s/def ::http-session-updater-batch-max-size ::us/integer)
@@ -239,12 +243,16 @@
                    ::oidc-user-uri
                    ::oidc-scopes
                    ::oidc-roles-attr
+                   ::oidc-email-attr
+                   ::oidc-name-attr
                    ::oidc-roles
                    ::host
                    ::http-server-host
                    ::http-server-port
-                   ::http-server-max-threads
-                   ::http-server-min-threads
+                   ::http-server-max-body-size
+                   ::http-server-max-multipart-body-size
+                   ::http-server-io-threads
+                   ::http-server-worker-threads
                    ::http-session-idle-max-age
                    ::http-session-updater-batch-max-age
                    ::http-session-updater-batch-max-size
@@ -339,8 +347,8 @@
       (when (ex/ex-info? e)
         (println ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;")
         (println "Error on validating configuration:")
-        (println (:explain (ex-data e))
-        (println ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;")))
+        (println (us/pretty-explain (ex-data e)))
+        (println ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"))
       (throw e))))
 
 (def version
diff --git a/backend/src/app/http.clj b/backend/src/app/http.clj
index fa8643879..010bc941f 100644
--- a/backend/src/app/http.clj
+++ b/backend/src/app/http.clj
@@ -7,9 +7,7 @@
 (ns app.http
   (:require
    [app.common.data :as d]
-   [app.common.exceptions :as ex]
    [app.common.logging :as l]
-   [app.common.spec :as us]
    [app.http.doc :as doc]
    [app.http.errors :as errors]
    [app.http.middleware :as middleware]
@@ -31,40 +29,46 @@
 
 (s/def ::handler fn?)
 (s/def ::router some?)
-(s/def ::port ::us/integer)
-(s/def ::host ::us/string)
-(s/def ::name ::us/string)
-(s/def ::executors (s/map-of keyword? ::wrk/executor))
+(s/def ::port integer?)
+(s/def ::host string?)
+(s/def ::name string?)
 
-;; (s/def ::max-threads ::cf/http-server-max-threads)
-;; (s/def ::min-threads ::cf/http-server-min-threads)
+(s/def ::max-body-size integer?)
+(s/def ::max-multipart-body-size integer?)
+(s/def ::io-threads integer?)
+(s/def ::worker-threads integer?)
 
 (defmethod ig/prep-key ::server
   [_ cfg]
   (merge {:name "http"
           :port 6060
-          :host "0.0.0.0"}
+          :host "0.0.0.0"
+          :max-body-size (* 1024 1024 24)             ; 24 MiB
+          :max-multipart-body-size (* 1024 1024 120)} ; 120 MiB
          (d/without-nils cfg)))
 
 (defmethod ig/pre-init-spec ::server [_]
-  (s/keys :req-un [::port ::host ::name ::executors]
-          :opt-un [::router ::handler]))
+  (s/and
+   (s/keys :req-un [::port ::host ::name ::max-body-size ::max-multipart-body-size]
+           :opt-un [::router ::handler ::io-threads ::worker-threads ::wrk/executor])
+   (fn [cfg]
+     (or (contains? cfg :router)
+         (contains? cfg :handler)))))
 
 (defmethod ig/init-key ::server
-  [_ {:keys [handler router port name host executors] :as cfg}]
-  (l/info :hint "starting http server"
-          :port port :host host :name name)
-
+  [_ {:keys [handler router port name host] :as cfg}]
+  (l/info :hint "starting http server" :port port :host host :name name)
   (let [options {:http/port port
                  :http/host host
-                 :ring/async true
-                 :xnio/dispatch (:default executors)}
-        handler (cond
-                  (fn? handler)  handler
-                  (some? router) (wrap-router cfg router)
-                  :else (ex/raise :type :internal
-                                  :code :invalid-argument
-                                  :hint "Missing `handler` or `router` option."))
+                 :http/max-body-size (:max-body-size cfg)
+                 :http/max-multipart-body-size (:max-multipart-body-size cfg)
+                 :xnio/io-threads (:io-threads cfg)
+                 :xnio/worker-threads (:worker-threads cfg)
+                 :xnio/dispatch (:executor cfg)
+                 :ring/async true}
+        handler (if (some? router)
+                  (wrap-router cfg router)
+                  handler)
         server  (yt/server handler (d/without-nils options))]
     (assoc cfg :server (yt/start! server))))
 
@@ -97,7 +101,7 @@
       (handler request respond
                (fn [cause]
                  (l/error :hint "unexpected error processing request"
-                          ::l/context (errors/get-error-context request cause)
+                          ::l/context (errors/get-context request)
                           :query-string (yrq/query request)
                           :cause cause)
                  (respond (yrs/response 500 "internal server error")))))))
diff --git a/backend/src/app/http/debug.clj b/backend/src/app/http/debug.clj
index 53f70a584..92daf1f63 100644
--- a/backend/src/app/http/debug.clj
+++ b/backend/src/app/http/debug.clj
@@ -162,7 +162,8 @@
             (let [context (dissoc report
                                   :trace :cause :params :data :spec-problems
                                   :spec-explain :spec-value :error :explain :hint)
-                  params  {:context (with-out-str (fpp/pprint context {:width 300}))
+                  params  {:context (with-out-str
+                                      (fpp/pprint context {:width 200}))
                            :hint    (:hint report)
                            :spec-explain  (:spec-explain report)
                            :spec-problems (:spec-problems report)
diff --git a/backend/src/app/http/errors.clj b/backend/src/app/http/errors.clj
index 40eaf9fc3..95d4f9819 100644
--- a/backend/src/app/http/errors.clj
+++ b/backend/src/app/http/errors.clj
@@ -21,27 +21,17 @@
       (yrq/get-header request "x-real-ip")
       (yrq/remote-addr request)))
 
-(defn get-error-context
-  [request error]
-  (let [data (ex-data error)]
-    (merge
-     {:path          (:uri request)
-      :method        (:request-method request)
-      :hint          (ex-message error)
-      :params        (:params request)
-
-      :spec-problems (some->> data ::s/problems (take 10) seq vec)
-      :spec-value    (some->> data ::s/value)
-      :data          (some-> data (dissoc ::s/problems ::s/value ::s/spec))
-      :ip-addr       (parse-client-ip request)
-      :profile-id    (:profile-id request)}
-
-     (let [headers (:headers request)]
-       {:user-agent (get headers "user-agent")
-        :frontend-version (get headers "x-frontend-version" "unknown")})
-
-     (when (and data (::s/problems data))
-       {:spec-explain (us/pretty-explain data)}))))
+(defn get-context
+  [request]
+  (merge
+   {:path          (:uri request)
+    :method        (:request-method request)
+    :params        (:params request)
+    :ip-addr       (parse-client-ip request)
+    :profile-id    (:profile-id request)}
+   (let [headers (:headers request)]
+     {:user-agent (get headers "user-agent")
+      :frontend-version (get headers "x-frontend-version" "unknown")})))
 
 (defmulti handle-exception
   (fn [err & _rest]
@@ -70,7 +60,7 @@
   (let [edata (ex-data error)
         explain (us/pretty-explain edata)]
     (l/error ::l/raw (ex-message error)
-             ::l/context (get-error-context request error)
+             ::l/context (get-context request)
              :cause error)
     (yrs/response :status 500
                   :body   {:type :server-error
@@ -96,7 +86,7 @@
       (handle-exception (:handling edata) request)
       (do
         (l/error ::l/raw (ex-message error)
-                 ::l/context (get-error-context request error)
+                 ::l/context (get-context request)
                  :cause error)
         (yrs/response 500 {:type :server-error
                            :code :unexpected
@@ -107,7 +97,7 @@
   [error request]
   (let [state (.getSQLState ^java.sql.SQLException error)]
     (l/error ::l/raw (ex-message error)
-             ::l/context (get-error-context request error)
+             ::l/context (get-context request)
              :cause error)
     (cond
       (= state "57014")
diff --git a/backend/src/app/http/oauth.clj b/backend/src/app/http/oauth.clj
index fffdcfbd1..4e2748529 100644
--- a/backend/src/app/http/oauth.clj
+++ b/backend/src/app/http/oauth.clj
@@ -57,7 +57,8 @@
                 :grant_type "authorization_code"
                 :redirect_uri (build-redirect-uri cfg)}
         req    {:method :post
-                :headers {"content-type" "application/x-www-form-urlencoded"}
+                :headers {"content-type" "application/x-www-form-urlencoded"
+                          "accept" "application/json"}
                 :uri (:token-uri provider)
                 :body (u/map->query-string params)}]
     (p/then
@@ -69,42 +70,61 @@
             :type (get data :token_type)})
          (ex/raise :type :internal
                    :code :unable-to-retrieve-token
-                   ::http-status status
-                   ::http-body body))))))
+                   :http-status status
+                   :http-body body))))))
 
 (defn- retrieve-user-info
   [{:keys [provider http-client] :as cfg} tdata]
-  (p/then
-   (http-client {:uri (:user-uri provider)
-                 :headers {"Authorization" (str (:type tdata) " " (:token tdata))}
-                 :timeout 6000
-                 :method :get})
-   (fn [{:keys [status body] :as res}]
-     (if (= 200 status)
-       (let [info (json/read body)
-             info {:backend (:name provider)
-                   :email (get info :email)
-                   :fullname (get info :name)
-                   :props (->> (dissoc info :name :email)
-                               (qualify-props provider))}]
+  (letfn [(retrieve []
+            (http-client {:uri (:user-uri provider)
+                          :headers {"Authorization" (str (:type tdata) " " (:token tdata))}
+                          :timeout 6000
+                          :method :get}))
 
-         (when-not (s/valid? ::info info)
-           (l/warn :hint "received incomplete profile info object (please set correct scopes)"
-                   :info (pr-str info))
-           (ex/raise :type :internal
-                     :code :unable-to-auth
-                     :hint "no user info"))
-         info)
-       (ex/raise :type :internal
-                 :code :unable-to-retrieve-user-info
-                 ::http-status status
-                 ::http-body body)))))
+          (validate-response [{:keys [status body] :as res}]
+            (when-not (= 200 status)
+              (ex/raise :type :internal
+                        :code :unable-to-retrieve-user-info
+                        :hint "unable to retrieve user info"
+                        :http-status status
+                        :http-body body))
+            res)
+
+          (get-email [info]
+            (let [attr-kw (cf/get :oidc-email-attr :email)]
+              (get info attr-kw)))
+
+          (get-name [info]
+            (let [attr-kw (cf/get :oidc-name-attr :name)]
+              (get info attr-kw)))
+
+          (process-response [{:keys [body]}]
+            (let [info (json/read body)]
+              {:backend  (:name provider)
+               :email    (get-email info)
+               :fullname (get-name info)
+               :props (->> (dissoc info :name :email)
+                           (qualify-props provider))}))
+
+          (validate-info [info]
+            (when-not (s/valid? ::info info)
+              (l/warn :hint "received incomplete profile info object (please set correct scopes)"
+                      :info (pr-str info))
+              (ex/raise :type :internal
+                        :code :incomplete-user-info
+                        :hint "inconmplete user info"
+                        :info info))
+            info)]
+
+    (-> (retrieve)
+        (p/then' validate-response)
+        (p/then' process-response)
+        (p/then' validate-info))))
 
 (s/def ::backend ::us/not-empty-string)
 (s/def ::email ::us/not-empty-string)
 (s/def ::fullname ::us/not-empty-string)
 (s/def ::props (s/map-of ::us/keyword any?))
-
 (s/def ::info
   (s/keys :req-un [::backend
                    ::email
@@ -112,7 +132,7 @@
                    ::props]))
 
 (defn retrieve-info
-  [{:keys [tokens provider] :as cfg} request]
+  [{:keys [tokens provider] :as cfg} {:keys [params] :as request}]
   (letfn [(validate-oidc [info]
             ;; If the provider is OIDC, we can proceed to check
             ;; roles if they are defined.
@@ -143,9 +163,15 @@
               (map? (:props state))
               (update :props merge (:props state))))]
 
-    (let [state  (get-in request [:params :state])
-          state  (tokens :verify {:token state :iss :oauth})
-          code   (get-in request [:params :code])]
+    (when-let [error (get params :error)]
+      (ex/raise :type :internal
+                :code :error-on-retrieving-code
+                :error-id error
+                :error-desc (get params :error_description)))
+
+    (let [state  (get params :state)
+          code   (get params :code)
+          state  (tokens :verify {:token state :iss :oauth})]
       (-> (p/resolved code)
           (p/then #(retrieve-access-token cfg %))
           (p/then #(retrieve-user-info cfg %))
@@ -224,15 +250,18 @@
       (redirect-response uri))))
 
 (defn- auth-handler
-  [{:keys [tokens] :as cfg} {:keys [params] :as request} respond _]
-  (let [props (extract-utm-props params)
-        state (tokens :generate
-                      {:iss :oauth
-                       :invitation-token (:invitation-token params)
-                       :props props
-                       :exp (dt/in-future "15m")})
-        uri   (build-auth-uri cfg state)]
-    (respond (yrs/response 200 {:redirect-uri uri}))))
+  [{:keys [tokens] :as cfg} {:keys [params] :as request} respond raise]
+  (try
+    (let [props (extract-utm-props params)
+          state (tokens :generate
+                        {:iss :oauth
+                         :invitation-token (:invitation-token params)
+                         :props props
+                         :exp (dt/in-future "15m")})
+          uri   (build-auth-uri cfg state)]
+      (respond (yrs/response 200 {:redirect-uri uri})))
+    (catch Throwable cause
+      (raise cause))))
 
 (defn- callback-handler
   [cfg request respond _]
@@ -242,7 +271,7 @@
               (generate-redirect cfg request info profile)))
 
           (handle-error [cause]
-            (l/warn :hint "error on oauth process" :cause cause)
+            (l/error :hint "error on oauth process" :cause cause)
             (respond (generate-error-redirect cfg cause)))]
 
     (-> (process-request)
@@ -385,17 +414,16 @@
         (assoc-in cfg [:providers "github"] opts))
       cfg)))
 
-
 (defn- initialize-gitlab-provider
   [cfg]
   (let [base (cf/get :gitlab-base-uri "https://gitlab.com")
         opts {:base-uri      base
               :client-id     (cf/get :gitlab-client-id)
               :client-secret (cf/get :gitlab-client-secret)
-              :scopes        #{"read_user"}
+              :scopes        #{"openid" "profile" "email"}
               :auth-uri      (str base "/oauth/authorize")
               :token-uri     (str base "/oauth/token")
-              :user-uri      (str base "/api/v4/user")
+              :user-uri      (str base "/oauth/userinfo")
               :name          "gitlab"}]
     (if (and (string? (:client-id opts))
              (string? (:client-secret opts)))
diff --git a/backend/src/app/loggers/audit.clj b/backend/src/app/loggers/audit.clj
index ae80ffaec..952c4d640 100644
--- a/backend/src/app/loggers/audit.clj
+++ b/backend/src/app/loggers/audit.clj
@@ -254,7 +254,7 @@
   "select * from audit_log
     where archived_at is null
     order by created_at asc
-    limit 1000
+    limit 256
       for update skip locked;")
 
 (defn archive-events
@@ -298,8 +298,9 @@
               (if (= (:status resp) 204)
                 true
                 (do
-                  (l/warn :hint "unable to archive events"
-                          :resp-status (:status resp))
+                  (l/error :hint "unable to archive events"
+                           :resp-status (:status resp)
+                           :resp-body (:body resp))
                   false))))
 
           (mark-as-archived [conn rows]
diff --git a/backend/src/app/main.clj b/backend/src/app/main.clj
index 7b54ad9f7..ec0808a8c 100644
--- a/backend/src/app/main.clj
+++ b/backend/src/app/main.clj
@@ -113,7 +113,8 @@
     :host        (cf/get :http-server-host)
     :router      (ig/ref :app.http/router)
     :metrics     (ig/ref :app.metrics/metrics)
-    :executors   (ig/ref :app.worker/executors)}
+    :executor    (ig/ref [::default :app.worker/executor])
+    :io-threads  (cf/get :http-server-io-threads)}
 
    :app.http/router
    {:assets        (ig/ref :app.http.assets/handlers)
diff --git a/backend/src/app/metrics.clj b/backend/src/app/metrics.clj
index 254c9d56b..2ae0223dc 100644
--- a/backend/src/app/metrics.clj
+++ b/backend/src/app/metrics.clj
@@ -262,10 +262,3 @@
     :gauge   (make-gauge props)
     :summary (make-summary props)
     :histogram (make-histogram props)))
-
-;; (defn instrument-jetty!
-;;   [^CollectorRegistry registry ^StatisticsHandler handler]
-;;   (doto (JettyStatisticsCollector. handler)
-;;     (.register registry))
-;;   nil)
-
diff --git a/backend/src/app/rpc/mutations/profile.clj b/backend/src/app/rpc/mutations/profile.clj
index 540e5e22b..963c36416 100644
--- a/backend/src/app/rpc/mutations/profile.clj
+++ b/backend/src/app/rpc/mutations/profile.clj
@@ -19,7 +19,6 @@
    [app.rpc.queries.profile :as profile]
    [app.rpc.rlimit :as rlimit]
    [app.storage :as sto]
-   [app.util.async :as async]
    [app.util.services :as sv]
    [app.util.time :as dt]
    [buddy.hashers :as hashers]
@@ -101,8 +100,14 @@
 (sv/defmethod ::prepare-register-profile {:auth false}
   [{:keys [pool tokens] :as cfg} params]
   (when-not (contains? cf/flags :registration)
-    (ex/raise :type :restriction
-              :code :registration-disabled))
+    (if-not (contains? params :invitation-token)
+      (ex/raise :type :restriction
+                :code :registration-disabled)
+      (let [invitation (tokens :verify {:token (:invitation-token params) :iss :team-invitation})]
+        (when-not (= (:email params) (:member-email invitation))
+          (ex/raise :type :restriction
+                    :code :email-does-not-match-invitation
+                    :hint "email should match the invitation")))))
 
   (when-let [domains (cf/get :registration-domain-whitelist)]
     (when-not (email-domain-in-whitelist? domains (:email params))
@@ -129,6 +134,7 @@
                 :backend "penpot"
                 :iss :prepared-register
                 :exp (dt/in-future "48h")}
+
         token  (tokens :generate params)]
     {:token token}))
 
@@ -149,7 +155,6 @@
   [{:keys [conn tokens session] :as cfg} {:keys [token] :as params}]
   (let [claims    (tokens :verify {:token token :iss :prepared-register})
         params    (merge params claims)]
-
     (check-profile-existence! conn params)
 
     (let [is-active  (or (:is-active params)
@@ -158,10 +163,8 @@
                           (create-profile conn)
                           (create-profile-relations conn)
                           (decode-profile-row))
-
           invitation (when-let [token (:invitation-token params)]
                        (tokens :verify {:token token :iss :team-invitation}))]
-
       (cond
         ;; If invitation token comes in params, this is because the user comes from team-invitation process;
         ;; in this case, regenerate token and send back to the user a new invitation token (and mark current
@@ -280,10 +283,14 @@
           :opt-un [::scope ::invitation-token]))
 
 (sv/defmethod ::login
-  {:auth false
-   ::async/dispatch :default
-   ::rlimit/permits (cf/get :rlimit-password)}
+  {:auth false ::rlimit/permits (cf/get :rlimit-password)}
   [{:keys [pool session tokens] :as cfg} {:keys [email password] :as params}]
+
+  (when-not (contains? cf/flags :login)
+    (ex/raise :type :restriction
+              :code :login-disabled
+              :hint "login is disabled in this instance"))
+
   (letfn [(check-password [profile password]
             (when (= (:password profile) "!")
               (ex/raise :type :validation
diff --git a/backend/src/app/storage.clj b/backend/src/app/storage.clj
index cff6c3363..218835149 100644
--- a/backend/src/app/storage.clj
+++ b/backend/src/app/storage.clj
@@ -259,7 +259,7 @@
 ;; A task responsible to permanently delete already marked as deleted
 ;; storage files. The storage objects are practically never marked to
 ;; be deleted directly by the api call. The touched-gc is responsible
-;; collect the usage of the object and mark it as deleted.
+;; of collecting the usage of the object and mark it as deleted.
 
 (declare sql:retrieve-deleted-objects-chunk)
 
diff --git a/backend/test/app/services_profile_test.clj b/backend/test/app/services_profile_test.clj
index fb0f4980e..c87e7cfa8 100644
--- a/backend/test/app/services_profile_test.clj
+++ b/backend/test/app/services_profile_test.clj
@@ -7,6 +7,7 @@
 (ns app.services-profile-test
   (:require
    [app.common.uuid :as uuid]
+   [app.config :as cf]
    [app.db :as db]
    [app.rpc.mutations.profile :as profile]
    [app.test-helpers :as th]
@@ -195,6 +196,56 @@
         (t/is (nil? error))))
     ))
 
+(t/deftest prepare-and-register-with-invitation-and-disabled-registration-1
+  (with-redefs [app.config/flags [:disable-registration]]
+    (let [tokens-fn (:app.tokens/tokens th/*system*)
+          itoken    (tokens-fn :generate
+                               {:iss :team-invitation
+                                :exp (dt/in-future "48h")
+                                :role :editor
+                                :team-id uuid/zero
+                                :member-email "user@example.com"})
+          data  {::th/type :prepare-register-profile
+                 :invitation-token itoken
+                 :email "user@example.com"
+                 :password "foobar"}
+
+          {:keys [result error] :as out} (th/mutation! data)]
+      (t/is (nil? error))
+      (t/is (map? result))
+      (t/is (string? (:token result)))
+
+      (let [rtoken (:token result)
+            data   {::th/type :register-profile
+                    :token rtoken
+                    :fullname "foobar"}
+
+            {:keys [result error] :as out} (th/mutation! data)]
+        ;; (th/print-result! out)
+        (t/is (nil? error))
+        (t/is (map? result))
+        (t/is (string? (:invitation-token result)))))))
+
+(t/deftest prepare-and-register-with-invitation-and-disabled-registration-2
+  (with-redefs [app.config/flags [:disable-registration]]
+    (let [tokens-fn (:app.tokens/tokens th/*system*)
+          itoken    (tokens-fn :generate
+                               {:iss :team-invitation
+                                :exp (dt/in-future "48h")
+                                :role :editor
+                                :team-id uuid/zero
+                                :member-email "user2@example.com"})
+
+          data  {::th/type :prepare-register-profile
+                 :invitation-token itoken
+                 :email "user@example.com"
+                 :password "foobar"}
+          {:keys [result error] :as out} (th/mutation! data)]
+      (t/is (th/ex-info? error))
+      (t/is (= :restriction (th/ex-type error)))
+      (t/is (= :email-does-not-match-invitation (th/ex-code error))))))
+
+
 (t/deftest prepare-register-with-registration-disabled
   (th/with-mocks {#'app.config/flags nil}
     (let [data  {::th/type :prepare-register-profile
diff --git a/backend/test/app/test_helpers.clj b/backend/test/app/test_helpers.clj
index f51bccc86..e626f4dd1 100644
--- a/backend/test/app/test_helpers.clj
+++ b/backend/test/app/test_helpers.clj
@@ -313,6 +313,14 @@
   [v]
   (instance? clojure.lang.ExceptionInfo v))
 
+(defn ex-type
+  [e]
+  (:type (ex-data e)))
+
+(defn ex-code
+  [e]
+  (:code (ex-data e)))
+
 (defn ex-of-type?
   [e type]
   (let [data (ex-data e)]
diff --git a/common/src/app/common/exceptions.cljc b/common/src/app/common/exceptions.cljc
index dbc63a8ba..b3b73e5a9 100644
--- a/common/src/app/common/exceptions.cljc
+++ b/common/src/app/common/exceptions.cljc
@@ -23,11 +23,12 @@
                    ::cause]))
 
 (defn error
-  [& {:keys [hint cause ::data] :as params}]
+  [& {:keys [hint cause ::data type] :as params}]
   (s/assert ::error-params params)
   (let [payload (-> params
                     (dissoc :cause ::data)
-                    (merge data))]
+                    (merge data))
+        hint    (or hint (pr-str type))]
     (ex-info hint payload cause)))
 
 (defmacro raise
diff --git a/common/src/app/common/flags.cljc b/common/src/app/common/flags.cljc
index 149f71c65..2bdaab823 100644
--- a/common/src/app/common/flags.cljc
+++ b/common/src/app/common/flags.cljc
@@ -12,7 +12,7 @@
 (def default
   "A common flags that affects both: backend and frontend."
   [:enable-registration
-   :enable-demo-users])
+   :enable-login])
 
 (defn parse
   [& flags]
diff --git a/common/src/app/common/logging.cljc b/common/src/app/common/logging.cljc
index 663f4beae..44cadc35d 100644
--- a/common/src/app/common/logging.cljc
+++ b/common/src/app/common/logging.cljc
@@ -8,8 +8,10 @@
   (:require
    [app.common.exceptions :as ex]
    [app.common.uuid :as uuid]
+   [app.common.spec :as us]
    [clojure.pprint :refer [pprint]]
    [cuerdas.core :as str]
+   [clojure.spec.alpha :as s]
    [fipp.edn :as fpp]
    #?(:clj [io.aviso.exception :as ie])
    #?(:cljs [goog.log :as glog]))
@@ -152,6 +154,18 @@
      [logger level]
      (.isEnabled ^Logger logger ^Level level)))
 
+#?(:clj
+   (defn get-error-context
+     [error]
+     (when-let [data (ex-data error)]
+       (merge
+        {:hint          (ex-message error)
+         :spec-problems (some->> data ::s/problems (take 10) seq vec)
+         :spec-value    (some->> data ::s/value)
+         :data          (some-> data (dissoc ::s/problems ::s/value ::s/spec))}
+        (when (and data (::s/problems data))
+          {:spec-explain (us/pretty-explain data)})))))
+
 (defmacro log
   [& {:keys [level cause ::logger ::async ::raw ::context] :or {async true} :as props}]
   (if (:ns &env) ; CLJS
@@ -169,7 +183,9 @@
            ~(if async
               `(send-off logging-agent
                          (fn [_#]
-                           (with-context (into {:id (uuid/next)} ~context)
+                           (with-context (merge {:id (uuid/next)}
+                                                (get-error-context ~cause)
+                                                ~context)
                             (->> (or ~raw (build-map-message ~props))
                                  (write-log! ~logger-sym ~level-sym ~cause)))))
 
diff --git a/common/src/app/common/spec.cljc b/common/src/app/common/spec.cljc
index 083011b7b..03f3ddc37 100644
--- a/common/src/app/common/spec.cljc
+++ b/common/src/app/common/spec.cljc
@@ -140,22 +140,26 @@
 
 ;; --- SPEC: set of Keywords
 
-(s/def ::set-of-keywords
-  (s/conformer
-   (fn [s]
-     (let [xform (comp
-                  (map (fn [s]
-                         (cond
-                           (string? s) (keyword s)
-                           (keyword? s) s
-                           :else nil)))
-                  (filter identity))]
-       (cond
-         (set? s)    (into #{} xform s)
-         (string? s) (into #{} xform (str/words s))
-         :else       ::s/invalid)))
-   (fn [s]
-     (str/join " " (map name s)))))
+(letfn [(conform-fn [dest s]
+          (let [xform (keep (fn [s]
+                              (cond
+                                (string? s) (keyword s)
+                                (keyword? s) s
+                                :else nil)))]
+            (cond
+              (set? s)    (into dest xform s)
+              (string? s) (into dest xform (str/words s))
+              :else       ::s/invalid)))]
+
+  (s/def ::set-of-keywords
+    (s/conformer
+     (fn [s] (conform-fn #{} s))
+     (fn [s] (str/join " " (map name s)))))
+
+  (s/def ::vec-of-keywords
+    (s/conformer
+     (fn [s] (conform-fn [] s))
+     (fn [s] (str/join " " (map name s))))))
 
 ;; --- SPEC: email
 
diff --git a/frontend/resources/images/icons/brand-gitlab.svg b/frontend/resources/images/icons/brand-gitlab.svg
index 8dc42e815..04993577b 100644
--- a/frontend/resources/images/icons/brand-gitlab.svg
+++ b/frontend/resources/images/icons/brand-gitlab.svg
@@ -1,10 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 13.1072 13.10542" preserveAspectRatio="xMinYMin meet">
-    <path d="M6.5534 13.1502l2.41333-7.42742H4.14l2.41334 7.42743z" fill="#e24329"/>
-    <path d="M6.5534 13.15016L4.14 5.72273H.75783l5.79556 7.42743z" fill="#fc6d26"/>
-    <path d="M.75783 5.72273L.02446 7.97991a.49964.49964 0 00.18147.5586l6.34746 4.6117L.75777 5.72278z" fill="#fca326"/>
-    <path d="M.75783 5.72278H4.14L2.68654 1.24927c-.0748-.2302-.40045-.23015-.4752 0L.75783 5.72278z" fill="#e24329"/>
-    <path d="M6.5534 13.15016l2.41333-7.42743h3.38223l-5.79562 7.42743z" fill="#fc6d26"/>
-    <path d="M12.34896 5.72273l.73336 2.25718" fill="#fca326"/>
-    <path d="M12.34896 5.72278H8.96673l1.45351-4.47351c.0748-.2302.40045-.23015.4752 0l1.45352 4.47351z" fill="#e24329"/>
-    <path d="M12.34937 5.72273l.73337 2.25718a.49964.49964 0 01-.18147.5586l-6.34746 4.6117 5.79561-7.42742z" fill="#fca326"/>
-</svg>
+<svg viewBox="3658.551 302.026 20 17.949" width="20" height="17.949" xmlns="http://www.w3.org/2000/svg" style="-webkit-print-color-adjust:exact"><path d="m3668.55 319.974 3.685-11.043h-7.364l3.68 11.043ZM3659.71 308.932l-1.122 3.355a.733.733 0 0 0 .277.83l9.685 6.857-8.84-11.042ZM3659.71 308.931h5.16l-2.22-6.65c-.114-.34-.61-.34-.727 0l-2.213 6.65Z" style="fill:#fff"/><path d="m3677.396 308.932 1.118 3.355a.733.733 0 0 1-.276.83l-9.688 6.857 8.846-11.042ZM3677.396 308.931h-5.16l2.216-6.65c.114-.34.61-.34.727 0l2.217 6.65ZM3668.55 319.974l3.685-11.042h5.16l-8.845 11.042ZM3668.55 319.974l-8.84-11.042h5.16l3.68 11.042Z" style="fill:#fff"/></svg>
\ No newline at end of file
diff --git a/frontend/resources/images/icons/brand-google.svg b/frontend/resources/images/icons/brand-google.svg
new file mode 100644
index 000000000..dba95de0f
--- /dev/null
+++ b/frontend/resources/images/icons/brand-google.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="5345 -1143 500 500"><path fill="#fff" fill-rule="evenodd" d="M5845-887c0-18-1-35-4-51h-240v96h137c-6 32-24 58-51 76v63h82c49-44 76-108 76-184z" clip-rule="evenodd"/><path fill="#fff" fill-rule="evenodd" d="M5601-643c68 0 126-22 168-60l-82-63a156 156 0 0 1-229-79h-85v64c42 82 128 138 228 138z" clip-rule="evenodd"/><path fill="#fff" fill-rule="evenodd" d="M5458-845a148 148 0 0 1 0-95v-65h-85a246 246 0 0 0 0 224z" clip-rule="evenodd"/><path fill="#fff" fill-rule="evenodd" d="M5601-1043c37 0 71 12 97 37l73-72a256 256 0 0 0-399 73l86 65c20-59 76-103 143-103z" clip-rule="evenodd"/></svg>
diff --git a/frontend/resources/images/icons/brand-openid.svg b/frontend/resources/images/icons/brand-openid.svg
new file mode 100644
index 000000000..a335b6664
--- /dev/null
+++ b/frontend/resources/images/icons/brand-openid.svg
@@ -0,0 +1 @@
+<svg viewBox="7437 302 20.011 18.182" width="20.011" height="18.182" xmlns="http://www.w3.org/2000/svg" style="-webkit-print-color-adjust:exact"><path d="M7455.039 309.1c-1.9-1.183-4.555-1.918-7.46-1.918-5.845 0-10.579 2.922-10.579 6.526 0 3.3 3.945 6.007 9.055 6.473v-1.9c-3.442-.43-6.024-2.313-6.024-4.573 0-2.564 3.37-4.662 7.549-4.662 2.08 0 3.962.52 5.325 1.363l-1.937 1.202h6.043v-3.73l-1.972 1.22Zm-8.984-5.146v16.227l3.03-1.9V302l-3.03 1.954Z" style="fill:#fff;fill-opacity:1"/></svg>
\ No newline at end of file
diff --git a/frontend/resources/styles/main/layouts/login.scss b/frontend/resources/styles/main/layouts/login.scss
index fa79a3995..574343485 100644
--- a/frontend/resources/styles/main/layouts/login.scss
+++ b/frontend/resources/styles/main/layouts/login.scss
@@ -72,20 +72,44 @@
     width: 412px;
 
     .auth-buttons {
-      margin-top: $size-6;
+      margin: $size-6 0 $size-4 0;
+      display: flex;
+      justify-content: center;
+      column-gap: 17px;
     }
 
     form {
-      margin: 2rem 0;
+      margin: 2rem 0 0.5rem 0;
     }
   }
 
+  .btn-large {
+    flex-grow: 1;
+    font-size: 14px;
+    font-family: sourcesanspro;
+    font-style: normal;
+    font-weight: normal;
+  }
+
   .btn-google-auth {
+    background-color: #4285f4;
+    color: $color-white;
     margin-bottom: $size-4;
     text-decoration: none;
+    .logo {
+      width: 20px;
+      height: 20px;
+      margin-right: 1rem;
+    }
+    &:hover {
+      background-color: #2065d7;
+      color: $color-white;
+    }
   }
 
   .btn-gitlab-auth {
+    background-color: #fc6d26;
+    color: $color-white;
     margin-bottom: $size-4;
     text-decoration: none;
 
@@ -94,9 +118,16 @@
       height: 20px;
       margin-right: 1rem;
     }
+
+    &:hover {
+      background-color: #ee5f18;
+      color: $color-white;
+    }
   }
 
   .btn-github-auth {
+    background-color: #4c4c4c;
+    color: $color-white;
     margin-bottom: $size-4;
     text-decoration: none;
 
@@ -105,6 +136,15 @@
       height: 20px;
       margin-right: 1rem;
     }
+
+    &:hover {
+      background-color: #2f2f2f;
+      color: $color-white;
+    }
+  }
+
+  .link-oidc {
+    text-align: center;
   }
 
   .separator {
@@ -112,6 +152,18 @@
     justify-content: center;
     width: 100%;
     text-transform: uppercase;
+    text-align: center;
+
+    .text {
+      margin: 0 10px;
+      color: $color-gray-40;
+    }
+
+    .line {
+      border: 1px solid $color-gray-10;
+      flex-grow: 10;
+      margin: auto;
+    }
   }
 
   .links {
diff --git a/frontend/src/app/config.cljs b/frontend/src/app/config.cljs
index 58b03b299..456f163a7 100644
--- a/frontend/src/app/config.cljs
+++ b/frontend/src/app/config.cljs
@@ -86,6 +86,9 @@
 (def browser              (atom (parse-browser)))
 (def platform             (atom (parse-platform)))
 
+(def terms-of-service-uri (obj/get global "penpotTermsOfServiceURI" nil))
+(def privacy-policy-uri   (obj/get global "penpotPrivacyPolicyURI" nil))
+
 ;; maintain for backward compatibility
 (let [login-with-ldap (obj/get global "penpotLoginWithLDAP" false)
       registration    (obj/get global "penpotRegistrationEnabled" true)]
@@ -135,5 +138,3 @@
    (str (cond-> (u/join public-uri "assets/by-file-media-id/")
           (true? thumbnail?) (u/join (str id "/thumbnail"))
           (false? thumbnail?) (u/join (str id))))))
-
-
diff --git a/frontend/src/app/main/ui/auth.cljs b/frontend/src/app/main/ui/auth.cljs
index 9c79ed2dd..3b00adacb 100644
--- a/frontend/src/app/main/ui/auth.cljs
+++ b/frontend/src/app/main/ui/auth.cljs
@@ -6,6 +6,7 @@
 
 (ns app.main.ui.auth
   (:require
+   [app.config :as cf]
    [app.main.ui.auth.login :refer [login-page]]
    [app.main.ui.auth.recovery :refer [recovery-page]]
    [app.main.ui.auth.recovery-request :refer [recovery-request-page]]
@@ -15,6 +16,23 @@
    [app.util.i18n :as i18n :refer [tr]]
    [rumext.alpha :as mf]))
 
+(mf/defc terms-login
+  []
+  (let [show-all?     (and cf/terms-of-service-uri cf/privacy-policy-uri)
+        show-terms?   (some? cf/terms-of-service-uri)
+        show-privacy? (some? cf/privacy-policy-uri)]
+
+    (when show-all?
+      [:div.terms-login
+       (when show-terms?
+         [:a {:href cf/terms-of-service-uri :target "_blank"} "Terms of service"])
+
+       (when show-all?
+         [:span "and"])
+
+       (when show-privacy?
+         [:a {:href cf/privacy-policy-uri :target "_blank"} "Privacy policy"])])))
+
 (mf/defc auth
   [{:keys [route] :as props}]
   (let [section (get-in route [:data :name])
@@ -48,7 +66,5 @@
         :auth-recovery
         [:& recovery-page {:params params}])
 
-      [:div.terms-login
-       [:a {:href "https://penpot.app/terms.html" :target "_blank"} "Terms of service"]
-       [:span "and"]
-       [:a {:href "https://penpot.app/privacy.html" :target "_blank"} "Privacy policy"]]]]))
+      [:& terms-login {}]]]))
+
diff --git a/frontend/src/app/main/ui/auth/login.cljs b/frontend/src/app/main/ui/auth/login.cljs
index 936d5ebb0..41e2c7e71 100644
--- a/frontend/src/app/main/ui/auth/login.cljs
+++ b/frontend/src/app/main/ui/auth/login.cljs
@@ -97,7 +97,6 @@
              (login-with-ldap event (with-meta params
                                       {:on-error on-error
                                        :on-success on-succes})))))]
-
     [:*
      (when-let [message @error]
        [:& msgs/inline-banner
@@ -123,9 +122,10 @@
          :label (tr "auth.password")}]]
 
       [:div.buttons-stack
-       [:& fm/submit-button
-        {:label (tr "auth.login-submit")
-         :data-test "login-submit"}]
+       (when (contains? @cf/flags :login)
+         [:& fm/submit-button
+          {:label (tr "auth.login-submit")
+           :data-test "login-submit"}])
 
        (when (contains? @cf/flags :login-with-ldap)
          [:& fm/submit-button
@@ -136,50 +136,69 @@
   [{:keys [params] :as props}]
   [:div.auth-buttons
    (when cf/google-client-id
-     [:a.btn-ocean.btn-large.btn-google-auth
+     [:a.btn-primary.btn-large.btn-google-auth
       {:on-click #(login-with-oauth % :google params)}
+      [:span.logo i/brand-google]
       (tr "auth.login-with-google-submit")])
 
-   (when cf/gitlab-client-id
-     [:a.btn-ocean.btn-large.btn-gitlab-auth
-      {:on-click #(login-with-oauth % :gitlab params)}
-      [:img.logo
-       {:src "/images/icons/brand-gitlab.svg"}]
-      (tr "auth.login-with-gitlab-submit")])
-
    (when cf/github-client-id
-     [:a.btn-ocean.btn-large.btn-github-auth
+     [:a.btn-primary.btn-large.btn-github-auth
       {:on-click #(login-with-oauth % :github params)}
-      [:img.logo
-       {:src "/images/icons/brand-github.svg"}]
+      [:span.logo i/brand-github]
       (tr "auth.login-with-github-submit")])
 
+   (when cf/gitlab-client-id
+     [:a.btn-primary.btn-large.btn-gitlab-auth
+      {:on-click #(login-with-oauth % :gitlab params)}
+      [:span.logo i/brand-gitlab]
+      (tr "auth.login-with-gitlab-submit")])
+
    (when cf/oidc-client-id
-     [:a.btn-ocean.btn-large.btn-github-auth
+     [:a.btn-primary.btn-large.btn-github-auth
       {:on-click #(login-with-oauth % :oidc params)}
+      [:span.logo i/brand-openid]
       (tr "auth.login-with-oidc-submit")])])
 
+(mf/defc login-button-oidc
+  [{:keys [params] :as props}]
+  (when cf/oidc-client-id
+    [:div.link-entry.link-oidc
+     [:a {:on-click #(login-with-oauth % :oidc params)}
+      (tr "auth.login-with-oidc-submit")]]))
+
 (mf/defc login-page
   [{:keys [params] :as props}]
   [:div.generic-form.login-form
    [:div.form-container
     [:h1 {:data-test "login-title"} (tr "auth.login-title")]
-    [:div.subtitle (tr "auth.login-subtitle")]
-
-    [:& login-form {:params params}]
 
     (when show-alt-login-buttons?
       [:*
-       [:span.separator (tr "labels.or")]
+       [:span.separator
+        [:span.line]
+        [:span.text (tr "labels.continue-with")]
+        [:span.line]]
 
        [:div.buttons
-        [:& login-buttons {:params params}]]])
+        [:& login-buttons {:params params}]]
+
+       (when (or (contains? @cf/flags :login)
+                 (contains? @cf/flags :login-with-ldap))
+         [:span.separator
+          [:span.line]
+          [:span.text (tr "labels.or")]
+          [:span.line]])])
+
+    (when (or (contains? @cf/flags :login)
+              (contains? @cf/flags :login-with-ldap))
+      [:& login-form {:params params}])
 
     [:div.links
-     [:div.link-entry
-      [:a {:on-click #(st/emit! (rt/nav :auth-recovery-request))
-           :data-test "forgot-password"}
-       (tr "auth.forgot-password")]]
+     (when (contains? @cf/flags :login)
+       [:div.link-entry
+        [:a {:on-click #(st/emit! (rt/nav :auth-recovery-request))
+             :data-test "forgot-password"}
+         (tr "auth.forgot-password")]])
 
      (when (contains? @cf/flags :registration)
        [:div.link-entry
diff --git a/frontend/src/app/main/ui/auth/register.cljs b/frontend/src/app/main/ui/auth/register.cljs
index 84ed3de24..9cb0ed293 100644
--- a/frontend/src/app/main/ui/auth/register.cljs
+++ b/frontend/src/app/main/ui/auth/register.cljs
@@ -121,15 +121,25 @@
    (when (contains? @cf/flags :demo-warning)
      [:& demo-warning])
 
+   (when login/show-alt-login-buttons?
+     [:*
+      [:span.separator
+       [:span.line]
+       [:span.text (tr "labels.continue-with")]
+       [:span.line]]
+
+      [:div.buttons
+       [:& login/login-buttons {:params params}]]
+
+      (when (or (contains? @cf/flags :login)
+                (contains? @cf/flags :login-with-ldap))
+        [:span.separator
+         [:span.line]
+         [:span.text (tr "labels.or")]
+         [:span.line]])])
+
    [:& register-form {:params params}]
 
-    (when login/show-alt-login-buttons?
-      [:*
-       [:span.separator (tr "labels.or")]
-
-       [:div.buttons
-        [:& login/login-buttons {:params params}]]])
-
    [:div.links
     [:div.link-entry
      [:span (tr "auth.already-have-account") " "]
diff --git a/frontend/src/app/main/ui/icons.cljs b/frontend/src/app/main/ui/icons.cljs
index db8a4ead5..d6ff5f0da 100644
--- a/frontend/src/app/main/ui/icons.cljs
+++ b/frontend/src/app/main/ui/icons.cljs
@@ -170,6 +170,10 @@
 (def uppercase (icon-xref :uppercase))
 (def user (icon-xref :user))
 
+(def brand-openid (icon-xref :brand-openid))
+(def brand-github (icon-xref :brand-github))
+(def brand-gitlab (icon-xref :brand-gitlab))
+(def brand-google (icon-xref :brand-google))
 
 (def loader-pencil
   (mf/html
diff --git a/frontend/translations/ar.po b/frontend/translations/ar.po
index e042e8d6d..c1af242ae 100644
--- a/frontend/translations/ar.po
+++ b/frontend/translations/ar.po
@@ -56,10 +56,6 @@ msgstr "تسجيل الدخول هنا"
 msgid "auth.login-submit"
 msgstr "تسجيل الدخول"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "أدخل التفاصيل أدناه"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "سعيد برؤيتك مجددا!"
diff --git a/frontend/translations/ca.po b/frontend/translations/ca.po
index af65d41fe..c960744f7 100644
--- a/frontend/translations/ca.po
+++ b/frontend/translations/ca.po
@@ -59,10 +59,6 @@ msgstr "Inicieu la sessió aquí"
 msgid "auth.login-submit"
 msgstr "Entra"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Introduïu les vostres dades a continuació"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Ens agrada tornar a veure-vos!"
diff --git a/frontend/translations/da.po b/frontend/translations/da.po
index 16ebcb64d..9f09c8dbd 100644
--- a/frontend/translations/da.po
+++ b/frontend/translations/da.po
@@ -59,10 +59,6 @@ msgstr "Log på her"
 msgid "auth.login-submit"
 msgstr "Log på"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Indtast dine oplysninger nedenunder"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Fedt at se dig igen!"
diff --git a/frontend/translations/de.po b/frontend/translations/de.po
index beafaf131..d2dd6c2b9 100644
--- a/frontend/translations/de.po
+++ b/frontend/translations/de.po
@@ -59,10 +59,6 @@ msgstr "Hier einloggen"
 msgid "auth.login-submit"
 msgstr "Anmelden"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Geben Sie unten Ihre Daten ein"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Schön, Sie wiederzusehen!"
diff --git a/frontend/translations/el.po b/frontend/translations/el.po
index f3100b1c4..582c5da77 100644
--- a/frontend/translations/el.po
+++ b/frontend/translations/el.po
@@ -54,10 +54,6 @@ msgstr "Συνδεθείτε εδώ"
 msgid "auth.login-submit"
 msgstr "Συνδεθείτε"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Εισαγάγετε τα στοιχεία σας παρακάτω"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Χαίρομαι που σας ξαναδώ"
diff --git a/frontend/translations/en.po b/frontend/translations/en.po
index bcd036717..6eacdf3a1 100644
--- a/frontend/translations/en.po
+++ b/frontend/translations/en.po
@@ -57,25 +57,21 @@ msgstr "Login here"
 msgid "auth.login-submit"
 msgstr "Login"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Enter your details below"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Great to see you again!"
 
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-with-github-submit"
-msgstr "Login with GitHub"
+msgstr "GitHub"
 
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-with-gitlab-submit"
-msgstr "Login with Gitlab"
+msgstr "Gitlab"
 
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-with-google-submit"
-msgstr "Login with Google"
+msgstr "Google"
 
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-with-ldap-submit"
@@ -83,7 +79,7 @@ msgstr "Login with LDAP"
 
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-with-oidc-submit"
-msgstr "Login with OpenID (SSO)"
+msgstr "OpenID Connect"
 
 #: src/app/main/ui/auth/recovery.cljs
 msgid "auth.new-password"
@@ -1231,6 +1227,9 @@ msgstr "Old password"
 msgid "labels.only-yours"
 msgstr "Only yours"
 
+msgid "labels.continue-with"
+msgstr "Continue with"
+
 msgid "labels.or"
 msgstr "or"
 
diff --git a/frontend/translations/es.po b/frontend/translations/es.po
index f557a462b..963881642 100644
--- a/frontend/translations/es.po
+++ b/frontend/translations/es.po
@@ -59,25 +59,21 @@ msgstr "Entra aquí"
 msgid "auth.login-submit"
 msgstr "Entrar"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Introduce tus datos aquí"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "¡Un placer verte de nuevo!"
 
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-with-github-submit"
-msgstr "Entrar con Github"
+msgstr "Github"
 
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-with-gitlab-submit"
-msgstr "Entrar con Gitlab"
+msgstr "Gitlab"
 
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-with-google-submit"
-msgstr "Entrar con Google"
+msgstr "Google"
 
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-with-ldap-submit"
@@ -85,7 +81,7 @@ msgstr "Entrar con LDAP"
 
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-with-oidc-submit"
-msgstr "Entrar con OpenID (SSO)"
+msgstr "OpenID Connect"
 
 #: src/app/main/ui/auth/recovery.cljs
 msgid "auth.new-password"
@@ -1232,6 +1228,9 @@ msgstr "Contraseña anterior"
 msgid "labels.only-yours"
 msgstr "Sólo los tuyos"
 
+msgid "labels.continue-with"
+msgstr "Continúa con"
+
 msgid "labels.or"
 msgstr "o"
 
diff --git a/frontend/translations/fr.po b/frontend/translations/fr.po
index 69fc42465..88c306d11 100644
--- a/frontend/translations/fr.po
+++ b/frontend/translations/fr.po
@@ -59,10 +59,6 @@ msgstr "Se connecter ici"
 msgid "auth.login-submit"
 msgstr "Se connecter"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Entrez vos informations ci‑dessous"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Ravi de vous revoir !"
diff --git a/frontend/translations/he.po b/frontend/translations/he.po
index 5d3be3b37..2aa0f8b37 100644
--- a/frontend/translations/he.po
+++ b/frontend/translations/he.po
@@ -56,10 +56,6 @@ msgstr "כניסה מכאן"
 msgid "auth.login-submit"
 msgstr "כניסה"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "נא למלא את הפרטים שלך להלן"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "שמחים לראות אותך שוב!"
diff --git a/frontend/translations/id.po b/frontend/translations/id.po
index f9380e177..adc798da5 100644
--- a/frontend/translations/id.po
+++ b/frontend/translations/id.po
@@ -63,10 +63,6 @@ msgstr "Masuk disini"
 msgid "auth.login-submit"
 msgstr "Masuk"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Masukkan detail anda di bawah ini"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Senang bertemu denganmu lagi!"
diff --git a/frontend/translations/pt_BR.po b/frontend/translations/pt_BR.po
index cd0442519..54a936db9 100644
--- a/frontend/translations/pt_BR.po
+++ b/frontend/translations/pt_BR.po
@@ -59,10 +59,6 @@ msgstr "Entrar aqui"
 msgid "auth.login-submit"
 msgstr "Entrar"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Insira seus dados abaixo"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Bom te ver de novo!"
diff --git a/frontend/translations/ro.po b/frontend/translations/ro.po
index 26c1f7e93..14f72441b 100644
--- a/frontend/translations/ro.po
+++ b/frontend/translations/ro.po
@@ -60,10 +60,6 @@ msgstr "Conectează-te"
 msgid "auth.login-submit"
 msgstr "Intră în cont"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Introduceți detaliile dvs. mai jos"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Mă bucur să te văd din nou!"
diff --git a/frontend/translations/ru.po b/frontend/translations/ru.po
index c8c118ca5..dac4374a0 100644
--- a/frontend/translations/ru.po
+++ b/frontend/translations/ru.po
@@ -48,10 +48,6 @@ msgstr "Войти здесь"
 msgid "auth.login-submit"
 msgstr "Вход"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Введите информацию о себе ниже"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Рады видеть Вас снова!"
diff --git a/frontend/translations/tr.po b/frontend/translations/tr.po
index bb1120a81..33a992d25 100644
--- a/frontend/translations/tr.po
+++ b/frontend/translations/tr.po
@@ -59,10 +59,6 @@ msgstr "Buradan oturum açın"
 msgid "auth.login-submit"
 msgstr "Oturum aç"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "Bilgilerini aşağıdaki alana gir"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "Seni tekrar görmek süper!"
diff --git a/frontend/translations/zh_CN.po b/frontend/translations/zh_CN.po
index 43cfecabd..b29c3026b 100644
--- a/frontend/translations/zh_CN.po
+++ b/frontend/translations/zh_CN.po
@@ -55,10 +55,6 @@ msgstr "在这里登录"
 msgid "auth.login-submit"
 msgstr "登录"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "请在下面输入你的详细信息"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "很高兴又见到你!"
diff --git a/frontend/translations/zh_Hant.po b/frontend/translations/zh_Hant.po
index dcfd8e9bc..9627b07e1 100644
--- a/frontend/translations/zh_Hant.po
+++ b/frontend/translations/zh_Hant.po
@@ -55,10 +55,6 @@ msgstr "在此登入"
 msgid "auth.login-submit"
 msgstr "登入"
 
-#: src/app/main/ui/auth/login.cljs
-msgid "auth.login-subtitle"
-msgstr "在下方輸入您的詳細資訊"
-
 #: src/app/main/ui/auth/login.cljs
 msgid "auth.login-title"
 msgstr "很高興再次見到你!"