Merge pull request #13739 from mozilla/13492.FXA-5454

refactor(css): Tailwindify Sync + other content-server flows w/design tweaks
This commit is contained in:
Lauren Zugai 2022-07-29 18:03:11 -05:00 коммит произвёл GitHub
Родитель a91ae90549 c23113d2a1
Коммит 2b390ba7dc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
91 изменённых файлов: 830 добавлений и 773 удалений

Просмотреть файл

@ -51,6 +51,12 @@ This package uses Selenium to perform functional tests. By default `npm test` wi
npm run test -- --grep="change password, sign in with new password"
```
If you need to run tests for a particular suite, you can like so:
```bash
node tests/intern.js --suites=server --grep='check resources entrained by /signin in all locales'
```
#### Changing the Auth Server
To change the default Auth Server edit `server/config/*.json` on your deployed instance.

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

До

Ширина:  |  Высота:  |  Размер: 6.2 KiB

После

Ширина:  |  Высота:  |  Размер: 6.2 KiB

Просмотреть файл

@ -1,14 +1,14 @@
<div id="main-content" class="card">
<header>
<h1 id="fxa-cannot-create-account-header">{{#t}}Cannot create account{{/t}}</h1>
<div class="card">
<header class="mb-4">
<h1 id="fxa-cannot-create-account-header" class="card-header">{{#t}}Cannot create account{{/t}}</h1>
</header>
<section class="cannot-create-account-content">
<section>
<p>
{{#unsafeTranslate}}You must meet certain age requirements to create a Firefox&nbsp;account.{{/unsafeTranslate}}
</p>
<p class="links">
<a class="ftc" href="https://www.ftc.gov/tips-advice/business-center/privacy-and-security/children%27s-privacy" {{#isSync}} target="_blank"{{/isSync}}>{{#t}}Learn more{{/t}}</a>
<p class="mt-9">
<a id="ftc" class="link-blue" href="https://www.ftc.gov/tips-advice/business-center/privacy-and-security/children%27s-privacy" {{#isSync}} target="_blank"{{/isSync}}>{{#t}}Learn more{{/t}}</a>
</p>
</section>

Просмотреть файл

@ -5,14 +5,14 @@
<section>
<form id="choose-what-to-sync" novalidate>
<header>
<h1 id="fxa-choose-what-to-sync-header">
<h1 id="fxa-choose-what-to-sync-header" class="font-normal mb-5 text-base">
{{#t}}Choose what to sync:{{/t}}
</h1>
</header>
<div class="two-col-items">
<div class="flex flex-wrap ltr:text-left rtl:text-right ltr:mobileLandscape:ml-6 rtl:mobileLandscape:mr-6">
{{#engines}}
<div class="input-row choose-what-to-sync-row">
<input name="sync-content" id="sync-engine-{{id}}" type="checkbox" class="customize-sync" {{#checked}}checked="checked"{{/checked}} value="{{id}}" tabindex="{{tabindex}}" /><label class="fxa-checkbox__label" for="sync-engine-{{id}}">{{text}}</label>
<div class="mb-5 relative flex-50% rtl:mobileLandscape:pr-6 ltr:mobileLandscape:pl-6 rtl:pr-3 ltr:pl-3">
<input name="sync-content" id="sync-engine-{{id}}" type="checkbox" {{#checked}}checked="checked"{{/checked}} value="{{id}}" tabindex="{{tabindex}}" /><label class="top-1" for="sync-engine-{{id}}">{{text}}</label>
</div>
{{/engines}}
</div>

Просмотреть файл

@ -1,7 +1,7 @@
<div id="main-content" class="card account-recovery-create-password">
<div class="card account-recovery-create-password">
{{#isLinkExpired}}
<header>
<h1 id="fxa-reset-link-expired-header">{{#t}}Reset password link expired{{/t}}</h1>
<header class="mb-4">
<h1 id="fxa-reset-link-expired-header" class="card-header">{{#t}}Reset password link expired{{/t}}</h1>
</header>
<section>
@ -67,11 +67,11 @@
<input type="password" class="password tooltip-below" id="vpassword" placeholder="{{#t}}Re-enter password{{/t}}" required pattern=".{8,}" data-synchronize-show="true"/>
</div>
<div class="button-row ">
<button type="submit">{{#t}}Reset password{{/t}}</button>
<div class="flex">
<button type="submit" class="cta-primary cta-xl">{{#t}}Reset password{{/t}}</button>
</div>
<div class="links">
<a href="#" class="remember-password">{{#t}}Remember password? Sign in{{/t}}</a>
<a href="#" id="remember-password" class="link-blue mt-5">{{#t}}Remember password? Sign in{{/t}}</a>
</div>
</form>
</section>

Просмотреть файл

@ -1,8 +1,8 @@
<div id="main-content" class="card confirm-signup">
<header>
<h1 id="fxa-confirm-signup-code-header">
<div class="card">
<header class="mb-4">
<h1 id="fxa-confirm-signup-code-header" class="card-header">
{{#t}}Enter confirmation code{{/t}}
<span class="description">
<span class="card-subheader" id="subheader">
{{#t}}for your Firefox account{{/t}}
</span>
</h1>
@ -12,20 +12,20 @@
<div class="error"></div>
<div class="success"></div>
<div class="graphic graphic-mail"></div>
<div class="bg-image-email"></div>
<p class="verification-email-message">{{#unsafeTranslate}}Enter the code that was sent to %(escapedEmail)s within 5 minutes.{{/unsafeTranslate}}</p>
<p id="verification-email-message" class="mb-5">{{#unsafeTranslate}}Enter the code that was sent to %(escapedEmail)s within 5 minutes.{{/unsafeTranslate}}</p>
<form novalidate>
<div class="input-row">
<!-- Using `type="text" inputmode="numeric"` shows the numericpad on mobile and strips out whitespace on desktop. -->
<input type="text" inputmode="numeric" pattern="\d[ ]*" class="tooltip-below otp-code" placeholder="{{#t}}Enter 6-digit code{{/t}}" required autofocus />
</div>
<div class="button-row">
<button id="submit-btn" type="submit">{{#t}}Confirm{{/t}}</button>
</div>
<div class="links">
<span class="delayed-fadein faint">{{#t}}Code expired?{{/t}}</span>&nbsp;<a id="resend" class="delayed-fadein" href="#">{{#t}}Email new code.{{/t}}</a>
<div class="flex">
<button id="submit-btn" type="submit" class="cta-primary cta-xl">{{#t}}Confirm{{/t}}</button>
</div>
<p id="links" class="animate-delayed-fade-in opacity-0 mt-5 text-grey-500 text-xs">
{{#t}}Code expired?{{/t}}&nbsp;<a id="resend" class="link-blue" href="#">{{#t}}Email new code.{{/t}}</a>
</p>
</form>
</section>
</div>

Просмотреть файл

@ -1,34 +1,29 @@
<div id="main-content" class="card">
<header class="hidden" id="fxa-connect-another-device-header"><h1>{{#t}}Connect another device{{/t}}</h1></header>
<div class="card">
<header class="hidden" id="fxa-connect-another-device-header"><h1 class="card-header mb-8">{{#t}}Connect another device{{/t}}</h1></header>
{{#showSuccessMessage}}
{{#isSignedIn}}
<h2 id="fxa-connected-heading" class="mb-10"><img
src="/images/circle-check.svg"
role="presentation"
alt=""
class="align-middle mr-3"
/>{{#t}}Firefox account connected{{/t}}</h2>
<h2 id="fxa-connected-heading" class="card-header mb-8 ltr:before:content-circle-check rtl:after:content-circle-check rtl:after:relative"><span class="align-top ltr:pl-3 rtl:pr-3">{{#t}}Firefox account connected{{/t}}</span></h2>
{{/isSignedIn}}
{{^isSignedIn}}
{{#isSignUp}}
<div class="success success-not-authenticated visible">{{#t}}Email verified{{/t}}</div>
<div class="success visible" id="success-not-authenticated">{{#t}}Email verified{{/t}}</div>
{{/isSignUp}}
{{#isSignIn}}
<div class="success success-not-authenticated visible">{{#t}}Sign-in confirmed{{/t}}</div>
<div class="success visible" id="success-not-authenticated">{{#t}}Sign-in confirmed{{/t}}</div>
{{/isSignIn}}
{{/isSignedIn}}
{{/showSuccessMessage}}
<section>
<div class="graphic {{graphicId}}" role="img" aria-label="{{#t}}Complete your set-up{{/t}}"></div>
<div class="{{graphicId}}" role="img" aria-label="{{#t}}Complete your set-up{{/t}}"></div>
{{#canSignIn}}
<p>
<p class="mb-5">
{{#t}}Sign in to this Firefox to complete set-up{{/t}}
</p>
<form novalidate>
<div class="button-row">
<a data-flow-event="link.signin" id="signin" class="button primary-button" href="{{{ escapedSignInUrl }}}">{{#t}}Sign in{{/t}}</a>
<div class="flex">
<a data-flow-event="link.signin" id="signin" class="cta-primary cta-xl" href="{{{ escapedSignInUrl }}}">{{#t}}Sign in{{/t}}</a>
</div>
</form>
{{/canSignIn}}
@ -47,13 +42,15 @@
{{#isFirefoxDesktop}}
<p id="install-mobile-firefox-desktop">
{{#isSignedIn}}
<div class="button-row">
<a id="sync-firefox-devices" href="{{{pairingUrl}}}" class="button primary-button">{{#t}}Sync Firefox across devices{{/t}}</a>
<div class="flex">
<a id="sync-firefox-devices" href="{{{pairingUrl}}}" class="cta-primary cta-xl">{{#t}}Sync Firefox across devices{{/t}}</a>
</div>
{{/isSignedIn}}
</p>
<div class="pair-everywhere-cta text-grey-500 text-xs font-normal leading-[18px]">{{#t}}Sign in everywhere you use Firefox.{{/t}}</div>
<div class="pair-everywhere-cta text-grey-500 text-xs font-normal leading-[18px]">{{#t}}Were on Android and iOS, too!{{/t}}</div>
<div id="pair-everywhere" class="text-grey-500 text-xs font-normal mt-4">
<p>{{#t}}Sign in everywhere you use Firefox.{{/t}}</p>
<p>{{#t}}Were on Android and iOS, too!{{/t}}</p>
</div>
{{/isFirefoxDesktop}}
{{#isFirefoxIos}}
<!-- user verifies in Fx for iOS, assume they are not signed in -->

Просмотреть файл

@ -1,14 +1,14 @@
<div id="main-content" class="card">
<div class="card">
<header>
<h1 id="fxa-force-auth-header">
<h1 id="fxa-force-auth-header" class="card-header">
{{#isSync}}
{{#unsafeTranslate}}
Enter your password <span class="description">for your Firefox account</span>
Enter your password <span class="card-subheader" id="subheader">for your Firefox account</span>
{{/unsafeTranslate}}
{{/isSync}}
{{^isSync}}
<!-- L10N: For languages structured like English, the second phrase can read "to continue to %(serviceName)s" -->
{{#t}}Sign in{{/t}} <span class="service">{{#t}}Continue to %(serviceName)s{{/t}}</span>
{{#t}}Sign in{{/t}} <span class="card-subheader" id="subheader">{{#t}}Continue to %(serviceName)s{{/t}}</span>
{{/isSync}}
</h1>
</header>
@ -29,18 +29,18 @@
<input type="password" class="password tooltip-below" id="password" placeholder="{{#t}}Password{{/t}}" required pattern=".{8,}" required {{#email}}autofocus{{/email}} />
</div>
<div class="button-row">
<button id="submit-btn" type="submit">{{{buttonSignInText}}}</button>
<div class="flex">
<button id="submit-btn" type="submit" class="cta-primary cta-xl">{{{buttonSignInText}}}</button>
</div>
</form>
<div class="tos-pp faint">
{{#unsafeTranslate}}By proceeding, you agree to the <a id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a id="fxa-pp" href="/legal/privacy">Privacy Notice</a>.{{/unsafeTranslate}}
<div id="tos-pp" class="text-grey-500 my-5 text-xs">
{{#unsafeTranslate}}By proceeding, you agree to the <a class="link-grey" id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a class="link-grey" id="fxa-pp" href="/legal/privacy">Privacy Notice</a>.{{/unsafeTranslate}}
</div>
<div class="links">
<a href="/" class="left use-different" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a>
<a href="/reset_password" class="right reset-password" data-flow-event="forgot-password">{{#t}}Forgot password?{{/t}}</a>
<div class="flex justify-between">
<a href="/" id="use-different" class="link-blue" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a>
<a href="/reset_password" class="link-blue" data-flow-event="forgot-password" id="reset-password">{{#t}}Forgot password?{{/t}}</a>
</div>
{{/fatalError}}
</section>

Просмотреть файл

@ -1,17 +1,17 @@
<div id="main-content" class="card">
<header>
<div class="card">
<header class="mb-4">
{{#isSync}}
<h1 id="fxa-enter-email-header">
<h1 id="fxa-enter-email-header" class="card-header">
{{#t}}Continue to Firefox accounts{{/t}}
</h1>
<p class="sync-description">
<p class="mt-1 mb-9" id="subheader">
{{#t}}Sync your passwords, tabs, and bookmarks everywhere you use Firefox.{{/t}}
</p>
{{/isSync}}
{{^isSync}}
<h1 id="fxa-enter-email-header">
<h1 id="fxa-enter-email-header" class="card-header">
{{#t}}Enter your email{{/t}}
<span class="service">
<span class="block text-sm font-body font-normal mt-1" id="subheader">
{{#serviceLogo}}
<!-- L10N: For languages structured like English, the phrase can read "to continue to" with Pocket image following -->
{{#unsafeTranslate}}Continue to <div class="graphic %(serviceLogo)s">%(serviceName)s</div>{{/unsafeTranslate}}
@ -32,11 +32,11 @@
<form novalidate>
<div class="input-row">
<input name="email" type="email" class="email tooltip-below" autofocus placeholder="{{#t}}Email{{/t}}"/>
<input name="email" type="email" class="email tooltip-below" autofocus placeholder="{{#t}}Enter your email{{/t}}"/>
</div>
<div class="button-row">
<button id="submit-btn" type="submit">
<div class="flex">
<button id="submit-btn" type="submit" class="cta-primary cta-xl">
{{#t}}Sign up or sign in{{/t}}
</button>
</div>
@ -47,7 +47,7 @@
{{/isInThirdPartyAuthExperiment}}
{{^isInThirdPartyAuthExperiment}}
<p class="firefox-family-services">
<p class="text-xs text-grey-500 mb-0 mt-5" id="firefox-family-services">
{{#t}}A Firefox account also unlocks access to more privacy-protecting products from Mozilla.{{/t}}
</p>
{{/isInThirdPartyAuthExperiment}}

Просмотреть файл

@ -1,6 +1,6 @@
<div id="main-content" class="card pair-auth">
<header>
<h1 id="fxa-pair-auth-allow-header">
<div class="card">
<header class="mb-4">
<h1 id="fxa-pair-auth-allow-header" class="card-header">
{{#t}}Did you just sign in to Firefox?{{/t}}
</h1>
<p>{{#unsafeTranslate}} %(email)s {{/unsafeTranslate}}</p>
@ -9,15 +9,15 @@
<section>
<div class="error"></div>
<div class="success"></div>
<div class="graphic graphic-confirm-pairing" role="img" aria-label="{{#t}}location balloon{{/t}}"></div>
<div class="bg-image-location-balloon" role="img" aria-label="{{#t}}location balloon{{/t}}"></div>
<form novalidate>
{{{ unsafeDeviceBeingPairedHTML }}}
<div class="button-row">
<button type="submit" id="auth-approve-btn">{{#t}}Yes, approve device{{/t}}</button>
<div class="flex">
<button type="submit" class="cta-primary cta-xl my-5" id="auth-approve-btn">{{#t}}Yes, approve device{{/t}}</button>
</div>
<p>{{#unsafeTranslate}}If this wasnt you, <a id="change-password">change your password</a> {{/unsafeTranslate}}</p>
<p class="text-grey-500 text-xs">{{#unsafeTranslate}}If this wasnt you, <a id="change-password" class="link-blue">change your password</a> {{/unsafeTranslate}}</p>
</form>
</section>
</div>

Просмотреть файл

@ -1,27 +1,27 @@
<div id="main-content" class="card pair-auth pair-auth-complete">
<header>
<h1 id="pair-auth-complete-header">{{#t}}Device connected{{/t}}</h1>
<div class="card">
<header class="mb-9">
<h1 id="pair-auth-complete-header" class="card-header">{{#t}}Device connected{{/t}}</h1>
</header>
<section>
<div class="error"></div>
<div class="graphic {{ graphicId }}" role="img" aria-label="{{#t}}Successfully connected{{/t}}"></div>
<div class="{{ graphicId }}" role="img" aria-label="{{#t}}Successfully connected{{/t}}"></div>
<h2 id="device-os">
<h2 id="device-os" class="text-base">
{{#unsafeTranslate}}
You are now syncing with: <span>%(deviceFamily)s on %(deviceOS)s</span>
{{/unsafeTranslate}}
</h2>
<p>{{#t}}Now you can access your open tabs, passwords, and bookmarks on all your devices.{{/t}}</p>
<p class="my-5">{{#t}}Now you can access your open tabs, passwords, and bookmarks on all your devices.{{/t}}</p>
<div class="button-row">
<div class="flex">
{{#hasFirefoxViewSupport}}
<a id="open-firefox-view" class="button primary-button">{{#t}}See tabs from synced devices{{/t}}</a>
<a id="open-firefox-view" class="cta-primary cta-xl">{{#t}}See tabs from synced devices{{/t}}</a>
{{/hasFirefoxViewSupport}}
{{^hasFirefoxViewSupport}}
<a href="/settings#connected-services" class="button primary-button">{{#t}}Manage devices{{/t}}</a>
<a href="/settings#connected-services" class="cta-primary cta-xl">{{#t}}Manage devices{{/t}}</a>
{{/hasFirefoxViewSupport}}
</div>
</section>

Просмотреть файл

@ -1,6 +1,6 @@
<div id="main-content" class="card">
<div class="card">
<header>
<h1 id="fxa-pair-failure-header">
<h1 id="fxa-pair-failure-header" class="card-header">
{{#t}}Pairing not successful{{/t}}
</h1>
</header>
@ -10,7 +10,7 @@
<div class="success"></div>
<form novalidate>
<div class="graphic graphic-pair-failure">{{#t}}Pairing not successful{{/t}}</div>
<div class="bg-image-pair-fail"></div>
<p>{{#t}}The setup process was terminated.{{/t}}</p>
</form>

Просмотреть файл

@ -1,24 +1,24 @@
<div id="main-content" class="card">
<div class="card">
<header>
<h2 id="pair-header">{{#t}}Get Firefox on your phone or tablet{{/t}}</h2>
<h2 id="pair-header" class="card-header">{{#t}}Get Firefox on your phone or tablet{{/t}}</h2>
</header>
<section>
<div class="error"></div>
{{#showQrCode}}
<div class="graphic graphic-connect-another-device-qr-code" role="img" aria-label="{{#t}}Get Firefox on your phone or tablet{{/t}}"></div>
<p>{{#t}}Hold your phone's camera over the code to scan.{{/t}}<br>{{#unsafeTranslate}}Or, send yourself a <a href="https://www.mozilla.org/firefox/mobile/get-app/" class="download-firefox-mobile">download link.</a>{{/unsafeTranslate}}</p>
<div class="bg-image-cad-qr-code" role="img" aria-label="{{#t}}QR code{{/t}}"></div>
<p class="my-5">{{#t}}Hold your phones camera over the code to scan.{{/t}}<br>{{#unsafeTranslate}}Or, send yourself a <a href="https://www.mozilla.org/firefox/mobile/get-app/" target="_blank" class="link-blue">download link.</a>{{/unsafeTranslate}}</p>
{{/showQrCode}}
{{^showQrCode}}
<div class="graphic {{graphicId}}" role="img" aria-label="{{#t}}Get Firefox on your phone or tablet{{/t}}"></div>
<div class="{{graphicId}} mt-5" role="img" aria-label="{{#t}}Complete your set-up{{/t}}"></div>
{{/showQrCode}}
<form novalidate>
<div class="button-row">
<button id="start-pairing" type="submit">{{#t}}I'm ready to sync devices{{/t}}</button>
<div class="flex">
<button id="start-pairing" class="cta-primary cta-xl" type="submit">{{#t}}Im ready to sync devices{{/t}}</button>
</div>
</form>
<p>{{#t}}Sync devices to access your tabs, passwords, and bookmarks everywhere you use Firefox.{{/t}}</p>
<p class="mt-5 text-grey-500 text-xs">{{#t}}Sync devices to access your tabs, passwords, and bookmarks everywhere you use Firefox.{{/t}}</p>
</section>
</div>

Просмотреть файл

@ -1,15 +1,14 @@
<div id="main-content" class="card pair-auth pair-auth-complete">
<header>
<h1 id="pair-auth-complete-header">{{#t}}Device connected{{/t}}</h1>
<div class="card">
<header class="mb-9">
<h1 id="pair-auth-complete-header" class="card-header">{{#t}}Device connected{{/t}}</h1>
</header>
<section>
<div class="error"></div>
<div class="graphic {{ graphicId }}" role="img" aria-label="{{#t}}Device successfully paired{{/t}}"></div>
<div class="{{ graphicId }}" role="img" aria-label="{{#t}}Device successfully paired{{/t}}"></div>
<p>{{#t}}Pairing was successful.{{/t}}</p>
</section>
</div>

Просмотреть файл

@ -1,15 +1,14 @@
<div id="main-content" class="card">
<div class="card">
<header>
<h1 id="pair-unsupported-header">{{#t}}Pair using an app{{/t}}</h1>
<h1 id="pair-unsupported-header" class="card-header">{{#t}}Pair using an app{{/t}}</h1>
</header>
<section>
<div class="error"></div>
<div class="graphic graphic-pair-failure">{{#t}}Pair using an app{{/t}}</div>
<div class="bg-image-pair-fail"></div>
<p>{{#t}}Did you use the system camera? You must pair from within a Firefox app.{{/t}}</p>
</section>
</div>

Просмотреть файл

@ -1,4 +1,4 @@
<div id="coppa" class="input-row input-row-age">
<input type="number" pattern="\d*" id="age" placeholder="{{#t}}How old are you?{{/t}}" min="0" max="130" value="{{ age }}" {{#required}}required{{/required}} />
<p>{{#t}}You must be over 13 to create an account.{{/t}}</p>
<p>{{#t}}You must be at least 13 years old to create an account.{{/t}}</p>
</div>

Просмотреть файл

@ -1,5 +1,5 @@
<aside class="third-party-auth">
<div class="separator">{{#t}}or{{/t}}</div>
<button id="google-login-button" class="login-button"><span class="google-logo"></span>{{#t}}Continue with Google{{/t}}</button>
<button id="apple-login-button" class="login-button"><span class="apple-logo"></span>{{#t}}Continue with Apple{{/t}}</button>
<button id="google-login-button" class="button login-button"><span class="google-logo"></span>{{#t}}Continue with Google{{/t}}</button>
<button id="apple-login-button" class="button login-button"><span class="apple-logo"></span>{{#t}}Continue with Apple{{/t}}</button>
</aside>

Просмотреть файл

@ -1,8 +1,4 @@
<div class="user-card">
<div class="avatar-wrapper card-view"></div>
<div class="user-info">
<div>
<div class="prefillEmail">{{ email }}</div>
</div>
</div>
<div class="mt-9">
<div class="avatar-wrapper mx-auto h-24 w-24 mobileLandscape:h-40 mobileLandscape:w-40"></div>
<div class="my-5 text-base break-all" id="prefillEmail">{{ email }}</div>
</div>

Просмотреть файл

@ -53,8 +53,8 @@
<button type="submit">{{#t}}Create Password{{/t}}</button>
</div>
<div class="tos-pp faint">
{{#unsafeTranslate}}By proceeding, you agree to the <a id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a id="fxa-pp" href="/legal/privacy">Privacy Notice</a>.{{/unsafeTranslate}}
<div id="tos-pp" class="text-grey-500 my-5 text-xs">
{{#unsafeTranslate}}By proceeding, you agree to the <a class="link-grey" id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a class="link-grey" id="fxa-pp" href="/legal/privacy">Privacy Notice</a>.{{/unsafeTranslate}}
</div>
</form>
</section>

Просмотреть файл

@ -1,8 +1,8 @@
<div id="main-content" class="card">
<header>
<h1 id="fxa-reset-password-header">
<header class="mb-4">
<h1 id="fxa-reset-password-header" class="card-header">
<!-- L10N: For languages structured like English, the second phrase can read "to continue to %(serviceName)s" -->
{{#t}}Reset password{{/t}} <span class="service">{{#t}}Continue to %(serviceName)s{{/t}}</span>
{{#t}}Reset password{{/t}} <span class="card-subheader">{{#t}}Continue to %(serviceName)s{{/t}}</span>
</h1>
</header>
@ -15,7 +15,7 @@
</p>
<div class="input-row">
{{#forceEmail}}
<p class="prefillEmail">{{ forceEmail }}</p>
<p id="prefillEmail" class="text-base break-all">{{ forceEmail }}</p>
<input type="email" class="email hidden" value="{{ forceEmail }}" disabled />
{{/forceEmail}}
{{^forceEmail}}
@ -23,14 +23,14 @@
{{/forceEmail}}
</div>
<div class="button-row">
<button id="submit-btn" type="submit">{{#t}}Begin reset{{/t}}</button>
<div class="flex">
<button id="submit-btn" type="submit" class="cta-primary cta-xl">{{#t}}Begin reset{{/t}}</button>
</div>
</form>
{{#canGoBack}}
<div class="links">
<a href="#" class="remember-password">{{#t}}Remember password? Sign in{{/t}}</a>
<a href="#" id="remember-password" class="link-blue mt-5">{{#t}}Remember password? Sign in{{/t}}</a>
</div>
{{/canGoBack}}

Просмотреть файл

@ -1,14 +1,14 @@
<div id="main-content" class="card">
<div class="card">
<header>
<h1 id="fxa-signin-password-header">
<h1 id="fxa-signin-password-header" class="card-header">
{{#isPasswordNeeded}}
{{#unsafeTranslate}}
Enter your password <span class="description">for your Firefox account</span>
Enter your password <span class="card-subheader" id="subheader">for your Firefox account</span>
{{/unsafeTranslate}}
{{/isPasswordNeeded}}
{{^isPasswordNeeded}}
{{#t}}Sign in{{/t}}
<span class="service">
<span class="card-subheader" id="subheader">
<!-- L10N: For languages structured like English, the phrase can read "to continue to %(serviceName)s" -->
{{#serviceLogo}}
{{#unsafeTranslate}}Continue to <div class="graphic %(serviceLogo)s">%(serviceName)s</div>{{/unsafeTranslate}}
@ -41,26 +41,26 @@
- showing the doorhanger. -->
<input class="hidden" required />
<div class="button-row">
<button id="submit-btn" {{^isPasswordNeeded}}class="use-logged-in"{{/isPasswordNeeded}} type="submit">{{#t}}Sign in{{/t}}</button>
<div class="flex">
<button id="{{^isPasswordNeeded}}use-logged-in{{/isPasswordNeeded}}{{#isPasswordNeeded}}submit-btn{{/isPasswordNeeded}}" class="cta-primary cta-xl {{^isPasswordNeeded}}use-logged-in{{/isPasswordNeeded}}" type="submit">{{#t}}Sign in{{/t}}</button>
</div>
<div class="tos-pp faint">
<div id="tos-pp" class="text-grey-500 my-5 text-xs">
{{#isPocketClient}}
{{#unsafeTranslate}}
By proceeding, you agree to:<br />
Pockets <a id="pocket-tos" href="https://getpocket.com/en/tos/">Terms of Service</a> and <a id="pocket-pp" href="https://getpocket.com/en/privacy/">Privacy Notice</a><br />
Firefoxs <a id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a id="fxa-pp" href="/legal/privacy">Privacy Notice</a>
Pockets <a class="link-grey" id="pocket-tos" href="https://getpocket.com/en/tos/">Terms of Service</a> and <a id="pocket-pp" class="link-grey" href="https://getpocket.com/en/privacy/">Privacy Notice</a><br />
Firefoxs <a class="link-grey" id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a class="link-grey" id="fxa-pp" href="/legal/privacy">Privacy Notice</a>.
{{/unsafeTranslate}}
{{/isPocketClient}}
{{^isPocketClient}}
{{#unsafeTranslate}}By proceeding, you agree to the <a id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a id="fxa-pp" href="/legal/privacy">Privacy Notice</a>.{{/unsafeTranslate}}
{{#unsafeTranslate}}By proceeding, you agree to the <a class="link-grey" id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a class="link-grey" id="fxa-pp" href="/legal/privacy">Privacy Notice</a>.{{/unsafeTranslate}}
{{/isPocketClient}}
</div>
<div class="links">
<a href="/" class="left use-different" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a>
<a href="/reset_password" class="right reset-password" data-flow-event="forgot-password">{{#t}}Forgot password?{{/t}}</a>
<div class="flex justify-between">
<a href="/" id="use-different" class="link-blue" data-flow-event="use-different-account">{{#t}}Use a different account{{/t}}</a>
<a href="/reset_password" class="link-blue" data-flow-event="forgot-password" id="reset-password">{{#t}}Forgot password?{{/t}}</a>
</div>
</form>
</section>

Просмотреть файл

@ -21,7 +21,7 @@
</div>
<div class="button-row">
<button type="submit" class="use-logged-in">{{#t}}Verify{{/t}}</button>
<button type="submit" id="use-logged-in">{{#t}}Verify{{/t}}</button>
</div>
</form>

Просмотреть файл

@ -1,15 +1,15 @@
<div id="main-content" class="card">
<header>
<h1 id="fxa-signin-code-header">{{#unsafeTranslate}}Enter confirmation code<span class="description">for your Firefox account</span>{{/unsafeTranslate}}</h1>
<h1 id="fxa-signin-code-header" class="card-header">{{#unsafeTranslate}}Enter confirmation code<span class="card-subheader">for your Firefox account</span>{{/unsafeTranslate}}</h1>
</header>
<section>
<div class="error"></div>
<div class="success"></div>
<div class="graphic graphic-mail">{{#t}}Enter confirmation{{/t}}</div>
<div class="bg-image-email"></div>
<p class="verification-email-message">
<p id="verification-email-message" class="mb-5">
{{#t}}Enter the code that was sent to %(email)s within 5 minutes{{/t}}
</p>
@ -19,14 +19,14 @@
<input type="text" inputmode="numeric" pattern="\d[ ]*" class="tooltip-below otp-code" placeholder="{{#t}}Enter 6-digit code{{/t}}" required autofocus />
</div>
<div class="button-row">
<button type="submit" class="use-logged-in">{{#t}}Confirm{{/t}}</button>
<div class="flex">
<button type="submit" id="use-logged-in" class="cta-primary cta-xl">{{#t}}Confirm{{/t}}</button>
</div>
</form>
<div class="links">
<span class="delayed-fadein faint">{{#t}}Code expired?{{/t}}</span><a id="resend" class="left delayed-fadein" href="#">{{#t}}Email new code{{/t}}</a>
<p class="animate-delayed-fade-in opacity-0 mt-5 text-grey-500 text-xs">
{{#t}}Code expired?{{/t}}&nbsp;<a id="resend" class="link-blue" href="#">{{#t}}Email new code.{{/t}}</a>
</p>
</div>
</section>
</div>

Просмотреть файл

@ -21,7 +21,7 @@
</div>
<div class="button-row">
<button type="submit" class="use-logged-in">{{#t}}Verify{{/t}}</button>
<button type="submit" id="use-logged-in">{{#t}}Verify{{/t}}</button>
</div>
</form>

Просмотреть файл

@ -19,7 +19,7 @@
</div>
<div class="button-row">
<button type="submit" class="use-logged-in">{{#t}}Continue{{/t}}</button>
<button type="submit" id="use-logged-in">{{#t}}Continue{{/t}}</button>
</div>
</form>

Просмотреть файл

@ -1,6 +1,6 @@
<div id="main-content" class="card signup-password">
<header>
<h1 id="fxa-signup-password-header">
<div class="card">
<header class="mb-2">
<h1 id="fxa-signup-password-header" class="card-header">
{{#t}}Set your password{{/t}}
</h1>
</header>
@ -11,10 +11,12 @@
{{{ accountSuggestionHTML }}}
<form novalidate>
<p class="prefillEmail">{{ email }}</p>
<p id="prefillEmail" class="text-base break-all {{^canChangeAccount}}mb-9{{/canChangeAccount}}">{{ email }}</p>
<input name="email" type="email" class="email hidden" value="{{ email }}" disabled />
{{#canChangeAccount}}
<a href="/" class="use-different">{{#t}}Change email{{/t}}</a>
<div class="mb-9">
<a href="/" id="use-different" class="link-blue">{{#t}}Change email{{/t}}</a>
</div>
{{/canChangeAccount}}
<div class="input-row password-row">
@ -49,33 +51,33 @@
{{/isCWTSOnSignupPasswordEnabled}}
{{#isCWTSOnSignupPasswordEnabled}}
<header>
<h2 id="fxa-choose-what-to-sync-header">
{{#t}}Choose what to sync:{{/t}}
<h2 id="fxa-choose-what-to-sync-header" class="font-normal mb-5 text-base">
{{#t}}Choose what to sync{{/t}}
</h2>
</header>
<div class="two-col-items">
<div class="flex flex-wrap ltr:text-left rtl:text-right ltr:mobileLandscape:ml-6 rtl:mobileLandscape:mr-6">
{{#engines}}
<div class="input-row choose-what-to-sync-row">
<input name="sync-content" id="sync-engine-{{id}}" type="checkbox" class="customize-sync" {{#checked}}checked="checked"{{/checked}} value="{{id}}" tabindex="{{tabindex}}" /><label class="fxa-checkbox__label" for="sync-engine-{{id}}">{{text}}</label>
<div class="mb-5 relative flex-50% rtl:mobileLandscape:pr-6 ltr:mobileLandscape:pl-6 rtl:pr-3 ltr:pl-3">
<input name="sync-content" id="sync-engine-{{id}}" type="checkbox" {{#checked}}checked="checked"{{/checked}} value="{{id}}" tabindex="{{tabindex}}" /><label class="top-1" for="sync-engine-{{id}}">{{text}}</label>
</div>
{{/engines}}
</div>
{{/isCWTSOnSignupPasswordEnabled}}
<div class="button-row">
<button id="submit-btn" type="submit">{{#t}}Create account{{/t}}</button>
<div class="flex">
<button id="submit-btn" class="cta-primary cta-xl" type="submit">{{#t}}Create account{{/t}}</button>
</div>
<div class="tos-pp faint">
<div id="tos-pp" class="text-grey-500 mt-5 text-xs">
{{#isPocketClient}}
{{#unsafeTranslate}}
By proceeding, you agree to:<br />
Pockets <a id="pocket-tos" href="https://getpocket.com/en/tos/">Terms of Service</a> and <a id="pocket-pp" href="https://getpocket.com/en/privacy/">Privacy Notice</a><br />
Firefoxs <a id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a id="fxa-pp" href="/legal/privacy">Privacy Notice</a>
Pockets <a class="link-grey" id="pocket-tos" href="https://getpocket.com/en/tos/">Terms of Service</a> and <a class="link-grey" id="pocket-pp" href="https://getpocket.com/en/privacy/">Privacy Notice</a><br />
Firefoxs <a class="link-grey" id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a class="link-grey" id="fxa-pp" href="/legal/privacy">Privacy Notice</a>
{{/unsafeTranslate}}
{{/isPocketClient}}
{{^isPocketClient}}
{{#unsafeTranslate}}By proceeding, you agree to the <a id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a id="fxa-pp" href="/legal/privacy">Privacy Notice</a>.{{/unsafeTranslate}}
{{#unsafeTranslate}}By proceeding, you agree to the <a class="link-grey" id="fxa-tos" href="/legal/terms">Terms of Service</a> and <a class="link-grey" id="fxa-pp" href="/legal/privacy">Privacy Notice</a>.{{/unsafeTranslate}}
{{/isPocketClient}}
</div>
</form>

Просмотреть файл

@ -25,7 +25,7 @@ const View = FormView.extend({
className: 'complete-reset-password',
events: _.extend({}, FormView.prototype.events, {
'click .remember-password': preventDefaultThen('_navigateToSignin'),
'click #remember-password': preventDefaultThen('_navigateToSignin'),
}),
_navigateToSignin() {
@ -54,9 +54,8 @@ const View = FormView.extend({
// key view, then these properties must be set in order to recover the account
// using the recovery key.
if (model && model.get('recoveryKeyId')) {
this._accountRecoveryVerficationInfo = new AccountRecoveryVerificationInfo(
model.toJSON()
);
this._accountRecoveryVerficationInfo =
new AccountRecoveryVerificationInfo(model.toJSON());
}
},
@ -168,8 +167,8 @@ const View = FormView.extend({
// The account recovery verification info will be set from the
// `confirm recovery key` view. If the are not set, then perform
// a regular password reset.
const accountRecoveryVerificationInfo = this
._accountRecoveryVerficationInfo;
const accountRecoveryVerificationInfo =
this._accountRecoveryVerficationInfo;
if (accountRecoveryVerificationInfo) {
return this.user.completeAccountPasswordResetWithRecoveryKey(
account,
@ -202,8 +201,8 @@ const View = FormView.extend({
);
})
.then(() => {
const accountRecoveryVerificationInfo = this
._accountRecoveryVerficationInfo;
const accountRecoveryVerificationInfo =
this._accountRecoveryVerficationInfo;
if (!accountRecoveryVerificationInfo) {
this.navigate('reset_password_verified');
} else {

Просмотреть файл

@ -19,7 +19,6 @@ const proto = FormView.prototype;
class ConfirmSignupCodeView extends FormView {
template = Template;
className = 'confirm-signup-code';
afterVisible() {
// the view is always rendered, but the confirmation may be
@ -84,11 +83,8 @@ class ConfirmSignupCodeView extends FormView {
event: 'newsletter.subscribed',
});
}
return this.invokeBrokerMethod(
'afterSignUpConfirmationPoll',
account
);
return this.invokeBrokerMethod('afterSignUpConfirmationPoll', account);
})
.catch((err) => {
if (

Просмотреть файл

@ -178,7 +178,7 @@ const View = FormView.extend({
'click a[href="/reset_password"]': cancelEventThen(
'_navigateToForceResetPassword'
),
'click .use-different': preventDefaultThen('useDifferentAccount'),
'click #use-different': preventDefaultThen('useDifferentAccount'),
},
useDifferentAccount() {

Просмотреть файл

@ -17,8 +17,8 @@ export default {
dependsOn: [UserAgentMixin, UrlMixin],
/**
* Returns graphicId 'graphic-connect-another-device-hearts' if the
* browser supports SVG Transform Origin, and 'graphic-connect-another-device'
* Returns graphicId 'bg-image-cad-hearts' if the
* browser supports SVG Transform Origin, and 'bg-image-cad'
* if it does not.
*
* @returns {String}
@ -27,9 +27,9 @@ export default {
getGraphicsId() {
const uap = this.getUserAgent();
if (uap.supportsSvgTransformOrigin()) {
return 'graphic-connect-another-device-hearts';
return 'bg-image-cad-hearts';
}
return 'graphic-connect-another-device';
return 'bg-image-cad';
},
/**

Просмотреть файл

@ -17,7 +17,7 @@ const t = (msg) => msg;
const ResetPasswordView = FormView.extend({
events: {
'click .remember-password': preventDefaultThen('_rememberPassword'),
'click #remember-password': preventDefaultThen('_rememberPassword'),
},
initialize(options) {

Просмотреть файл

@ -23,7 +23,7 @@ const SignInPasswordView = FormView.extend({
template: Template,
events: assign({}, FormView.prototype.events, {
'click .use-different': preventDefaultThen('useDifferentAccount'),
'click #use-different': preventDefaultThen('useDifferentAccount'),
}),
useDifferentAccount() {

Просмотреть файл

@ -33,7 +33,7 @@ const SignUpPasswordView = FormView.extend({
className: 'sign-up',
events: assign({}, FormView.prototype.events, {
'click .use-different': preventDefaultThen('useDifferentAccount'),
'click #use-different': preventDefaultThen('useDifferentAccount'),
}),
useDifferentAccount() {

Просмотреть файл

@ -68,53 +68,6 @@ a {
@include anchor-default-pseudo-classes();
}
header {
margin-bottom: 15px;
h1,
h2,
h3 {
@include header-font();
line-height: 1em;
margin: 0;
}
h1 {
@include title30();
color: $header-color;
line-height: 26px;
.description,
.service,
.email {
display: block;
font-size: 15px;
line-height: 22px;
margin-top: 4px;
}
.email {
color: $faint-text-color;
// allow long email addresses to be
// split across lines
word-break: anywhere;
}
}
h2 {
@include title20();
font-size: 17px;
font-weight: 600;
margin: 0;
}
.sync-description {
padding: 0 24px;
line-height: 21px;
margin-bottom: 32px;
}
}
button,
input {
@include font();
@ -267,28 +220,6 @@ input[type='checkbox'] {
}
}
.prefillEmail {
@include title20();
color: $text-color;
font-size: 16px;
font-weight: 350;
margin: 0 0 5px 0;
word-wrap: anywhere;
~ .use-different {
display: inline-block;
margin: 0 0 17px 0;
}
}
section p {
margin: 0 auto 25px 0;
}
.email {
display: block;
}
// Add the clearfix class to an element that contains
// floated elements to give the element the height
// of the tallest floated element. This fixes layout

Просмотреть файл

@ -1,5 +1,6 @@
// Two main widths
// Apply styles to div injected by backbone, rather than to the stage itself.
#main-content {
position: relative;
text-align: center;
@ -38,6 +39,64 @@
position: relative;
width: 94%;
}
// Below is all a * TEMP HACK * until all template files using #main-content are converted
// to TW. We should be able to remove all then. At that point we we can also set `a` to default
// to `link-blue` styles, remove that class set on `a`s, and set `link-grey` where needed
header {
margin-bottom: 15px;
h1,
h2,
h3 {
@include header-font();
line-height: 1em;
margin: 0;
}
h1 {
@include title30();
color: $header-color;
line-height: 26px;
}
h2 {
@include title20();
font-size: 17px;
font-weight: 600;
margin: 0;
}
}
section p {
margin: 0 auto 25px 0;
}
.email:not(.hidden) {
display: block;
}
a:not(.button) {
border-radius: 2px; // Give the focusring rounded corners
color: $link-color-default;
cursor: pointer; // Use the correct cursor for anchors without an href
text-decoration: none;
@include anchor-default-pseudo-classes();
}
// can remove once every page with error class uses TW
// at the time of writing we need this for pages that don't have TW available like the 404 page
.error {
@include message-box($error-background-color, $error-text-color);
display: none;
margin-bottom: 10px;
a {
color: $color-white;
text-decoration: underline;
}
}
}
#fxa-settings-content {

Просмотреть файл

@ -1,8 +1,4 @@
.error {
@include message-box($error-background-color, $error-text-color);
display: none;
margin-bottom: 10px;
#loading-template & {
position: fixed;
top: 0;
@ -38,10 +34,6 @@
display: none;
}
.hidden {
display: none;
}
.reset-warning {
font-size: $base-font;
font-weight: normal;
@ -207,9 +199,9 @@ div + .error {
}
// custom state indicators
#suggest-sync, #suggest-account {
/*Pull the message up to bring it closer to the header*/
margin: -6px auto 16px;
#suggest-sync,
#suggest-account {
margin: 0 auto 16px;
.dismiss {
background-image: url('/images/icon-close.svg');

Просмотреть файл

@ -1,4 +1,3 @@
@import '~normalize.css';
@import 'fontello';
@import 'variables';
@import 'mixins';

Просмотреть файл

@ -35,128 +35,15 @@
position: relative;
width: $avatar-size;
.avatar-camera & {
margin-bottom: 20px;
&.spinner-completed {
border: 2px solid $avatar-border-color;
box-shadow: $card-box-low;
}
&.card-view {
align-self: center;
@include respond-to('big') {
height: 120px;
width: 120px;
img {
display: block;
height: 120px;
width: 120px;
}
}
@include respond-to('small') {
height: 84px;
width: 84px;
img {
display: block;
height: 84px;
width: 84px;
}
}
.default {
background-image: image-url('default-profile.svg');
background-size: cover;
}
&.avatar-view {
background-size: 120px auto;
display: block;
height: 120px;
margin: 0 auto 16px auto;
width: 120px;
img,
.change-avatar {
display: block;
height: 120px;
width: 120px;
}
small {
bottom: 0;
position: absolute;
}
}
&.avatar-settings-view {
border: 2px solid transparent;
display: block;
flex-shrink: 0;
margin: 0;
&:not(.nohover):hover {
box-shadow: 0 0 0 1px $color-blue;
}
&:not(.nohover):active {
box-shadow: 0 0 0 1px $color-orange;
}
&.spinner-completed {
border: 2px solid $avatar-border-color;
box-shadow: $card-box-low;
}
.change-avatar:focus {
box-shadow: none;
}
@include respond-to('big') {
height: 64px;
width: 64px;
}
@include respond-to('small') {
height: 50px;
width: 50px;
}
span {
display: inline-block;
}
img,
span,
.change-avatar {
@include respond-to('big') {
height: 60px;
width: 60px;
}
@include respond-to('small') {
height: 46px;
width: 46px;
}
}
}
img {
display: block;
height: $avatar-size;
width: $avatar-size;
&.hidden {
display: none;
}
&.default {
background-image: image-url('default-profile.svg');
background-size: cover;
}
}
}
.with-default {
background: image-url('default-profile.svg') center;
background-repeat: no-repeat;
background-size: 100% 100%;
}
#done {

Просмотреть файл

@ -1,6 +1,5 @@
.button,
.settings-button,
button {
// After all .button-rows are converted to TW, we can remove this entire file
.button {
@include font();
align-items: center;
background: $button-background-color-default;
@ -69,39 +68,6 @@ button {
}
}
&.warning-button {
background: $error-background-color;
border: 0;
color: $message-text-color;
&:disabled,
&:enabled {
background: $error-background-color;
}
&:enabled {
&:hover {
background: $error-background-color-hover;
}
&:active {
background: $error-background-color-active;
}
// 'type' is needed for selector specificity
&[type='submit'] {
&:active,
&:active:hover {
background: darken($error-background-color, 10);
}
&:hover {
background: darken($error-background-color, 5);
}
}
}
}
&:disabled,
&.disabled {
cursor: not-allowed;
@ -120,14 +86,3 @@ button {
text-decoration: none;
}
}
.button-flex-row {
display: flex;
flex-direction: row;
margin: 0 0 20px;
}
button::-moz-focus-inner {
border: 0;
padding: 0;
}

Просмотреть файл

@ -32,15 +32,6 @@
}
}
.tos-pp {
font-size: 12px;
line-height: 18px;
& + .links {
margin-top: 20px;
}
}
.verification-email-message,
.signed-in-email-message,
.verification-recovery-code-message,
@ -168,30 +159,6 @@
}
}
.two-col-items {
display: grid;
grid-template-columns: repeat(2, 1fr);
margin-top: 20px;
padding: 0 15px;
.choose-what-to-sync-row {
display: grid;
grid-template-columns: 28px auto;
line-height: 1.5;
margin-bottom: 20px;
padding-right: 4px;
}
.fxa-checkbox__label {
color: $text-color;
top: -2px;
}
@include respond-to('small') {
column-width: 150px;
}
}
.pair-auth {
h1 {
> small {
@ -255,12 +222,14 @@
border-color: #1a1a1a;
}
.google-logo {
background: url('/images/third_party_auth/google_btn_normal.svg') 50% no-repeat;
background: url('/images/third_party_auth/google_btn_normal.svg') 50%
no-repeat;
width: 40px;
height: 40px;
}
.apple-logo {
background: url('/images/third_party_auth/apple_btn_normal.svg') 50% no-repeat;
background: url('/images/third_party_auth/apple_btn_normal.svg') 50%
no-repeat;
width: 40px;
height: 40px;
}

Просмотреть файл

@ -37,36 +37,6 @@
}
}
.graphic-connect-another-device {
background-image: image-url('account-verified.svg');
@include respond-to('small') {
height: 100px;
}
}
.graphic-connect-another-device-qr-code {
background-image: image-url('qr_code_firefox_mobile.svg');
@include respond-to('small') {
height: 100px;
}
}
.graphic-connect-another-device-hearts {
background-image: image-url('account-verified-hearts.svg');
height: 138px;
margin: 0 auto 20px auto;
}
.graphic-confirm-pairing {
background-image: image-url('confirm-pairing.svg');
@include respond-to('small') {
height: 100px;
}
}
.graphic-laptop-mobile {
background-image: image-url('graphic_laptop_mobile.svg');
height: 138px;
@ -84,11 +54,6 @@
margin: 20px auto 20px auto;
}
.graphic-cad-qr-code-connected {
background-image: image-url('account-verified-hearts.svg');
margin: 40px auto 40px auto;
}
.graphic-two-factor-auth {
background-image: image-url('graphic_two_factor_auth.svg');
height: 138px;
@ -151,10 +116,6 @@
}
}
.graphic-pair-failure {
background-image: image-url('graphic_hearts_broken.svg');
}
.graphic-send-tab-complete {
background-image: image-url('send_tab_complete.svg');
}

Просмотреть файл

@ -24,12 +24,6 @@
}
}
.firefox-family-services {
margin-bottom: 0;
font-size: 12px;
line-height: 18px;
}
.sign-up {
display: flex;
}

Просмотреть файл

@ -255,7 +255,7 @@
border: 1px solid $marketing-border-color;
border-radius: $small-border-radius;
box-shadow: 0 2px 8px rgba($grey-90, 0.1);
color: $faint-text-color !important; // override default tip styles
color: $color-black !important; // override default tip styles
padding: 15px;
position: absolute;
text-align: left;
@ -284,11 +284,11 @@
}
.password-strength-balloon {
font-size: 14px;
font-size: 12px;
font-weight: 400;
line-height: 1.3;
line-height: 1.5;
opacity: 1;
padding: 24px 14px 28px;
padding: 16px;
z-index: 5;
// The characters in Arabic look way too small at 14px and are difficult to read. Bump them up by 1
@ -298,14 +298,15 @@
}
a {
color: $grey-50;
color: $color-black;
text-decoration: underline;
}
.balloon-header {
font-size: 14px;
font-size: 12px;
font-weight: 300;
margin-top: 0;
margin-bottom: 8px;
}
ul {
@ -315,12 +316,12 @@
}
li {
margin: 0 0 7px 0;
margin: 0 0 4px 0;
padding-inline-start: 26px;
&:last-of-type {
margin-bottom: 0;
margin-top: 24px;
margin-top: 16px;
}
&::before {

Просмотреть файл

@ -1,4 +1,22 @@
/* If or when content-server is using Tailwind exclusively, we should enable @base. */
/* @tailwind base; */
@tailwind components;
@tailwind utilities;
/* When content-server is using Tailwind exclusively use "@tailwind" directives instead of
* imports. See: https://tailwindcss.com/docs/using-with-preprocessors */
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
@import 'fxa-react/styles/index.css';
@import './tailwind/fonts';
/* REACT NOTE: when we refactor to React it's going to be nicer to create reusable
* components and ditch some of these custom component classes. */
@import './tailwind/flows';
@import './tailwind/state';
@import './tailwind/ctas';
@import './tailwind/inputs';
@import './tailwind/images';
body {
@apply min-h-screen mobileLandscape:pt-12 text-black flex flex-col justify-center;
}

Просмотреть файл

@ -0,0 +1,23 @@
# Tailwind in fxa-content-server
current as of 2022-07-26
FxA's front-ends either use Tailwind (TW) or will be using Tailwind in near the future. We plan to convert the content-server over to a similar stack to `fxa-settings`, which includes React and Tailwind.
To make the stack conversion easier and to get a head start on making FxA's styles consistent, any design tweaks in the content-server should reference Tailwind classes if at all possible. This should be done with care.
If you're adding Tailwind styles:
- Be sure to inspect the elements and make sure only Tailwind styles (utility classes preferably) are applied as much as possible. Youll have to remove some old SCSS targeted with selectors or else theyll override your utility classes but do so carefully and be sure to refactor other mustache files that would match those selectors.
- At the time of writing, `tailwind.out.css` isn't added to every content-servers `index.html` file. If/when we reskin other error pages or `privacy.html` we'll need to include it there too.
- At the time of writing, all Tailwindified files have removed the ID `#main-content` in its mustache files. This is only serving stylistic purposes so please remove this when you touch the file.
Whenever content-server is converted to Tailwind we can consider extending the `link-blue` class to all `a` elements as our default for links, then override with `link-blue` where needed.
## Component classes
Component classes should live in this `tailwind` directory for organization purposes but when we're no longer using SCSS we can move these styles out of the directory. **Don't use SCSS in component class files** because while we have to keep the build step at the moment for old SCSS files, we'll want to remove it later, and we can use `postcss-import` and `tailwind/nesting` which uses `postcss-nested` under the hood instead.
Component classes (custom `.css`) can usually be avoided by creating reusable _new components/partials_ and applying TW classes on and within that component, [see the TW docs on this](https://tailwindcss.com/docs/reusing-styles#extracting-components-and-partials). This is something to keep in mind when we convert to React since **we should favor new components over [basically writing CSS again](https://tailwindcss.com/docs/reusing-styles#avoiding-premature-abstraction)** - we can remove a lot of the currently existing component classes following that philosophy.
Only use `@apply [tailwind-classes]` in component classes if possible. Nesting element styles within TW is also not preferred since single-element specificity matches the utility pattern and it makes [using layer directives](https://tailwindcss.com/docs/functions-and-directives#layer) easier, but is sometimes unavoidable. It will be necessary in some spots as a "hack" until content-server uses React because currently our Backbone JS files can insert DOM elements containing HTML, and we'd need to 1) be sure to add classes every instance and 2) add these JS files to content-server's TW "content" option for purging reasons.

Просмотреть файл

@ -0,0 +1,15 @@
/* 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/. */
/* Max-height is a likely temp "hack" for .spinner until it's converted to TW */
/* font-color is also a hack until all buttons are TWified */
.cta-xl {
@apply flex-1 font-bold text-base p-4 border-0 max-h-14;
}
/* Temp hack until .spinner is fully converted to TW */
.cta-primary .spinner {
background-image: inline('../images/spinnerwhite.svg');
@apply -mt-[6px] mx-auto;
}

Просмотреть файл

@ -0,0 +1,29 @@
/* 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/. */
.card {
@apply relative text-center w-full mobileLandscape:w-120 mobileLandscape:bg-white rounded-xl px-8 pb-10 pt-28 mobileLandscape:pt-20;
&::before {
@apply h-16 mobileLandscape:h-20 left-0 block absolute bg-center bg-no-repeat w-full bg-contain top-5 mobileLandscape:-top-10;
content: '';
background-image: inline('../images/firefox-logo.svg');
}
&-header {
@apply font-header text-xl font-bold;
}
&-subheader {
@apply font-body font-normal text-sm block mt-1;
}
}
@screen mobileLandscape {
/* Design specifically requested a custom box-shadow. */
.card {
box-shadow: 0 16px 24px rgba(34, 0, 51, 0.04),
0 6px 32px rgba(7, 48, 114, 0.12), 0 8px 12px rgba(14, 13, 26, 0.12);
}
}

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,37 @@
/* font path is relative to the tailwind.out file */
/* REACT NOTE: this file can likely be shared in `fxa-react` */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('tailwind/fonts/Inter-Regular.woff2?v=3.13') format('woff2'),
url('tailwind/fonts/Inter-Regular.woff?v=3.13') format('woff');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('tailwind/fonts/Inter-Bold.woff2?v=3.13') format('woff2'),
url('tailwind/fonts/Inter-Bold.woff?v=3.13') format('woff');
}
@font-face {
font-family: 'Metropolis';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('tailwind/fonts/Metropolis-Regular.woff2?v=10.0.0') format('woff2'),
url('tailwind/fonts/Metropolis-Regular.woff?v=10.0.0') format('woff');
}
@font-face {
font-family: 'Metropolis';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url('tailwind/fonts/Metropolis-Bold.woff2?v=10.0.0') format('woff2'),
url('tailwind/fonts/Metropolis-Bold.woff?v=10.0.0') format('woff');
}

Просмотреть файл

@ -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/. */
/* REACT NOTE: Should be able to refactor avatar stuff and remove this class,
* .with-default and other classes are added in `avatar-mixin.js`.
* Also what about the .default class in _avatar.scss? */
.with-default {
@apply bg-center bg-no-repeat bg-contain;
background-image: inline('../images/default-profile.svg');
}
/* REACT NOTE: inline these SVGs in the JSX. Also might consider taking the y-margins
* off and applying to surrounding elements instead for better extensibility */
.bg-image-email {
@apply mt-8 mb-3 bg-center bg-no-repeat bg-contain h-40;
background-image: inline('../images/graphic_mail.svg');
}
.bg-image-cad-hearts {
@apply mb-8 bg-center bg-no-repeat bg-contain h-40;
background-image: inline('../images/account-verified-hearts.svg');
}
.bg-image-cad {
@apply mb-3 bg-center bg-no-repeat bg-contain h-36;
background-image: inline('../images/account-verified.svg');
}
.bg-image-cad-qr-code {
@apply mt-9 bg-center bg-no-repeat bg-contain h-48;
background-image: inline('../images/qr_code_firefox_mobile.svg');
}
.bg-image-location-balloon {
@apply mt-9 bg-center bg-no-repeat bg-contain h-36;
background-image: inline('../images/confirm-pairing.svg');
}
.bg-image-pair-fail {
@apply mt-9 mb-5 bg-center bg-no-repeat bg-contain h-36;
background-image: inline('../images/graphic_hearts_broken.svg');
}

Просмотреть файл

@ -2,8 +2,6 @@
* 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/. */
module.exports = {
plugins: {
autoprefixer: {},
},
};
.input-text {
@apply flex-1 p-4 text-grey-500 text-base rounded border border-grey-300 focus:border-blue-400 focus:outline-none focus:shadow-input-blue-focus;
}

Просмотреть файл

@ -0,0 +1,12 @@
/* 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/. */
.error {
@apply text-xs bg-red-700 font-bold p-3 my-3 hidden rounded text-white;
/* REACT NOTE: probably don't need this nesting, add class in JSX instead */
a {
@apply underline;
}
}

Просмотреть файл

@ -38,7 +38,7 @@ describe('views/cannot_create_account', function () {
return view.render().then(function () {
assert.ok(view.$('#fxa-cannot-create-account-header').length);
assert.equal(view.$('.ftc').attr('target'), '_blank');
assert.equal(view.$('#ftc').attr('target'), '_blank');
});
});
@ -48,7 +48,7 @@ describe('views/cannot_create_account', function () {
});
return view.render().then(function () {
assert.equal(view.$('.ftc').attr('target'), null);
assert.equal(view.$('#ftc').attr('target'), null);
});
});
});

Просмотреть файл

@ -252,7 +252,7 @@ describe('views/choose_what_to_sync', () => {
return initView().then(() => {
$('#container').html(view.el);
//decline the first engine
$('.customize-sync').first().click();
$('[id^="sync-engine-"').first().click();
const declined = view._getDeclinedEngineIds();
assert.sameMembers(declined, ['tabs']);
});
@ -272,7 +272,7 @@ describe('views/choose_what_to_sync', () => {
it('updates the account, logs metrics, calls onSubmitComplete', () => {
return initView()
.then(() => {
view.$('.customize-sync').first().removeAttr('checked');
view.$('[id^="sync-engine-"').first().removeAttr('checked');
sinon.spy(notifier, 'trigger');
return view.submit();

Просмотреть файл

@ -313,7 +313,7 @@ describe('views/connect_another_device', () => {
return view.render().then(() => {
view.afterVisible();
assert.lengthOf(view.$('.pair-everywhere-cta'), 2);
assert.lengthOf(view.$('#pair-everywhere'), 1);
testIsFlowEventLogged('install_from.fx_desktop');
});
});
@ -392,7 +392,7 @@ describe('views/connect_another_device', () => {
it('shows the marketing area, logs appropriately', () => {
assert.isTrue(view._isSignedIn.called);
assert.lengthOf(view.$('.pair-everywhere-cta'), 2);
assert.lengthOf(view.$('#pair-everywhere'), 1);
testIsFlowEventLogged('signedin.true');
testIsFlowEventLogged('signin.ineligible');
testIsFlowEventLogged('install_from.fx_desktop');
@ -531,25 +531,16 @@ describe('views/connect_another_device', () => {
it('shows animated hearts where supportsSvgTransformOrigin is supported', () => {
sinon.stub(view, 'getUserAgent').callsFake(() => userAgentObj);
assert.equal(
view.$el.find('.graphic-connect-another-device-hearts').length,
1
);
assert.equal(view.$el.find('.graphic-connect-another-device').length, 0);
assert.equal(view.$el.find('.bg-image-cad-hearts').length, 1);
assert.equal(view.$el.find('.bg-image-cad').length, 0);
});
it('shows non-animated hearts where supportsSvgTransformOrigin is not supported', () => {
userAgentObj.supportsSvgTransformOrigin = () => false;
sinon.stub(view, 'getUserAgent').callsFake(() => userAgentObj);
return view.render().then(() => {
assert.equal(
view.$el.find('.graphic-connect-another-device-hearts').length,
0
);
assert.equal(
view.$el.find('.graphic-connect-another-device').length,
1
);
assert.equal(view.$el.find('.bg-image-cad-hearts').length, 0);
assert.equal(view.$el.find('.bg-image-cad').length, 1);
});
});
});

Просмотреть файл

@ -108,50 +108,6 @@ describe('views/mixins/avatar-mixin', function () {
});
});
describe('displayAccountProfileImage with spinner in avatar settings view', () => {
let spinnerView;
const SpinnerAvatarSettingsView = SettingsView.extend({
template() {
return '<div class="avatar-wrapper avatar-settings-view"></div>';
},
});
beforeEach(() => {
spinnerView = new SpinnerAvatarSettingsView({
notifier,
user,
});
sinon
.stub(account, 'fetchCurrentProfileImage')
.returns(
Promise.resolve(
new ProfileImage({ id: 'foo', img: new Image(), url: 'url' })
)
);
sinon.stub(spinnerView, '_shouldShowDefaultProfileImage').returns(false);
return spinnerView.render();
});
it('adds `spinner-completed` class', () =>
spinnerView.displayAccountProfileImage(account).then(() => {
assert.equal(
spinnerView.$('.avatar-settings-view.spinner-completed').length,
1,
'expected .avatar-wrapper.avatar-settings-view to also have the .spinner-completed class'
);
assert.equal(
spinnerView.$('.change-avatar-inner').length,
1,
'expected .change-avatar-inner to exist and have a length equal to 1'
);
assert.equal(
spinnerView.$('.avatar-settings-view.spinner-completed').length,
1,
'expected .avatar-wrapper.avatar-settings-view to also have the .spinner-completed class'
);
}));
});
describe('displayAccountProfileImage spinner functionality', () => {
let spinnerView;
const SpinnerView = SettingsView.extend({

Просмотреть файл

@ -20,25 +20,22 @@ describe('views/mixins/pairing-graphics-mixin', function () {
});
describe('getGraphicsId', () => {
it('returns `graphic-connect-another-device` if SvgTransformOrigin not supported', () => {
it('returns `bg-image-cad` if SvgTransformOrigin not supported', () => {
sinon.stub(view, 'getUserAgent').callsFake(() => {
return {
supportsSvgTransformOrigin: () => false,
};
});
assert.equal(view.getGraphicsId(), 'graphic-connect-another-device');
assert.equal(view.getGraphicsId(), 'bg-image-cad');
});
it('returns `graphic-connect-another-device-hearts` if SvgTransformOrigin supported', () => {
it('returns `bg-image-cad-hearts` if SvgTransformOrigin supported', () => {
sinon.stub(view, 'getUserAgent').callsFake(() => {
return {
supportsSvgTransformOrigin: () => true,
};
});
assert.equal(
view.getGraphicsId(),
'graphic-connect-another-device-hearts'
);
assert.equal(view.getGraphicsId(), 'bg-image-cad-hearts');
});
});

Просмотреть файл

@ -85,11 +85,12 @@ describe('views/pair/auth_complete', () => {
view.$el.find('#pair-auth-complete-header').text(),
'Device connected'
);
assert.include(view.$el.find('#device-os').text(), 'Firefox on Windows');
assert.ok(
view.$el.find('.graphic-connect-another-device-hearts').length
assert.include(
view.$el.find('#device-os').text(),
'Firefox on Windows'
);
assert.ok(view.$el.find('.bg-image-cad-hearts').length);
});
});
});

Просмотреть файл

@ -25,7 +25,7 @@ describe('views/pair/failure', () => {
describe('render', () => {
it('renders', () => {
return view.render().then(() => {
assert.ok(view.$el.find('.graphic-pair-failure').length);
assert.ok(view.$el.find('.bg-image-pair-fail').length);
});
});
});

Просмотреть файл

@ -131,7 +131,7 @@ describe('views/pair/index', () => {
'Get Firefox on your phone or tablet'
);
assert.ok(view.$el.find('#start-pairing').length);
assert.ok(view.$el.find('.graphic').length);
assert.ok(view.$el.find('.bg-image-cad-hearts').length);
});
});
@ -169,7 +169,7 @@ describe('views/pair/index', () => {
it('shows qr code', () => {
sinon.stub(view, 'showDownloadFirefoxQrCode').callsFake(() => true);
return view.render().then(() => {
const qrCode = view.$el.find('.graphic-connect-another-device-qr-code');
const qrCode = view.$el.find('.bg-image-cad-qr-code');
assert.equal(qrCode.length, 1);
});
});
@ -177,7 +177,7 @@ describe('views/pair/index', () => {
it('does not show qr code', () => {
sinon.stub(view, 'showDownloadFirefoxQrCode').callsFake(() => false);
return view.render().then(() => {
const qrCode = view.$el.find('.graphic-connect-another-device-qr-code');
const qrCode = view.$el.find('.bg-image-cad-qr-code');
assert.equal(qrCode.length, 0);
});
});

Просмотреть файл

@ -29,7 +29,7 @@ describe('views/pair/unsupported', () => {
view.$el.find('#pair-unsupported-header').text(),
'Pair using an app'
);
assert.ok(view.$el.find('.graphic-pair-failure').length);
assert.ok(view.$el.find('.bg-image-pair-fail').length);
});
});
});

Просмотреть файл

@ -72,7 +72,7 @@ describe('views/reset_password', function () {
});
it('registers for the expected events', () => {
assert.isFunction(view.events['click .remember-password']);
assert.isFunction(view.events['click #remember-password']);
assert.isFunction(view.events['click a']);
assert.isFunction(view.events['click input']);
assert.isFunction(view.events['input input']);
@ -89,7 +89,7 @@ describe('views/reset_password', function () {
view = createView();
return view.render().then(() => {
assert.lengthOf(view.$('.remember-password'), 1);
assert.lengthOf(view.$('#remember-password'), 1);
});
});
@ -330,8 +330,8 @@ describe('views/reset_password with model.forceEmail', () => {
assert.equal($emailInputEl.val(), email);
assert.isTrue($emailInputEl.hasClass('hidden'));
assert.equal(view.$('.prefillEmail').text(), email);
assert.lengthOf(view.$('.remember-password'), 1);
assert.equal(view.$('#prefillEmail').text(), email);
assert.lengthOf(view.$('#remember-password'), 1);
assert.isFalse(view._resetPassword.called);
});
@ -372,7 +372,7 @@ describe('views/reset_password with `canGoBack: false`', () => {
});
it('does not show remember password button', () => {
assert.lengthOf(view.$('.remember-password'), 0);
assert.lengthOf(view.$('#remember-password'), 0);
});
});

Просмотреть файл

@ -91,7 +91,7 @@ describe('views/sign_in_password', () => {
assert.include(view.$(Selectors.SUB_HEADER).text(), 'Firefox Sync');
assert.lengthOf(view.$('input[type=email]'), 1);
assert.equal(view.$('input[type=email]').val(), EMAIL);
assert.lengthOf(view.$('.tos-pp'), 1);
assert.lengthOf(view.$('#tos-pp'), 1);
});
});
@ -106,7 +106,7 @@ describe('views/sign_in_password', () => {
assert.lengthOf(view.$('input[type=password]'), 1);
assert.isTrue(notifier.trigger.calledOnce);
assert.isTrue(notifier.trigger.calledWith('flow.initialize'));
assert.lengthOf(view.$('.tos-pp'), 1);
assert.lengthOf(view.$('#tos-pp'), 1);
});
});

Просмотреть файл

@ -88,7 +88,7 @@ describe('views/sign_in_token_code', () => {
describe('render', () => {
it('renders the view', () => {
assert.lengthOf(view.$('#fxa-signin-code-header'), 1);
assert.include(view.$('.verification-email-message').text(), 'a@a.com');
assert.include(view.$('#verification-email-message').text(), 'a@a.com');
});
describe('without an account', () => {

Просмотреть файл

@ -4,7 +4,7 @@
"description": "Firefox Accounts Content Server",
"scripts": {
"build": "tsc --build ../fxa-react && npm run build-css && NODE_ENV=production grunt build",
"build-css": "tailwindcss -i ./app/styles/tailwind.css -o ./app/styles/tailwind.out.css",
"build-css": "tailwindcss --postcss -i ./app/styles/tailwind.css -o ./app/styles/tailwind.out.css",
"postinstall": "cp server/config/local.json-dist server/config/local.json && ../../_scripts/clone-l10n.sh fxa-content-server",
"audit": "npm audit --json | audit-filter --nsp-config=.nsprc --audit=-",
"lint": "eslint app server tests --cache",
@ -144,6 +144,7 @@
"@babel/cli": "^7.18.9",
"@testing-library/react": "^12.1.5",
"@types/backbone": "^1.4.10",
"@types/postcss-import": "^14",
"@types/sinon-chai": "3.2.5",
"@types/sinon-express-mock": "1.3.9",
"audit-filter": "^0.5.0",
@ -172,6 +173,8 @@
"otplib": "^11.0.1",
"pm2": "^5.1.2",
"postcss": "^8.4.14",
"postcss-assets": "^6.0.0",
"postcss-import": "^14.1.0",
"prettier": "^2.3.1",
"proxyquire": "^2.1.3",
"request": "^2.88.2",

Просмотреть файл

@ -39,6 +39,8 @@ module.exports = {
'postcss.config.js',
'tailwind.config.js',
'app/scripts/templates/**/*.mustache',
'app/styles/tailwind.css',
'app/styles/tailwind/**/*.css',
require.resolve('fxa-react/configs/tailwind.js'),
],
time: true,

Просмотреть файл

@ -1,5 +1,8 @@
module.exports = {
plugins: {
'postcss-import': {},
'postcss-assets': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
},

Просмотреть файл

@ -6,6 +6,14 @@
const config = require('fxa-react/configs/tailwind');
config.content = ['./app/scripts/templates/**/*.mustache'];
config.content = [
'./app/scripts/templates/**/*.mustache',
'./app/server/templates/pages/**/*.html',
];
config.theme.extend.content = {
...config.theme.extend.content,
'circle-check': "inline('../images/circle-check.svg')",
};
module.exports = config;

Просмотреть файл

@ -328,10 +328,10 @@ module.exports = {
},
CONFIRM_SIGNUP_CODE: {
HEADER: '#fxa-confirm-signup-code-header',
SUB_HEADER: '#fxa-confirm-signup-code-header .description',
EMAIL_FIELD: '.verification-email-message',
SUB_HEADER: '#subheader',
EMAIL_FIELD: '#verification-email-message',
INPUT: '.otp-code',
LINKS: '.links',
LINKS: '#links',
LINK_BACK: '#back',
LINK_RESEND: '#resend',
},
@ -342,7 +342,7 @@ module.exports = {
SIGNIN_BUTTON: 'form div a',
CONNECTED: '#fxa-connected-heading',
SUCCESS: '.success',
SUCCESS_DIFFERENT_BROWSER: '.success-not-authenticated',
SUCCESS_DIFFERENT_BROWSER: '#success-not-authenticated',
SUCCESS_SAME_BROWSER: '.success-authenticated',
TEXT_INSTALL_FROM_OTHER: '#install-mobile-firefox-other',
TEXT_INSTALL_FX_ANDROID: '#install-mobile-firefox-android',
@ -389,12 +389,12 @@ module.exports = {
ENTER_EMAIL: {
EMAIL: 'input[type=email]',
ERROR: '.error',
SYNC_DESCRIPTION: '.sync-description',
FIREFOX_FAMILY_SERVICES: '.firefox-family-services',
SYNC_DESCRIPTION: '#subheader',
FIREFOX_FAMILY_SERVICES: '#firefox-family-services',
HEADER: '#fxa-enter-email-header',
LINK_SUGGEST_EMAIL_DOMAIN_CORRECTION: '#email-suggestion',
LINK_SUGGEST_SYNC: '#suggest-sync a',
SUB_HEADER: '#fxa-enter-email-header .service',
SUB_HEADER: '#subheader',
SUBMIT: 'button[type="submit"]',
SUGGEST_EMAIL_DOMAIN_CORRECTION: '.tooltip-suggest',
TOOLTIP: 'input[type=email] ~ .tooltip',
@ -411,12 +411,12 @@ module.exports = {
},
FORCE_AUTH: {
EMAIL: 'input[type=email]',
EMAIL_NOT_EDITABLE: '.prefillEmail',
EMAIL_NOT_EDITABLE: '#prefillEmail',
HEADER: '#fxa-force-auth-header',
LINK_RESET_PASSWORD: '.reset-password',
LINK_RESET_PASSWORD: '#reset-password',
PASSWORD: 'input[type=password]',
SUB_HEADER: '#fxa-force-auth-header .service',
SUB_HEADER_SYNC: '#fxa-force-auth-header .description',
SUB_HEADER: '#subheader',
SUB_HEADER_SYNC: '#subheader',
},
INLINE_TOTP: {
HEADER: '#fxa-inline-totp-setup',
@ -462,7 +462,7 @@ module.exports = {
PAIR_FAILURE: '#fxa-pair-failure-header',
START_PAIRING: '#start-pairing',
SUPP_SUBMIT: '#supp-approve-btn',
CONNECT_ANOTHER_QR_CODE: '.graphic-connect-another-device-qr-code',
CONNECT_ANOTHER_QR_CODE: '.bg-image-cad-qr-code',
},
PAYMENTS: {
HEADER: '.accepted-cards',
@ -585,12 +585,12 @@ module.exports = {
SUBMIT: 'button[type=submit]',
},
RESET_PASSWORD: {
BACK: '.remember-password',
BACK: '#remember-password',
EMAIL: 'input[type=email]',
ERROR: '.error',
HEADER: '#fxa-reset-password-header',
LINK_ERROR_SIGNUP: '.error a[href="/signup"]',
LINK_SIGNIN: '.remember-password',
LINK_SIGNIN: '#remember-password',
SUBMIT: 'button[type="submit"]',
SUCCESS: '.success',
},
@ -668,15 +668,15 @@ module.exports = {
},
SIGNIN: {
EMAIL: 'input[type=email]',
EMAIL_NOT_EDITABLE: '.prefillEmail',
EMAIL_NOT_EDITABLE: '#prefillEmail',
ERROR: '.error',
HEADER: '#fxa-signin-header',
LINK_USE_DIFFERENT: '.use-different',
LINK_USE_DIFFERENT: '#use-different',
PASSWORD: 'input[type=password]',
RESET_PASSWORD: 'a[href^="/reset_password"]',
SUB_HEADER: '#fxa-signin-header .service',
SUBMIT: 'button[type=submit]',
SUBMIT_USE_SIGNED_IN: '.use-logged-in',
SUBMIT_USE_SIGNED_IN: '#use-logged-in',
TOOLTIP: '.tooltip',
},
SIGNIN_BOUNCED: {
@ -692,18 +692,18 @@ module.exports = {
},
SIGNIN_PASSWORD: {
EMAIL: 'input[type=email]',
EMAIL_NOT_EDITABLE: '.prefillEmail',
EMAIL_NOT_EDITABLE: '#prefillEmail',
ERROR: '.error',
HEADER: '#fxa-signin-password-header',
LINK_FORGOT_PASSWORD: 'a[href^="/reset_password"]',
LINK_USE_DIFFERENT: '.use-different',
LINK_USE_DIFFERENT: '#use-different',
PASSWORD: 'input[type=password]',
SHOW_PASSWORD: '#password ~ .show-password-label',
SUB_HEADER: '#fxa-signin-password-header .service',
SUB_HEADER_ENTER_PW: '#fxa-signin-password-header .description',
SUB_HEADER: '#subheader',
SUB_HEADER_ENTER_PW: '#subheader',
SUCCESS: '.success',
SUBMIT: 'button[type="submit"]',
SUBMIT_USE_SIGNED_IN: '.use-logged-in',
SUBMIT_USE_SIGNED_IN: '#use-logged-in',
TOOLTIP: 'input[type=password] ~ .tooltip',
},
SIGNIN_RECOVERY_CODE: {
@ -719,7 +719,7 @@ module.exports = {
HEADER: '#fxa-sign-in-reported-header',
},
SIGNIN_TOKEN_CODE: {
EMAIL_FIELD: '.verification-email-message',
EMAIL_FIELD: '#verification-email-message',
ERROR: '.error',
HEADER: '#fxa-signin-code-header',
INPUT: '.otp-code',
@ -771,7 +771,7 @@ module.exports = {
ERROR: '.error',
ERROR_PASSWORDS_DO_NOT_MATCH: '.error',
HEADER: '#fxa-signup-password-header',
LINK_USE_DIFFERENT: '.use-different',
LINK_USE_DIFFERENT: '#use-different',
MARKETING_EMAIL_OPTIN: 'input.marketing-email-optin',
PASSWORD: '#password',
PASSWORD_BALLOON,

Просмотреть файл

@ -275,7 +275,7 @@ registerSuite('cached signin', {
.then(testElementExists(selectors.SIGNIN_TOKEN_CODE.HEADER))
// ensure signin page is visible otherwise credentials might
// not be cleared by clicking .use-different
// not be cleared by clicking #use-different
.then(
openPage(
ENTER_EMAIL_URL,

Просмотреть файл

@ -54,7 +54,7 @@ function testAtConfirmScreen(email) {
return this.parent
.then(testElementExists(selectors.CONFIRM_SIGNUP_CODE.HEADER))
.then(
testElementTextInclude(selectors.SIGNIN_UNBLOCK.EMAIL_FIELD, email)
testElementTextInclude(selectors.CONFIRM_SIGNUP_CODE.EMAIL_FIELD, email)
);
};
}

Просмотреть файл

@ -243,13 +243,21 @@ function parseCssUrls(content, base) {
ast.stylesheet.rules.forEach(function (rule) {
if (rule.type === 'font-face' || rule.type === 'rule') {
rule.declarations.forEach(function (declaration) {
extend(urls, findCssUrlMatches(declaration.value, base));
if (
declaration.value &&
// exclude inlined SVGs from the resource availability check
!declaration.value.includes('data:image/svg+xml')
) {
extend(urls, findCssUrlMatches(declaration.value, base));
}
});
} else if (rule.type === 'media') {
rule.rules.forEach(function (mediaRule) {
mediaRule.declarations.forEach(function (declaration) {
extend(urls, findCssUrlMatches(declaration.value, base));
});
if (mediaRule.declarations) {
mediaRule.declarations.forEach(function (declaration) {
extend(urls, findCssUrlMatches(declaration.value, base));
});
}
});
}
});

Просмотреть файл

@ -207,9 +207,6 @@ const webpackConfig = {
{
loader: 'css-loader',
},
{
loader: 'postcss-loader',
},
{
loader: 'sass-loader',
},

Просмотреть файл

@ -37,6 +37,7 @@ module.exports = {
width: {
7: '1.75rem',
18: '4.5rem',
120: '30rem',
},
minWidth: {
sm: '27rem',
@ -54,6 +55,7 @@ module.exports = {
32: '8rem',
48: '12rem',
64: '16rem',
100: '25rem',
},
inset: {
'1/2': '50%',
@ -88,6 +90,15 @@ module.exports = {
outline: {
'black-dotted': '1px dotted #000',
},
keyframes: {
'fade-in': {
'0%': { opacity: '0.01' },
'100%': { opacity: '1' },
},
},
animation: {
'delayed-fade-in': 'fade-in 1s linear 5s forwards',
},
},
screens: {
mobileLandscape: '480px',

Просмотреть файл

@ -0,0 +1,17 @@
/* 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/. */
.transition-standard {
@apply transition duration-150;
&:active {
@apply transition duration-150;
}
}
@media (hover: hover) {
.transition-standard:hover {
@apply transition duration-150;
}
}

Просмотреть файл

@ -0,0 +1,95 @@
/* 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/. */
@layer components {
.cta-neutral,
.cta-caution,
.cta-primary {
@apply rounded w-full inline-block text-center border font-header box-border transition-standard;
}
.cta-base-p {
@apply py-2 px-5;
}
.cta-neutral {
@apply bg-grey-10 border-grey-200;
&:active {
@apply border-grey-400 bg-grey-100 text-grey-400;
}
&:focus {
@apply bg-white;
}
&:disabled {
@apply bg-white text-grey-300 border-grey-200 cursor-not-allowed;
}
}
.cta-primary {
@apply bg-blue-500 border-blue-600 text-white;
&:active {
@apply bg-blue-800 border-blue-800;
}
&:focus {
@apply border-0;
}
&:disabled {
@apply bg-blue-500/40 border-transparent text-white/50 cursor-not-allowed;
}
}
.cta-caution {
@apply bg-red-500 border-red-600 text-white;
&:active {
@apply bg-red-800 border-red-800;
}
&:focus {
@apply border-transparent outline-dotted outline-black;
}
&:disabled {
@apply bg-red-500/40 border-transparent text-white/50 cursor-not-allowed;
}
}
.cta-base {
@apply text-base mt-6;
}
@media (hover: hover) {
.cta-neutral:hover:not(:disabled):not(:active) {
@apply border-grey-200 bg-grey-100 text-grey-400;
}
.cta-primary:hover:not(:disabled):not(:active) {
@apply bg-blue-600 border-blue-600;
/* TEMP HACK until all buttons are TWified in content-server */
@apply text-white no-underline;
}
.cta-caution:hover:not(:disabled):not(:active) {
@apply bg-red-600 border-red-600;
}
}
@screen mobileLandscape {
.cta-base {
@apply text-xs py-1 px-5 mt-0;
}
.cta-caution,
.cta-primary,
.cta-neutral {
@apply w-auto;
}
}
}

Просмотреть файл

@ -1,5 +1,12 @@
/* 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/. */
/*
This file gathers all stylesheets in fxa-react, so that they can easily
be imported in other packages that don't want to import tailwind.css.
*/
@import './animations.css';
@import './links.css';
@import './portal.css';
@import './ctas.css';

Просмотреть файл

@ -0,0 +1,28 @@
/* 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/. */
.link-blue {
@apply underline text-blue-500 rounded-sm;
&:active {
@apply text-blue-800;
}
}
.link-grey {
@apply underline text-grey-500 rounded-sm;
&:active {
@apply text-grey-500;
}
}
@media (hover: hover) {
.link-blue:hover {
@apply text-blue-600;
}
.link-grey:hover {
@apply text-grey-500;
}
}

Просмотреть файл

@ -1,5 +1,9 @@
@import './index.css';
/* 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/. */
@tailwind base;
@tailwind components;
@tailwind utilities;
@import './index.css';

Просмотреть файл

@ -5,7 +5,7 @@
"private": true,
"scripts": {
"postinstall": "../../_scripts/clone-l10n.sh fxa-settings",
"build-css": "node-sass ./src/styles/tailwind.scss ./src/styles/tailwind.out.pre-transform.css && tailwindcss -i ./src/styles/tailwind.out.pre-transform.css -o ./src/styles/tailwind.out.css",
"build-css": "node-sass ./src/styles/tailwind.scss ./src/styles/tailwind.out.pre-transform.css && tailwindcss -i ./src/styles/tailwind.out.pre-transform.css -o ./src/styles/tailwind.out.css --postcss",
"build-storybook": "NODE_ENV=production STORYBOOK_BUILD=1 npm run build-css && build-storybook",
"build": "tsc --build ../fxa-react && NODE_ENV=production npm run build-css && SKIP_PREFLIGHT_CHECK=true INLINE_RUNTIME_CHUNK=false rescripts build",
"eject": "react-scripts eject",

Просмотреть файл

@ -1,6 +1,7 @@
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
},

Просмотреть файл

@ -1,91 +0,0 @@
// 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/.
.cta-neutral,
.cta-caution,
.cta-primary {
@apply rounded w-full inline-block text-center border font-header box-border transition-standard;
}
.cta-base-p {
@apply py-2 px-5;
}
.cta-neutral {
@apply bg-grey-10 border-grey-200;
&:active {
@apply border-grey-400 bg-grey-100 text-grey-400;
}
&:focus {
@apply bg-white;
}
&:disabled {
@apply bg-white text-grey-300 border-grey-200 cursor-not-allowed;
}
}
.cta-primary {
@apply bg-blue-500 border-blue-600 text-white;
&:active {
@apply bg-blue-800 border-blue-800;
}
&:focus {
@apply border-0;
}
&:disabled {
@apply bg-blue-500/40 border-transparent text-white/50 cursor-not-allowed;
}
}
.cta-caution {
@apply bg-red-500 border-red-600 text-white;
&:active {
@apply bg-red-800 border-red-800;
}
&:focus {
@apply border-transparent outline-dotted outline-black;
}
&:disabled {
@apply bg-red-500/40 border-transparent text-white/50 cursor-not-allowed;
}
}
.cta-base {
@apply text-base mt-6;
}
@media (hover: hover) {
.cta-neutral:hover:not(:disabled) {
@apply border-grey-200 bg-grey-100 text-grey-400;
}
.cta-primary:hover:not(:disabled) {
@apply bg-blue-600 border-blue-600;
}
.cta-caution:hover:not(:disabled) {
@apply bg-red-600 border-red-600;
}
}
@screen mobileLandscape {
.cta-base {
@apply text-xs py-1 px-5 mt-0;
}
.cta-caution,
.cta-primary,
.cta-neutral {
@apply w-auto;
}
}

Просмотреть файл

@ -9,10 +9,10 @@
// We can remove `stylelint-disable` when Settings is no longer using SCSS, #13478
/* stylelint-disable */
@import 'fxa-react/styles/index.css';
@import './2fa.scss';
@import './animations';
@import './fonts';
@import './ctas.scss';
@import './unit-row.scss';
@import './drop-down-menu.scss';
@import './cropper.scss';
@ -24,37 +24,11 @@ body {
@apply text-base font-body bg-grey-10 text-grey-600;
}
.link-blue {
@apply underline text-blue-500;
&:active {
@apply text-blue-800;
}
}
.nav-anchor {
position: absolute;
top: -5em;
}
.transition-standard {
@apply transition duration-150;
&:active {
@apply transition duration-150;
}
}
@media (hover: hover) {
.link-blue:hover {
@apply text-blue-600;
}
.transition-standard:hover {
@apply transition duration-150;
}
}
@layer utilities {
.break-word {
word-break: break-word;

134
yarn.lock
Просмотреть файл

@ -12333,6 +12333,25 @@ __metadata:
languageName: node
linkType: hard
"assets@npm:^3.0.0":
version: 3.0.1
resolution: "assets@npm:3.0.1"
dependencies:
async: ^2.5.0
bluebird: ^3.4.6
calipers: ^2.0.0
calipers-gif: ^2.0.0
calipers-jpeg: ^2.0.0
calipers-png: ^2.0.0
calipers-svg: ^2.0.0
calipers-webp: ^2.0.0
glob: ^7.0.6
lodash: ^4.15.0
mime: ^2.4.0
checksum: 4ef7ccd4b255a88ba49a1455f0a489db4e5c99e809ede94043789eb066ae1ca8e8ebd89dc43734248c8d2bfeb9a2957403d6af52c40acb2b324886e904d79bb8
languageName: node
linkType: hard
"assign-symbols@npm:^1.0.0":
version: 1.0.0
resolution: "assign-symbols@npm:1.0.0"
@ -12495,6 +12514,15 @@ __metadata:
languageName: node
linkType: hard
"async@npm:^2.5.0":
version: 2.6.4
resolution: "async@npm:2.6.4"
dependencies:
lodash: ^4.17.14
checksum: a52083fb32e1ebe1d63e5c5624038bb30be68ff07a6c8d7dfe35e47c93fc144bd8652cbec869e0ac07d57dde387aa5f1386be3559cdee799cb1f789678d88e19
languageName: node
linkType: hard
"async@npm:^3.2.3":
version: 3.2.3
resolution: "async@npm:3.2.3"
@ -14031,7 +14059,7 @@ __metadata:
languageName: node
linkType: hard
"bluebird@npm:>=2.2.2, bluebird@npm:^3.3.5, bluebird@npm:^3.5.0, bluebird@npm:^3.5.5, bluebird@npm:^3.7.2":
"bluebird@npm:3.x.x, bluebird@npm:>=2.2.2, bluebird@npm:^3.3.5, bluebird@npm:^3.4.6, bluebird@npm:^3.5.0, bluebird@npm:^3.5.5, bluebird@npm:^3.7.2":
version: 3.7.2
resolution: "bluebird@npm:3.7.2"
checksum: 869417503c722e7dc54ca46715f70e15f4d9c602a423a02c825570862d12935be59ed9c7ba34a9b31f186c017c23cac6b54e35446f8353059c101da73eac22ef
@ -14966,6 +14994,66 @@ __metadata:
languageName: node
linkType: hard
"calipers-gif@npm:^2.0.0":
version: 2.0.0
resolution: "calipers-gif@npm:2.0.0"
dependencies:
bluebird: 3.x.x
peerDependencies:
calipers: 2.x.x
checksum: 9e81fa57bc60f1e6d35cddb7b0ea2a1c4199a6404ea4f1c7902a7040069da7b57b28682f6c37518a8677983ead77e74b2d89e09168da497aae07647906bf0bf9
languageName: node
linkType: hard
"calipers-jpeg@npm:^2.0.0":
version: 2.0.0
resolution: "calipers-jpeg@npm:2.0.0"
dependencies:
bluebird: 3.x.x
peerDependencies:
calipers: 2.x.x
checksum: 8f3a791c30d5adf4de897ed5e0b8d03fc67878ddd6bcb45b396daa2029a26b1ddd4fdd86cbb0a472c9f37af0dcdf896f0dbb9c45d373f98e29f41a1c224cda4b
languageName: node
linkType: hard
"calipers-png@npm:^2.0.0":
version: 2.0.0
resolution: "calipers-png@npm:2.0.0"
dependencies:
bluebird: 3.x.x
peerDependencies:
calipers: 2.x.x
checksum: 814141145a6478c877b147b5e90f3081a9c3680782f99430d9a1c6c9ff0d5f8c422912cb9ef4c79226b2bf5a3afdefb348ca165879712f22826e63727b05752b
languageName: node
linkType: hard
"calipers-svg@npm:^2.0.0":
version: 2.0.1
resolution: "calipers-svg@npm:2.0.1"
dependencies:
bluebird: 3.x.x
checksum: 6340bd2a7ee58e637224a42a417560ffefb15cfb11a98ccb67ad56f9b893bdcd149507b14fe32b03f3e8064322dee522f7eb06ba5173b341b227bbc7042f9e8a
languageName: node
linkType: hard
"calipers-webp@npm:^2.0.0":
version: 2.0.0
resolution: "calipers-webp@npm:2.0.0"
dependencies:
bluebird: 3.x.x
checksum: cb12fa47483b7839b0c6629086f005a7f46ec3c81d7cf4abbbfe6a903f02dc2c358558411f34efb6f95a43b98401a56530b5078e415297ad03232ec1158013ad
languageName: node
linkType: hard
"calipers@npm:^2.0.0":
version: 2.0.1
resolution: "calipers@npm:2.0.1"
dependencies:
bluebird: 3.x.x
checksum: fb585634c14a2245683af867e6402eeb6389d1903708efd04d3f879e66718834c8179b4cd981bbf875a85aaa21391e3cf7e4f0a1458dd24f90d48fbcdd303c17
languageName: node
linkType: hard
"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2":
version: 1.0.2
resolution: "call-bind@npm:1.0.2"
@ -22250,6 +22338,7 @@ fsevents@~2.1.1:
"@sentry/tracing": ^6.19.1
"@testing-library/react": ^12.1.5
"@types/backbone": ^1.4.10
"@types/postcss-import": ^14
"@types/sinon-chai": 3.2.5
"@types/sinon-express-mock": 1.3.9
asmcrypto.js: ^0.22.0
@ -22355,7 +22444,9 @@ fsevents@~2.1.1:
photon-colors: 1.0.3
pm2: ^5.1.2
postcss: ^8.4.14
postcss-assets: ^6.0.0
postcss-cli: 7.1.1
postcss-import: ^14.1.0
postcss-loader: 4.2.0
prettier: ^2.3.1
proxyquire: ^2.1.3
@ -23610,6 +23701,20 @@ fsevents@~2.1.1:
languageName: node
linkType: hard
"glob@npm:^7.0.6":
version: 7.2.3
resolution: "glob@npm:7.2.3"
dependencies:
fs.realpath: ^1.0.0
inflight: ^1.0.4
inherits: 2
minimatch: ^3.1.1
once: ^1.3.0
path-is-absolute: ^1.0.0
checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133
languageName: node
linkType: hard
"glob@npm:~7.1.1, glob@npm:~7.1.6, glob@npm:~7.1.7":
version: 7.1.7
resolution: "glob@npm:7.1.7"
@ -30087,7 +30192,7 @@ fsevents@~2.1.1:
languageName: node
linkType: hard
"lodash@npm:4.17.21, lodash@npm:4.17.x, lodash@npm:>=3.5 <5, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.17.5, lodash@npm:^4.7.0, lodash@npm:^4.8.0, lodash@npm:~4.17.12, lodash@npm:~4.17.15, lodash@npm:~4.17.19, lodash@npm:~4.17.21":
"lodash@npm:4.17.21, lodash@npm:4.17.x, lodash@npm:>=3.5 <5, lodash@npm:^4.15.0, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.17.5, lodash@npm:^4.7.0, lodash@npm:^4.8.0, lodash@npm:~4.17.12, lodash@npm:~4.17.15, lodash@npm:~4.17.19, lodash@npm:~4.17.21":
version: 4.17.21
resolution: "lodash@npm:4.17.21"
checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7
@ -31128,7 +31233,7 @@ fsevents@~2.1.1:
languageName: node
linkType: hard
"minimatch@npm:^3.1.2":
"minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
version: 3.1.2
resolution: "minimatch@npm:3.1.2"
dependencies:
@ -34734,6 +34839,18 @@ fsevents@~2.1.1:
languageName: node
linkType: hard
"postcss-assets@npm:^6.0.0":
version: 6.0.0
resolution: "postcss-assets@npm:6.0.0"
dependencies:
assets: ^3.0.0
postcss-functions: ^4.0.2
peerDependencies:
postcss: ^8.2.15
checksum: 7df91fd857aa9a2a0361c786182c16e75cc98cf689c280cdd71860d27606678909399d5a0f8865d7c490c697b7aab505113fe58f2d49720e579d2cc901a1ef8f
languageName: node
linkType: hard
"postcss-attribute-case-insensitive@npm:^4.0.1":
version: 4.0.2
resolution: "postcss-attribute-case-insensitive@npm:4.0.2"
@ -35006,6 +35123,17 @@ fsevents@~2.1.1:
languageName: node
linkType: hard
"postcss-functions@npm:^4.0.2":
version: 4.0.2
resolution: "postcss-functions@npm:4.0.2"
dependencies:
postcss-value-parser: ^4.0.0
peerDependencies:
postcss: ^8.0.0
checksum: de837e5b0fd57f323a7f08482f0c9291982ce850cdbac6a93327176eabca40f085fa8fb40b20e5c1c877bcb740fdfc567ae6509e09f6ade9e79ecedb9c02eed0
languageName: node
linkType: hard
"postcss-gap-properties@npm:^2.0.0":
version: 2.0.0
resolution: "postcss-gap-properties@npm:2.0.0"