From 796a6d5782aa6f7c6830935ff2bd4dce217adc57 Mon Sep 17 00:00:00 2001 From: Luis de Dios Date: Thu, 11 Jun 2026 16:32:58 +0200 Subject: [PATCH] :recycle: Refurbish create team slide --- .../images/form/slide-final-team.svg | 1 + frontend/src/app/main/ui/forms.cljs | 122 +++++++- frontend/src/app/main/ui/forms.scss | 43 +++ .../app/main/ui/onboarding/team_choice.cljs | 251 ++++++++------- .../app/main/ui/onboarding/team_choice.scss | 296 +++++++----------- 5 files changed, 401 insertions(+), 312 deletions(-) create mode 100644 frontend/resources/images/form/slide-final-team.svg create mode 100644 frontend/src/app/main/ui/forms.scss diff --git a/frontend/resources/images/form/slide-final-team.svg b/frontend/resources/images/form/slide-final-team.svg new file mode 100644 index 0000000000..48f2611188 --- /dev/null +++ b/frontend/resources/images/form/slide-final-team.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/src/app/main/ui/forms.cljs b/frontend/src/app/main/ui/forms.cljs index 67b56174ed..3999914cc4 100644 --- a/frontend/src/app/main/ui/forms.cljs +++ b/frontend/src/app/main/ui/forms.cljs @@ -5,13 +5,18 @@ ;; Copyright (c) KALEIDOS INC Sucursal en España SL (ns app.main.ui.forms + (:require-macros [app.main.style :as stl]) (:require [app.main.ui.ds.buttons.button :refer [button*]] + [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.ds.controls.input :refer [input*]] [app.main.ui.ds.controls.select :refer [select*]] + [app.main.ui.ds.foundations.assets.icon :as i] [app.util.dom :as dom] [app.util.forms :as fm] + [app.util.i18n :refer [tr]] [app.util.keyboard :as k] + [cuerdas.core :as str] [rumext.v2 :as mf])) (def context (mf/create-context nil)) @@ -49,8 +54,123 @@ [:> input* props])) +(defn- conj-dedup + "Adds item into a vector and removes possible duplicates." + [coll item] + (into [] (distinct) (conj coll item))) + +(mf/defc form-multi-input* + [{:keys [name trim valid-item-fn caution-item-fn] :rest props}] + (let [form (mf/use-ctx context) + + touched? (and (contains? (:data @form) name) + (get-in @form [:touched name])) + + value (mf/use-state "") + focus? (mf/use-state false) + + items + (mf/use-state + (fn [] + (let [initial (get-in @form [:data name])] + (if (or (vector? initial) (set? initial)) + (mapv (fn [val] + {:text val + :valid (valid-item-fn val) + :caution (caution-item-fn val)}) + initial) + [])))) + + on-focus + (mf/use-fn + #(reset! focus? true)) + + on-change + (mf/use-fn + (fn [event] + (let [content (-> event dom/get-target dom/get-input-value)] + (reset! value content)))) + + on-key-down + (mf/use-fn + (mf/deps @value form name valid-item-fn caution-item-fn trim) + (fn [event] + (let [val (cond-> @value trim str/trim)] + (cond + (or (k/enter? event) (k/comma? event) (k/space? event)) + (do + (dom/prevent-default event) + (dom/stop-propagation event) + (swap! form assoc-in [:touched name] true) + (when (and (valid-item-fn val) (not (str/empty? @value))) + (reset! value "") + (swap! form assoc-in [:touched name] false) + (doseq [v (str/split val #",|\s+")] + (let [v (str/trim v)] + (swap! items conj-dedup {:text v + :valid (valid-item-fn v) + :caution (caution-item-fn v)}))))) + + (and (k/backspace? event) (str/empty? @value)) + (do + (dom/prevent-default event) + (dom/stop-propagation event) + (swap! items (fn [items] + (if (empty? items) items (pop items))))))))) + + on-blur + (mf/use-fn + (fn [] + (reset! focus? false) + (when-not (get-in @form [:touched name]) + (swap! form assoc-in [:touched name] true)))) + + on-remove-item + (mf/use-fn + (fn [item] + (swap! items #(filterv (fn [x] (not= x item)) %)))) + + props + (mf/spread-props props {:value @value + :on-change on-change + :on-focus on-focus + :on-blur on-blur + :on-key-down on-key-down + :hint-type (when (and touched? + (not (str/empty? @value)) + (not (valid-item-fn @value))) "error")})] + + ;; Sync form data whenever items or input value changes. + ;; This ensures the current (unconfirmed) input value is included + ;; in the form data when the user submits without pressing Enter. + (mf/with-effect [@items @value] + (let [items-text (mapv :text @items) + val (cond-> @value trim str/trim) + combined (if (and (valid-item-fn val) (not (str/empty? val))) + (conj items-text val) + items-text) + data (str/join " " combined)] + (fm/update-input-value! form name data))) + + [:div {:class (stl/css :multi-input)} + [:> input* props] + + (when-let [items-seq (seq @items)] + [:div {:class (stl/css :multi-input-chips)} + (for [item items-seq] + [:div {:class (stl/css :multi-input-chip) + :key (:text item)} + [:span {:class (stl/css :multi-input-chip-text)} + (:text item)] + [:> icon-button* {:variant "ghost" + :class (stl/css :multi-input-chip-icon) + :icon i/close + :icon-size "s" + :aria-label (tr "labels.remove") + :on-click (partial on-remove-item item)}]])])])) + (mf/defc form-select* - [{:keys [name] :as props}] + [{:keys [name] :rest props}] (let [select-name name form (mf/use-ctx context) value (get-in @form [:data select-name] "") diff --git a/frontend/src/app/main/ui/forms.scss b/frontend/src/app/main/ui/forms.scss new file mode 100644 index 0000000000..c576dfcda2 --- /dev/null +++ b/frontend/src/app/main/ui/forms.scss @@ -0,0 +1,43 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) KALEIDOS INC Sucursal en España SL + +@use "ds/typography.scss" as t; +@use "ds/_borders.scss" as *; +@use "ds/_sizes.scss" as *; +@use "ds/_utils.scss" as *; + +.multi-input { + display: flex; + flex-direction: column; + gap: var(--sp-s); +} + +.multi-input-chips { + display: flex; + flex-wrap: wrap; + gap: var(--sp-xs); +} + +.multi-input-chip { + display: flex; + align-items: center; + gap: var(--sp-xs); + block-size: $sz-24; + padding-inline-start: var(--sp-s); + border-radius: $br-6; + background-color: var(--color-background-tertiary); +} + +.multi-input-chip-text { + @include t.use-typography("body-small"); + + color: var(--color-foreground-primary); +} + +.multi-input-chip-icon { + inline-size: $sz-24; + block-size: $sz-24; +} diff --git a/frontend/src/app/main/ui/onboarding/team_choice.cljs b/frontend/src/app/main/ui/onboarding/team_choice.cljs index af457b2dd3..95a626afa7 100644 --- a/frontend/src/app/main/ui/onboarding/team_choice.cljs +++ b/frontend/src/app/main/ui/onboarding/team_choice.cljs @@ -14,47 +14,60 @@ [app.main.data.profile :as du] [app.main.data.team :as dtm] [app.main.store :as st] - [app.main.ui.components.forms :as fm] - [app.main.ui.icons :as deprecated-icon] + [app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i] + [app.main.ui.ds.foundations.typography :as t] + [app.main.ui.ds.foundations.typography.heading :refer [heading*]] + [app.main.ui.ds.foundations.typography.text :refer [text*]] + [app.main.ui.forms :as fc] [app.main.ui.notifications.context-notification :refer [context-notification]] + [app.util.forms :as fm] [app.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) -(mf/defc left-sidebar* +(mf/defc team-info-feature* + {::mf/private true} + [{:keys [icon-id text]}] + [:li {:class (stl/css :modal-info-item)} + [:div {:class (stl/css :modal-info-icon)} + [:> icon* {:icon-id icon-id :size "m"}]] + [:> text* {:as "div" + :typography t/body-medium + :class (stl/css :color-light)} + text]]) + +(mf/defc team-info* {::mf/private true} [] - [:div {:class (stl/css :modal-left)} - [:h2 {:class (stl/css :modal-subtitle)} + [:div {:class (stl/css :modal-info)} + [:img {:src "images/form/slide-final-team.svg"}] + + [:> heading* {:level 2 + :typography t/title-medium + :class (stl/css :color-light)} (tr "onboarding.team-modal.team-definition")] - [:p {:class (stl/css :modal-text)} + + [:> text* {:as "div" + :typography t/body-medium + :class (stl/css :color-dimmed :margin-bottom)} (tr "onboarding.team-modal.create-team-desc")] - [:ul {:class (stl/css :team-features)} - [:li {:class (stl/css :feature)} - [:span {:class (stl/css :icon)} deprecated-icon/document] - [:p {:class (stl/css :modal-desc)} - (tr "onboarding.team-modal.create-team-feature-1")]] - [:li {:class (stl/css :feature)} - [:span {:class (stl/css :icon)} deprecated-icon/move] - [:p {:class (stl/css :modal-desc)} - (tr "onboarding.team-modal.create-team-feature-2")]] - [:li {:class (stl/css :feature)} - [:span {:class (stl/css :icon)} deprecated-icon/tree] - [:p {:class (stl/css :modal-desc)} - (tr "onboarding.team-modal.create-team-feature-3")]] - [:li {:class (stl/css :feature)} - [:span {:class (stl/css :icon)} deprecated-icon/user] - [:p {:class (stl/css :modal-desc)} - (tr "onboarding.team-modal.create-team-feature-4")]] - [:li {:class (stl/css :feature)} - [:span {:class (stl/css :icon)} deprecated-icon/tick] - [:p {:class (stl/css :modal-desc)} - (tr "onboarding.team-modal.create-team-feature-5")]]]]) + + [:ul {:class (stl/css :modal-info-features)} + [:> team-info-feature* {:icon-id i/document + :text (tr "onboarding.team-modal.create-team-feature-1")}] + [:> team-info-feature* {:icon-id i/move + :text (tr "onboarding.team-modal.create-team-feature-2")}] + [:> team-info-feature* {:icon-id i/tree + :text (tr "onboarding.team-modal.create-team-feature-3")}] + [:> team-info-feature* {:icon-id i/user + :text (tr "onboarding.team-modal.create-team-feature-4")}] + [:> team-info-feature* {:icon-id i/tick + :text (tr "onboarding.team-modal.create-team-feature-5")}]]]) (defn- get-available-roles [] - [{:value "viewer" :label (tr "labels.viewer")} - {:value "editor" :label (tr "labels.editor")} - {:value "admin" :label (tr "labels.admin")}]) + [{:id "viewer" :value "viewer" :label (tr "labels.viewer")} + {:id "editor" :value "editor" :label (tr "labels.editor")} + {:id "admin" :value "admin" :label (tr "labels.admin")}]) (def ^:private schema:team-form [:map {:title "TeamForm"} @@ -68,8 +81,8 @@ (let [initial (mf/with-memo [] {:role "editor"}) - form (fm/use-form :schema schema:team-form - :initial initial) + form (fm/use-form :schema schema:team-form + :initial initial) roles (mf/use-memo get-available-roles) @@ -109,7 +122,7 @@ :else (swap! error* (tr "errors.generic")))))) - on-invite-later + on-create-without-invitations (mf/use-fn (fn [{:keys [name]}] (let [mdata {:on-success on-success @@ -117,126 +130,122 @@ params {:name name}] (st/emit! (-> (dtm/create-team (with-meta params mdata)) (with-meta {::ev/origin :onboarding-without-invitations})) - (ev/event - {::ev/name "onboarding-step" - :label "team:create-team-and-invite-later" - :team-name name - :step 8}) - (ev/event - {::ev/name "onboarding-finish"}))))) + (ev/event {::ev/name "onboarding-step" + :label "team:create-team-and-invite-later" + :team-name name + :step 8}) + (ev/event {::ev/name "onboarding-finish"}))))) - on-invite-now + on-create-with-invitations (mf/use-fn (fn [{:keys [name emails] :as params}] (let [mdata {:on-success on-success :on-error on-error}] - (st/emit! (-> (dtm/create-team-with-invitations (with-meta params mdata)) (with-meta {::ev/origin :onboarding-with-invitations})) - (ev/event - {::ev/name "onboarding-step" - :label "team:create-team-and-invite" - :invites (count emails) - :team-name name - :role (:role params) - :step 8}) - (ev/event - {::ev/name "onboarding-finish"}))))) + (ev/event {::ev/name "onboarding-step" + :label "team:create-team-and-invite" + :invites (count emails) + :team-name name + :role (:role params) + :step 8}) + (ev/event {::ev/name "onboarding-finish"}))))) - on-submit* + on-submit (mf/use-fn (fn [form] (let [params (:clean-data @form) emails (:emails params)] (if (> (count emails) 0) - (on-invite-now params) - (on-invite-later params))))) + (on-create-with-invitations params) + (on-create-without-invitations params))))) on-skip (mf/use-fn (fn [] (st/emit! (du/update-profile-props {:onboarding-viewed true}) - (ev/event - {::ev/name "onboarding-step" - :label "team:skip-team-creation" - :step 7}) - (ev/event - {::ev/name "onboarding-finish"}))))] - [:* - [:div {:class (stl/css :modal-right)} - [:div {:class (stl/css :first-block)} - [:& fm/form {:form form - :class (stl/css :modal-form) - :on-submit on-submit*} - [:h2 {:class (stl/css :modal-subtitle)} - (tr "onboarding.team-modal.create-team")] - [:p {:class (stl/css :modal-text)} - (tr "onboarding.choice.team-up.create-team-desc")] + (ev/event {::ev/name "onboarding-step" + :label "team:skip-team-creation" + :step 7}) + (ev/event {::ev/name "onboarding-finish"}))))] + [:div {:class (stl/css :modal-team)} + [:> fc/form* {:form form + :class (stl/css :modal-team-form) + :on-submit on-submit} - [:& fm/input {:type "text" - :class (stl/css :team-name-input) - :name :name - :auto-focus? true - :placeholder "Team name" - :label (tr "onboarding.choice.team-up.create-team-placeholder")}] + [:div {:class (stl/css :modal-team-block)} + [:> heading* {:level 2 + :typography t/title-medium + :class (stl/css :color-light)} + (tr "onboarding.team-modal.create-team")] - [:h2 {:class (stl/css :modal-subtitle :invite-subtitle)} (tr "onboarding.choice.team-up.invite-members")] - [:p {:class (stl/css :modal-text)} (tr "onboarding.choice.team-up.invite-members-info")] + [:> fc/form-input* {:type "text" + :name :name + :auto-focus true + :auto-complete "off" + :placeholder (tr "onboarding.choice.team-up.create-team-placeholder")}] - (when-let [content (deref error*)] - [:& context-notification {:content content :level :error}]) + [:> text* {:as "div" + :typography t/body-small + :class (stl/css :color-dimmed)} + (tr "onboarding.choice.team-up.create-team-desc")]] - [:div {:class (stl/css :role-select)} - [:p {:class (stl/css :role-title)} (tr "onboarding.choice.team-up.roles")] - [:& fm/select {:name :role :options roles}]] + [:div {:class (stl/css :modal-team-block)} + [:> heading* {:level 2 + :typography t/title-medium + :class (stl/css :color-light)} + (tr "onboarding.choice.team-up.invite-members")] - [:div {:class (stl/css :invitation-row)} - [:& fm/multi-input {:type "email" - :name :emails - :trim true - :valid-item-fn sm/parse-email - :caution-item-fn #{} - :label (tr "modals.invite-member.emails")}]] + (when-let [content (deref error*)] + [:& context-notification {:content content :level :error}]) + [:div {:class (stl/css :modal-team-sub-block)} + [:> fc/form-select* {:name :role + :options roles}] + [:> fc/form-multi-input* {:type "email" + :name :emails + :trim true + :valid-item-fn sm/parse-email + :caution-item-fn #{} + :auto-complete "off" + :placeholder (tr "modals.invite-member.emails")}]] + [:> text* {:as "div" + :typography t/body-small + :class (stl/css :color-dimmed)} + (tr "onboarding.choice.team-up.invite-members-info")] - (let [params (:clean-data @form) - emails (:emails params)] - [:* - [:div {:class (stl/css :action-buttons)} + (let [params (:clean-data @form) + emails (:emails params)] + [:* + [:div {:class (stl/css :flex-align-right)} + [:> fc/form-submit* {:variant "primary"} + (if (> (count emails) 0) + (tr "onboarding.choice.team-up.create-team-and-invite") + (tr "onboarding.choice.team-up.create-team-without-invite"))]] - [:> fm/submit-button* - {:class (stl/css :accept-button) - :label (if (> (count emails) 0) - (tr "onboarding.choice.team-up.create-team-and-invite") - (tr "onboarding.choice.team-up.create-team-without-invite"))}]] + (when (= (count emails) 0) + [:> text* {:as "p" + :typography t/body-small + :class (stl/css :color-dimmed :text-align-right)} + "(" (tr "onboarding.choice.team-up.create-team-and-send-invites-description") ")"])])]] - (when (= (count emails) 0) - [:> :div {:class (stl/css :modal-hint)} - "(" (tr "onboarding.choice.team-up.create-team-and-send-invites-description") ")"])])]] - - [:div {:class (stl/css :second-block)} - [:h2 {:class (stl/css :modal-subtitle)} - (tr "onboarding.choice.team-up.start-without-a-team")] - [:p {:class (stl/css :modal-text)} - (tr "onboarding.choice.team-up.start-without-a-team-description")] - - [:div {:class (stl/css :action-buttons)} - [:button {:class (stl/css :accept-button) - :on-click on-skip} - (tr "onboarding.choice.team-up.continue-without-a-team")]]]]])) + [:> text* {:as "div" + :typography t/headline-small + :class (stl/css :link) + :on-click on-skip} + (tr "onboarding.choice.team-up.continue-without-a-team")]])) (mf/defc onboarding-team-modal* [{:keys [go-to-team]}] - - [:div {:class (stl/css-case - :modal-overlay true)} - + [:div {:class (stl/css-case :modal-overlay true)} [:div.animated.fade-in {:class (stl/css :modal-container)} - [:h1 {:class (stl/css :modal-title)} + [:> heading* {:level 1 + :typography t/title-large + :class (stl/css :color-light)} (tr "onboarding-v2.welcome.title")] [:div {:class (stl/css :modal-sections)} - [:> left-sidebar*] - [:div {:class (stl/css :separator)}] + [:> team-info*] + [:div {:class (stl/css :modal-separator)} + [:div {:class (stl/css :modal-separator-line)}]] [:> team-form* {:go-to-team go-to-team}]]]]) - diff --git a/frontend/src/app/main/ui/onboarding/team_choice.scss b/frontend/src/app/main/ui/onboarding/team_choice.scss index 5c8c4c78d9..a8b45bc983 100644 --- a/frontend/src/app/main/ui/onboarding/team_choice.scss +++ b/frontend/src/app/main/ui/onboarding/team_choice.scss @@ -6,215 +6,131 @@ @use "refactor/common-refactor.scss" as deprecated; +@use "ds/_borders.scss" as *; +@use "ds/_sizes.scss" as *; +@use "ds/_utils.scss" as *; + +.color-light { + color: var(--color-foreground-primary); +} + +.color-dimmed { + color: var(--color-foreground-secondary); +} + +.text-align-right { + text-align: right; +} + +.flex-align-right { + display: flex; + justify-content: flex-end; +} + +.margin-bottom { + margin-bottom: var(--sp-xxl); +} + +.link { + cursor: pointer; + text-decoration: underline; + text-align: center; + color: var(--color-foreground-secondary); + + &:hover { + color: var(--color-foreground-primary); + } +} + .modal-overlay { @extend %modal-overlay-base; } .modal-container { - position: relative; - width: deprecated.$s-908; - max-height: deprecated.$s-800; - height: 100%; - padding-inline: deprecated.$s-100; - padding-block: deprecated.$s-40 deprecated.$s-40; - border-radius: deprecated.$br-8; - background-color: var(--modal-background-color); - border: deprecated.$s-2 solid var(--modal-border-color); display: flex; flex-direction: column; - gap: deprecated.$s-24; + gap: var(--sp-xxl); + position: relative; + inline-size: px2rem(908); + padding: $sz-64 px2rem(100); + border-radius: $br-8; + background-color: var(--color-background-primary); + border: $b-2 solid var(--color-background-quaternary); } .modal-sections { display: grid; - grid-template-columns: 1fr deprecated.$s-32 1fr; - gap: deprecated.$s-24; - height: 100%; - overflow: hidden; + grid-template-columns: px2rem(310) $sz-32 1fr; + gap: var(--sp-xxl); + block-size: 100%; } -.paginator { - @include deprecated.body-small-typography; - - position: absolute; - top: deprecated.$s-40; - right: deprecated.$s-100; - padding: deprecated.$s-4; - border-radius: deprecated.$br-6; - color: var(--color-foreground-secondary); +.modal-info { + display: flex; + flex-direction: column; + gap: var(--sp-xl); + border: $b-1 solid var(--color-foreground-secondary); + padding: var(--sp-m); + border-radius: $br-12; + background-color: var(--color-background-quaternary); } -// MODAL LEFT -.modal-left { +.modal-info-features { + display: flex; + flex-direction: column; + gap: var(--sp-m); +} + +.modal-info-item { + display: flex; + align-items: center; + gap: var(--sp-l); +} + +.modal-info-icon { + display: flex; + align-items: center; + justify-content: center; + inline-size: $sz-32; + block-size: $sz-32; + border-radius: $br-circle; + border: $b-1 solid var(--color-accent-primary); + color: var(--color-accent-primary); +} + +.modal-separator { + display: flex; + justify-content: center; +} + +.modal-separator-line { + inline-size: px2rem(8); + block-size: 100%; + border-radius: $br-8; + opacity: 0.5; + background-color: var(--color-background-quaternary); +} + +.modal-team { + display: flex; + flex-direction: column; + gap: var(--sp-xl); +} + +.modal-team-form { display: grid; grid-template-columns: 1fr; - grid-template-rows: deprecated.$s-32 auto auto 1fr; - gap: deprecated.$s-16; - overflow: auto; + gap: var(--sp-xxl); } -.modal-title { - @include deprecated.big-title-typography; - - color: var(--modal-title-foreground-color); +.modal-team-block { + display: flex; + flex-direction: column; + gap: var(--sp-m); } -.modal-subtitle { - @include deprecated.med-title-typography; - - color: var(--modal-title-foreground-color); -} - -.invite-subtitle { - padding-top: deprecated.$s-16; -} - -.modal-text { - @include deprecated.body-large-typography; - - color: var(--modal-text-foreground-color); - margin: 0; -} - -.modal-desc { - @include deprecated.small-title-typography; - - margin: 0; - color: var(--modal-title-foreground-color); -} - -.team-features { - @include deprecated.flex-column; - - gap: deprecated.$s-16; - margin: 0; -} - -.feature { - @include deprecated.flex-row; - - gap: deprecated.$s-16; -} - -.icon { - @include deprecated.flex-center; - - height: deprecated.$s-32; - width: deprecated.$s-32; - border-radius: deprecated.$br-circle; - border: deprecated.$s-1 solid var(--color-accent-primary); - - svg { - @extend %button-icon; - - stroke: var(--color-accent-primary); - } -} - -.action-buttons { - @extend %modal-action-btns; - - justify-content: flex-end; -} - -.accept-button { - @extend %modal-accept-btn; -} - -.back-button { - @extend %modal-cancel-btn; -} - -// SEPARATOR -.separator { - width: deprecated.$s-8; - height: 100%; - border-radius: deprecated.$br-8; - opacity: 0.42; - background-color: var(--modal-separator-background-color); -} - -// MODAL RIGHT TEAM -.modal-right { - display: grid; - grid-template-columns: 1fr; - grid-template-rows: 1fr auto; - gap: deprecated.$s-24; - overflow: hidden; -} - -.first-block { - overflow: auto; - flex-grow: 1; -} - -.first-block, -.second-block { - @include deprecated.flex-column; - - gap: deprecated.$s-16; -} - -.modal-form { - display: grid; - grid-template-columns: 1fr; - gap: deprecated.$s-16; -} - -.team-name-input { - @extend %input-element-label; - - label { - @include deprecated.flex-column; - @include deprecated.body-small-typography; - - align-items: flex-start; - width: 100%; - border: none; - background-color: transparent; - height: 100%; - - input { - @include deprecated.body-small-typography; - - margin-top: deprecated.$s-8; - } - } -} - -// MODAL RIGHT INVITATIONS - -.modal-right-invitations { - display: grid; - grid-template-columns: 1fr; - grid-template-rows: auto auto 1fr; - gap: deprecated.$s-16; - max-height: deprecated.$s-512; -} - -.modal-form-invitations { - display: grid; - grid-template-columns: 1fr; - grid-template-rows: auto 1fr auto auto; - margin-block-end: deprecated.$s-72; - gap: deprecated.$s-8; -} - -.role-title { - @include deprecated.uppercase-title-typography; - - margin-block-end: deprecated.$s-8; - color: var(--modal-title-foreground-color); -} - -.invitation-row { - margin: 0; - color: var(--modal-title-foreground-color); -} - -.modal-hint { - @include deprecated.body-small-typography; - - color: var(--modal-text-foreground-color); - text-align: right; +.modal-team-sub-block { + display: flex; + flex-direction: column; + gap: var(--sp-s); }