gatsby-core-theme 30.0.110 → 30.0.111

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ ## [30.0.111](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/compare/v30.0.110...v30.0.111) (2024-04-16)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add newsletter core theme ([2d3a306](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/2d3a3066ca41c1fd4e1656f15f3832db7342a897))
7
+ * add required for checkbox, and generator for [link] ([91c419a](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/91c419aa6330467b9d183704c944c643ed2b8243))
8
+ * fix conflicts ([40aced4](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/40aced4b53fef6592787289805908d562b2aff2f))
9
+ * fix test and make style ([54b61c0](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/54b61c02a4a0b3e03d72192c75977fdeef199b28))
10
+ * fixed website icon ([d31a54d](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/d31a54dc14032e7d15ad79969e535f0ceef019f9))
11
+ * isSticky false ([c3e75cb](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/c3e75cb77a97547119a7dabb869ad129b7b23365))
12
+ * make logic ([c224482](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/c224482ea4aded40e80afa6dfbd66d0a75f4cb93))
13
+ * make style ([49f4151](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/49f4151df040fe3863e782d3069d4b9df5b38ad7))
14
+ * refactor ([470107c](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/470107cb1e586dfb21f3055c7d1a849fd86aa306))
15
+ * refactor ([4c66524](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/4c66524e37939b70d0b8552b9bedbd5bc1ab9753))
16
+ * refactor ([3d5370c](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/3d5370c739ab93506126184d1f49e44d86f96755))
17
+ * refactor form component ([661c828](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/661c8288af8c7dd1a0c6a794b2bc0abf889424f8))
18
+ * reuse the form component ([60b09ef](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/60b09ef4ad4d10684a2dbc8f77d2a303f2d88992))
19
+
20
+
21
+ * Merge branch 'tm-4099-newsletter' into 'master' ([56bdefb](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/56bdefbe9561bb3f318bc31ed89892a94cbcda68))
22
+ * Merge branch 'tm-4215-website-icon' into 'master' ([7f336b3](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/7f336b3362ef69ba06078940a300c7edd6c37a4b))
23
+ * Merge branch 'master' into 'tm-4099-newsletter' ([7b1fa8d](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/commit/7b1fa8df697c73093b93703d85354f71c15c89d5))
24
+
1
25
  ## [30.0.110](https://git.ilcd.rocks/team-floyd/themes/gatsby-themes/compare/v30.0.109...v30.0.110) (2024-04-11)
2
26
 
3
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-core-theme",
3
- "version": "30.0.110",
3
+ "version": "30.0.111",
4
4
  "description": "Gatsby Theme NPM Package",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -4,6 +4,7 @@ import { FaFacebookSquare } from '@react-icons/all-files/fa/FaFacebookSquare';
4
4
  import { IoLogoTiktok } from '@react-icons/all-files/io5/IoLogoTiktok';
5
5
  import { FaLinkedin } from '@react-icons/all-files/fa/FaLinkedin';
6
6
  import { FaWikipediaW } from '@react-icons/all-files/fa/FaWikipediaW';
7
+ import { FaGlobeAmericas } from '@react-icons/all-files/fa/FaGlobeAmericas';
7
8
  import { FaRegEnvelope } from '@react-icons/all-files/fa/FaRegEnvelope';
8
9
 
9
10
  export const TwitterIcon = () => (
@@ -25,6 +26,7 @@ const socialIcons = {
25
26
  twitter: <TwitterIcon />,
26
27
  tiktok: <IoLogoTiktok title="Tiktok Icon" />,
27
28
  wikipedia: <FaWikipediaW title="Wikipedia" />,
29
+ website: <FaGlobeAmericas title="Website" />,
28
30
  message: <FaRegEnvelope title="Envelope icon" />,
29
31
  };
30
32
 
@@ -34,6 +36,6 @@ export default (author) => [
34
36
  { id: 'li', link: author?.linkedin_profile, icon: socialIcons?.linkedin },
35
37
  { id: 'tw', link: author?.twitter_profile, icon: socialIcons?.twitter },
36
38
  { id: 'tt', link: author?.tik_tok, icon: socialIcons?.tiktok },
37
- { id: 'wk', link: author?.personal_website, icon: socialIcons?.wikipedia },
39
+ { id: 'ws', link: author?.personal_website, icon: socialIcons?.website },
38
40
  { id: 'em', link: author?.email_address, icon: socialIcons?.message },
39
41
  ];
@@ -0,0 +1,45 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { MdClose } from '@react-icons/all-files/md/MdClose';
4
+ import styles from './modal.module.scss';
5
+
6
+ const Modal = ({ children }) => {
7
+ const [show, setShow] = useState(false);
8
+
9
+ useEffect(() => {
10
+ setShow(!show);
11
+ // eslint-disable-next-line react-hooks/exhaustive-deps
12
+ }, []);
13
+
14
+ const handelClose = (e) => {
15
+ if (e.target.className === styles.modal) {
16
+ setShow(false);
17
+ }
18
+ };
19
+
20
+ if (show) {
21
+ return (
22
+ <div
23
+ role="button"
24
+ aria-hidden="true"
25
+ onClick={(e) => handelClose(e)}
26
+ className={`${styles?.modal || ''}`}
27
+ >
28
+ <div className={styles?.success || ''}>
29
+ {children}
30
+ <MdClose
31
+ className={styles?.closeBtn || ''}
32
+ onClick={() => setShow(false)}
33
+ title="Close Icon"
34
+ />
35
+ </div>
36
+ </div>
37
+ );
38
+ }
39
+
40
+ return <></>;
41
+ };
42
+ Modal.propTypes = {
43
+ children: PropTypes.node,
44
+ };
45
+ export default Modal;
@@ -0,0 +1,47 @@
1
+ .modal {
2
+ position: fixed;
3
+ top: 0;
4
+ left: 0;
5
+ width: 100%;
6
+ height: 100%;
7
+ background: rgba(0, 0, 0, 0.6);
8
+ z-index: 9999;
9
+ @include flex-align(center, center);
10
+ .success {
11
+ position: fixed;
12
+ background: #fff;
13
+ border-radius: 0.6rem;
14
+ height: auto;
15
+ width: 90%;
16
+ top: 30%;
17
+ left: 50%;
18
+ transform: translate(-50%, -50%);
19
+ padding: 2rem;
20
+ @include flex-align(center, center);
21
+ @include flex-direction(column);
22
+ @include min(tablet) {
23
+ width: 40%;
24
+ top: 50%;
25
+ }
26
+ .closeBtn {
27
+ position: absolute;
28
+ top: 1rem;
29
+ right: 1rem;
30
+ cursor: pointer;
31
+ }
32
+ svg {
33
+ width: 2.6rem;
34
+ height: 2.6rem;
35
+ }
36
+ p {
37
+ font-weight: 700;
38
+ }
39
+ div {
40
+ padding-top: 1rem;
41
+ p {
42
+ padding-top: 2.45rem;
43
+ font-weight: 700;
44
+ }
45
+ }
46
+ }
47
+ }
@@ -1,20 +1,40 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import loadable from '@loadable/component';
4
+ import { getURLParam } from 'gatsby-core-theme/src/helpers/getters';
4
5
  import Module from '~molecules/module';
5
6
  import styles from './main.module.scss';
6
7
  import keygen from '~helpers/keygen';
8
+ import settings from '../../../constants/settings.mjs';
7
9
  import { isSearchPath } from '~helpers/isSearchPath';
8
10
 
9
- const Main = ({ section = {}, pageContext = {}, serverData = {}, exclOperator = false }) => {
11
+ const Main = ({
12
+ section = {},
13
+ pageContext = {},
14
+ serverData = {},
15
+ exclOperator = false,
16
+ exclNewsletter = false,
17
+ }) => {
10
18
  const { page, allMarkets } = pageContext;
11
-
19
+ const siteName = process.env.GATSBY_SITE_NAME;
20
+ const showNewsletter =
21
+ !(
22
+ settings.newsletter[siteName]?.filter_pages?.includes('*') ||
23
+ settings.newsletter[siteName]?.filter_pages?.includes(page?.relation_type) ||
24
+ settings.newsletter.default?.filter_pages?.includes(page?.relation_type) ||
25
+ exclNewsletter
26
+ ) && !process.env?.HIDE_NEWSLETTER;
12
27
  const pathPrefixes = isSearchPath(allMarkets, page.path);
13
28
 
14
29
  const SearchPage = pathPrefixes ? loadable(() => import(`~pages/search`)) : null;
15
30
  const HtmlSitemap = pageContext.sitemapData ? loadable(() => import(`~atoms/sitemap`)) : null;
16
31
  const AuthorBox = page.author_id ? loadable(() => import(`~atoms/author-box`)) : null;
17
32
  const NotFound = page?.path?.includes('404') ? loadable(() => import(`~atoms/not-found`)) : null;
33
+ const Newsletter = showNewsletter ? loadable(() => import('~molecules/newsletter')) : null;
34
+ const NewsletterSuccess =
35
+ showNewsletter && typeof window !== 'undefined' && Boolean(getURLParam('subscribed'))
36
+ ? loadable(() => import(`../newsletter/success`))
37
+ : null;
18
38
 
19
39
  return (
20
40
  <main className={styles.modulePage || ''}>
@@ -41,6 +61,8 @@ const Main = ({ section = {}, pageContext = {}, serverData = {}, exclOperator =
41
61
  />
42
62
  )}
43
63
  {SearchPage && <SearchPage page={page} />}
64
+ {Newsletter && <Newsletter page={page} />}
65
+ {NewsletterSuccess && <NewsletterSuccess />}
44
66
  </main>
45
67
  );
46
68
  };
@@ -59,6 +81,7 @@ Main.propTypes = {
59
81
  pageContext: PropTypes.shape({}),
60
82
  serverData: PropTypes.shape({}),
61
83
  exclOperator: PropTypes.bool,
84
+ exclNewsletter: PropTypes.bool,
62
85
  };
63
86
 
64
87
  export default Main;
@@ -0,0 +1,92 @@
1
+ /* eslint-disable no-unused-expressions */
2
+
3
+ import React, { useState, useEffect, useContext } from 'react';
4
+ import PropTypes from 'prop-types';
5
+ import { Context } from 'gatsby-core-theme/src/context/MainProvider';
6
+ import { translate } from 'gatsby-core-theme/src/helpers/getters';
7
+ import Form from '../../../organisms/form';
8
+ import { newsLetterForm } from '../../../../constants/forms';
9
+
10
+ const NewsletterForm = ({ handleApi, redirectUrl, submitText = 'Submit', market }) => {
11
+ const [ip, setIP] = useState('');
12
+ const [error, setError] = useState(false);
13
+ const { translations } = useContext(Context) || {};
14
+
15
+ const getData = async () => {
16
+ await fetch('https://geolocation-db.com/json/', {
17
+ method: 'GET',
18
+ })
19
+ .then((response) => response.json())
20
+ .then((data) => setIP(data.IPv4))
21
+ .catch((err) => {
22
+ // console.log(`Error ${err}`);
23
+ });
24
+ };
25
+
26
+ useEffect(() => {
27
+ getData();
28
+ }, []);
29
+
30
+ const bacomApi = async (name, email, phomeNumber) => {
31
+ // eslint-disable-next-line no-bitwise
32
+ const timestamp = (Date.now() / 1000) | 0;
33
+ const refUrl = process.env.BACOM_REF_URL;
34
+ await fetch(
35
+ `https://bacom.dk/subscribe/gig/?firstname=${name}&user_ip=${ip}&ref_name=${
36
+ process.env.BACOM_REF_NAME
37
+ }&ref_url=${refUrl}&timestamp=${timestamp}&country=${process.env.COUNTRY}&email=${email}${
38
+ phomeNumber && `&phone_number=${phomeNumber}`
39
+ }`,
40
+ {
41
+ method: 'GET',
42
+ headers: {
43
+ 'Content-Type': 'application/json',
44
+ Accept: 'application/json',
45
+ },
46
+ }
47
+ ).then((res) =>
48
+ res.text().then((text) => {
49
+ text === 'OK' ? (window.location.href = redirectUrl) : setError(true);
50
+ })
51
+ );
52
+ };
53
+
54
+ const handelSubmit = (e) =>
55
+ handleApi
56
+ ? handleApi(e.name.value, e.email.value, ip)
57
+ : bacomApi(e.name.value, e.email.value, e.phomeNumber.value);
58
+
59
+ if (error)
60
+ return (
61
+ <span>
62
+ {translate(
63
+ translations,
64
+ 'fail_error_newsletter',
65
+ 'Something went wrong. Please try again later!'
66
+ )}{' '}
67
+ </span>
68
+ );
69
+
70
+ return (
71
+ <Form
72
+ formOptions={newsLetterForm[market] || newsLetterForm.default}
73
+ successMessage={translate(translations, 'newsletter_form_thanks', '')}
74
+ failMessage={translate(
75
+ translations,
76
+ 'fail_error_newsletter',
77
+ 'Something went wrong. Please try again later!'
78
+ )}
79
+ customeSubmit={handelSubmit}
80
+ customError
81
+ buttonLabel={submitText}
82
+ />
83
+ );
84
+ };
85
+ NewsletterForm.propTypes = {
86
+ handleApi: PropTypes.func,
87
+ redirectUrl: PropTypes.string,
88
+ submitText: PropTypes.string,
89
+ market: PropTypes.string,
90
+ };
91
+
92
+ export default NewsletterForm;
@@ -0,0 +1,72 @@
1
+ import React, { useState, useContext } from 'react';
2
+ import { MdClose } from '@react-icons/all-files/md/MdClose';
3
+ import PropTypes from 'prop-types';
4
+ import { Context } from 'gatsby-core-theme/src/context/MainProvider';
5
+ import { translate, getUrl } from 'gatsby-core-theme/src/helpers/getters';
6
+ import Button from './toggle-button/index';
7
+ import NewsletterForm from './form/index';
8
+ import styles from './newsletter.module.scss';
9
+
10
+ const Newsletter = ({ page, openBtnText = 'Unlock Bonuses', isSticky = true }) => {
11
+ const [toggleNewsetter, setToggleNewsletter] = useState(false);
12
+ const { translations } = useContext(Context) || {};
13
+ const redirectUrl =
14
+ page?.path === '/'
15
+ ? `${getUrl(page?.path)}?subscribed=true`
16
+ : `${getUrl(page?.path)}/?subscribed=true`;
17
+
18
+ const statesCombined = () => {
19
+ setToggleNewsletter(!toggleNewsetter);
20
+ };
21
+
22
+ return (
23
+ <>
24
+ {toggleNewsetter && (
25
+ <div
26
+ className={styles?.layer || ''}
27
+ onClick={() => setToggleNewsletter(false)}
28
+ aria-hidden="true"
29
+ />
30
+ )}
31
+ <div className={!isSticky ? styles.contentPage || '' : styles.content || ''}>
32
+ {isSticky && (
33
+ <Button
34
+ active={!toggleNewsetter}
35
+ text={translate(translations, 'newsletter_open_btn', openBtnText)}
36
+ toggleNewsLetter={statesCombined}
37
+ gtmClass="newsletter-gtm btn-cta"
38
+ />
39
+ )}
40
+ <div
41
+ className={
42
+ !isSticky
43
+ ? styles?.formPage || ''
44
+ : `${styles?.form || ''} ${toggleNewsetter ? styles?.active || '' : ''}`
45
+ }
46
+ >
47
+ <NewsletterForm market={page?.market} redirectUrl={redirectUrl} />
48
+ {isSticky && (
49
+ <MdClose
50
+ className={styles?.closeBtn || ''}
51
+ onClick={() => setToggleNewsletter(false)}
52
+ title="Close Icon"
53
+ />
54
+ )}
55
+ </div>
56
+ </div>
57
+ </>
58
+ );
59
+ };
60
+
61
+ Newsletter.propTypes = {
62
+ openBtnText: PropTypes.string,
63
+ page: PropTypes.shape({
64
+ path: PropTypes.string,
65
+ template: PropTypes.string,
66
+ type: PropTypes.string,
67
+ market: PropTypes.string,
68
+ }),
69
+ isSticky: PropTypes.bool,
70
+ };
71
+
72
+ export default Newsletter;
@@ -0,0 +1,82 @@
1
+ .content {
2
+ margin: 0 auto;
3
+ @include min(tablet) {
4
+ .active {
5
+ width: 70rem;
6
+ left: 2rem;
7
+ z-index: 15;
8
+ }
9
+ }
10
+ @include max(mobile) {
11
+ .active {
12
+ bottom: 30%;
13
+ }
14
+ }
15
+ }
16
+ .layer {
17
+ position: absolute;
18
+ width: 100vw;
19
+ height: 100vh;
20
+ top: 0;
21
+ }
22
+ .form {
23
+ position: fixed;
24
+ background: #fff;
25
+ box-shadow: 0 0.4rem 1.6rem rgba(0, 0, 0, 0.2);
26
+ border-radius: 0.4rem;
27
+ padding: 2rem;
28
+ transition: 0s;
29
+ bottom: -100%;
30
+ z-index: var(--scroll-to-top-index);
31
+ @include min(tablet) {
32
+ @include flex-direction(column);
33
+ left: -90rem;
34
+ max-width: 90rem;
35
+ height: fit-content;
36
+ top: 25vh;
37
+ position: fixed;
38
+ }
39
+ }
40
+
41
+ .closeBtn {
42
+ position: absolute;
43
+ right: 1rem;
44
+ top: 1rem;
45
+ width: 2.5rem;
46
+ height: 2.5rem;
47
+ cursor: pointer;
48
+ z-index: 2;
49
+ border: none;
50
+ color: #00889e;
51
+ }
52
+ .contentPage {
53
+ padding: 3.2rem 1.6rem;
54
+ width: 100%;
55
+ background: var(--newsletter-container-background-color);
56
+ z-index: var(--scroll-to-top-index);
57
+ max-width: 100rem;
58
+ margin: 0 auto;
59
+ }
60
+
61
+ .form{
62
+ // form style
63
+ >div{
64
+ background: transparent;
65
+ box-shadow: none;
66
+ h2{
67
+
68
+ }
69
+ p{
70
+
71
+ }
72
+ form{
73
+
74
+ label{
75
+
76
+ }
77
+ input{
78
+
79
+ }
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,49 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
+ import React from 'react';
3
+ import {
4
+ Title,
5
+ Description,
6
+ Primary,
7
+ PRIMARY_STORY,
8
+ ArgsTable,
9
+ } from '@storybook/addon-docs/blocks';
10
+ import { newsLetterForm } from '../../../constants/forms';
11
+
12
+ import Newsletter from '.';
13
+
14
+ export default {
15
+ title: 'Theme/Layout/Newsletter/Newsletter',
16
+ component: Newsletter,
17
+ argTypes: {
18
+ page: {
19
+ name: 'page',
20
+ type: { name: 'object', required: true },
21
+ defaultValue: null,
22
+ description: 'The page object.',
23
+ },
24
+ },
25
+ parameters: {
26
+ docs: {
27
+ description: {
28
+ component: 'Newsletter component',
29
+ },
30
+ page: () => (
31
+ <>
32
+ <Title />
33
+ <Description />
34
+ <Primary />
35
+ <ArgsTable story={PRIMARY_STORY} />
36
+ </>
37
+ ),
38
+ },
39
+ },
40
+ };
41
+
42
+ const Template = (args) => <Newsletter {...args} isSticky={false} />;
43
+
44
+ export const Default = Template.bind({});
45
+ Default.args = {
46
+ page: {},
47
+ ...newsLetterForm.default,
48
+ openBtnText: 'Unlock Bonuses',
49
+ };
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { IoMdCheckmarkCircleOutline } from '@react-icons/all-files/io/IoMdCheckmarkCircleOutline';
3
+
4
+ import Modal from '~atoms/modal';
5
+
6
+ const index = ({
7
+ text = {
8
+ title: 'You are registered!!!',
9
+ section: 'Now there are lots of extra goodies that are on their way to your inbox.',
10
+ footer: 'All the best and good luck in the casino world!',
11
+ },
12
+ }) => (
13
+ <Modal>
14
+ <IoMdCheckmarkCircleOutline color="green" title="Check Icon" />
15
+ <p>{text.title}</p>
16
+ <div>
17
+ {text.section}
18
+ <p>{text.footer}</p>
19
+ </div>
20
+ </Modal>
21
+ );
22
+
23
+ export default index;
@@ -0,0 +1,26 @@
1
+ /* eslint-disable react/button-has-type */
2
+ /* eslint-disable arrow-body-style */
3
+ /* eslint-disable import/no-extraneous-dependencies */
4
+ import React from 'react';
5
+ import PropTypes from 'prop-types';
6
+
7
+ import styles from './newsletter-button.module.scss';
8
+
9
+ const NewsletterButton = ({ text = 'Bonus alert', toggleNewsLetter, active = true }) => {
10
+ return (
11
+ <button
12
+ onClick={toggleNewsLetter}
13
+ className={`${styles?.button || ''} ${active ? styles.active || '' : ''}`}
14
+ >
15
+ {text}
16
+ </button>
17
+ );
18
+ };
19
+
20
+ NewsletterButton.propTypes = {
21
+ text: PropTypes.string,
22
+ toggleNewsLetter: PropTypes.bool,
23
+ active: PropTypes.bool,
24
+ };
25
+
26
+ export default NewsletterButton;
@@ -0,0 +1,33 @@
1
+ .button {
2
+ border: none;
3
+ background-color: #00889e;
4
+ padding: 1rem;
5
+ color: white;
6
+ border-radius: 0 0.5rem 0.5rem 0;
7
+ position: fixed;
8
+ z-index: var(--scroll-to-top-index);
9
+ }
10
+ @include max(mobile) {
11
+ .button {
12
+ bottom: -70rem;
13
+ width: 100%;
14
+ }
15
+ .active {
16
+ border-radius: 0;
17
+ bottom: 0;
18
+ }
19
+ }
20
+ .active {
21
+ transition: 0s;
22
+ }
23
+
24
+ @include min(tablet) {
25
+ .button {
26
+ width: 15rem;
27
+ left: -70rem;
28
+ top: 50vh;
29
+ }
30
+ .active {
31
+ left: 0;
32
+ }
33
+ }
@@ -0,0 +1,41 @@
1
+
2
+ .radioGroup,
3
+ .checkboxGroup,
4
+ .textareaGroup {
5
+ @include flex-direction(column);
6
+
7
+ > div {
8
+ @include flex-align(center, flex-start);
9
+ gap: 0.8rem;
10
+ font-weight: normal;
11
+ }
12
+
13
+ label {
14
+ font-weight: 400;
15
+ color: #3c3c40;
16
+
17
+ > a {
18
+ color: #165af8;
19
+ text-decoration: underline;
20
+ font-weight: 500;
21
+ }
22
+ }
23
+ }
24
+
25
+ .textareaGroup {
26
+ @include flex-align(flex-end, flex-start);
27
+
28
+ > span {
29
+ font-size: 1.4rem;
30
+ font-weight: 400;
31
+ line-height: 2.2rem;
32
+ }
33
+ }
34
+
35
+ .rangeValues {
36
+ @include flex-align(center, space-between);
37
+
38
+ .invalid {
39
+ color: var(--color-39, 'red');
40
+ }
41
+ }