diff --git a/bedrock/firefox/templates/firefox/nothing-personal/includes/browser-macro.html b/bedrock/firefox/templates/firefox/nothing-personal/includes/browser-macro.html
index 2168cc53b87..45aa055cfe6 100644
--- a/bedrock/firefox/templates/firefox/nothing-personal/includes/browser-macro.html
+++ b/bedrock/firefox/templates/firefox/nothing-personal/includes/browser-macro.html
@@ -5,11 +5,12 @@
#}
{% macro browser_border(
+ id=None,
class=None,
heading=None,
aria_label=None
) -%}
-
+
{% if heading and aria_label %}
{{ heading }}
diff --git a/bedrock/firefox/templates/firefox/nothing-personal/index.html b/bedrock/firefox/templates/firefox/nothing-personal/index.html
index 9e4af0d4342..21b276d53b8 100644
--- a/bedrock/firefox/templates/firefox/nothing-personal/index.html
+++ b/bedrock/firefox/templates/firefox/nothing-personal/index.html
@@ -12,6 +12,7 @@
{% block page_css %}
{{ css_bundle('firefox-nothing-personal') }}
+ {{ css_bundle('protocol-newsletter') }}
{% endblock %}
{% block page_title_prefix %}Nothing Personal{% endblock %}
@@ -181,6 +182,22 @@ Ok, what’s the privacy-catch?
{% endcall %}
+
+ {% call browser_border(id="newsletter-signup", class='mzp-l-content mzp-t-content-md mzp-t-content-nospace', heading='Newsletter') %}
+
+
[Sign up for our newsletter]
+
+ {{ email_newsletter_form(
+ include_title=False,
+ include_language=False,
+ include_country=False,
+ newsletters='mozilla-and-you, nothing-personal-college-interest',
+ multi_opt_in_required=True
+ )}}
+
+
By subscribing, you’ll receive Mozilla updates, plus exclusive college-related content if you opt in. You may unsubscribe from either at any time.
+
+ {% endcall %}
@@ -219,4 +236,5 @@
Ok, what’s the privacy-catch?
{% block js %}
{{ js_bundle('firefox-nothing-personal') }}
+ {{ js_bundle('newsletter') }}
{% endblock %}
diff --git a/bedrock/newsletter/forms.py b/bedrock/newsletter/forms.py
index e1413e91f58..010a760e3a4 100644
--- a/bedrock/newsletter/forms.py
+++ b/bedrock/newsletter/forms.py
@@ -175,6 +175,7 @@ class NewsletterFooterForm(forms.Form):
choice_labels = {
"mozilla-foundation": ftl("multi-newsletter-form-checkboxes-label-mozilla"),
"mozilla-and-you": ftl("multi-newsletter-form-checkboxes-label-firefox"),
+ "nothing-personal-college-interest": "Exclusive college-related content", # issue 15218.
}
email = forms.EmailField(widget=EmailInput(attrs={"required": "required", "data-testid": "newsletter-email-input"}))
@@ -188,7 +189,7 @@ class NewsletterFooterForm(forms.Form):
# has to take a newsletters argument so it can figure
# out which languages to list in the form.
- def __init__(self, newsletters, locale, data=None, *args, **kwargs):
+ def __init__(self, newsletters, locale, data=None, multi_opt_in_required=False, *args, **kwargs):
regions = product_details.get_regions(locale)
regions = sorted(iter(regions.items()), key=itemgetter(1))
@@ -201,6 +202,7 @@ def __init__(self, newsletters, locale, data=None, *args, **kwargs):
# form validation will work with submitted data
newsletters = ["mozilla-and-you"]
+ is_multi_newsletter = len(newsletters) > 1
lang = locale.lower()
if "-" in lang:
lang, country = lang.split("-", 1)
@@ -231,7 +233,12 @@ def __init__(self, newsletters, locale, data=None, *args, **kwargs):
lang_label = ftl_lazy("newsletter-form-select-language", fallback="newsletter-form-available-languages")
self.fields["lang"] = forms.TypedChoiceField(widget=lang_widget, choices=lang_choices, initial=lang, required=False, label=lang_label)
self.fields["newsletters"].choices = [(n, self.choice_labels.get(n, n)) for n in newsletters]
- self.fields["newsletters"].initial = newsletters
+
+ # Automatically check newsletter choices unless opt-in is explicitly required.
+ if is_multi_newsletter and multi_opt_in_required:
+ self.fields["newsletters"].initial = None
+ else:
+ self.fields["newsletters"].initial = newsletters
def clean_newsletters(self):
return validate_newsletters(self.cleaned_data["newsletters"])
diff --git a/bedrock/newsletter/templatetags/helpers.py b/bedrock/newsletter/templatetags/helpers.py
index cefe879311a..54a7d1fe0df 100644
--- a/bedrock/newsletter/templatetags/helpers.py
+++ b/bedrock/newsletter/templatetags/helpers.py
@@ -38,6 +38,7 @@ def email_newsletter_form(
spinner_color=None,
email_label=None,
email_placeholder=None,
+ multi_opt_in_required=False, # switches multi-newsletter forms to be opt-in rather than pre-checked.
):
request = ctx["request"]
context = ctx.get_all()
@@ -49,7 +50,7 @@ def email_newsletter_form(
form = ctx.get("newsletter_form", None)
if not form:
- form = NewsletterFooterForm(newsletters, get_locale(request))
+ form = NewsletterFooterForm(newsletters, get_locale(request), multi_opt_in_required=multi_opt_in_required)
if isinstance(newsletters, list):
newsletters = ", ".join(newsletters)
diff --git a/bedrock/newsletter/tests/test_footer_form.py b/bedrock/newsletter/tests/test_footer_form.py
index 9406077b460..12ddce20add 100644
--- a/bedrock/newsletter/tests/test_footer_form.py
+++ b/bedrock/newsletter/tests/test_footer_form.py
@@ -60,3 +60,20 @@ def test_language_selected(self):
resp = self.client.get(reverse(self.view_name))
doc = pq(resp.content)
assert doc('#id_lang option[selected="selected"]').val() == ""
+
+ @override_settings(DEV=True)
+ def test_newsletters_selected(self):
+ """
+ By default both newsletters should be checked.
+ """
+ with self.activate_locale("en-US"):
+ resp = self.client.get(reverse(self.view_name))
+ doc = pq(resp.content)
+ assert doc('#id_newsletters_0[checked="checked"]').length == 1
+ assert doc('#id_newsletters_1[checked="checked"]').length == 1
+
+ with self.activate_locale("en-US"):
+ resp = self.client.get(reverse("firefox.nothing-personal.index"))
+ doc = pq(resp.content)
+ assert doc('#id_newsletters_0[checked="checked"]').length == 0
+ assert doc('#id_newsletters_1[checked="checked"]').length == 0
diff --git a/media/css/firefox/nothing-personal/_browser.scss b/media/css/firefox/nothing-personal/_browser.scss
index fea36598d6f..6623945f840 100644
--- a/media/css/firefox/nothing-personal/_browser.scss
+++ b/media/css/firefox/nothing-personal/_browser.scss
@@ -102,10 +102,10 @@
.c-browser-window-top {
h2 {
- @include text-title-xl;
line-height: 1;
margin: 0;
padding-right: $spacing-lg;
+ @include text-title-xl;
}
&::after {
diff --git a/media/css/firefox/nothing-personal/_header.scss b/media/css/firefox/nothing-personal/_header.scss
index c48f2207dd8..cae144544c0 100644
--- a/media/css/firefox/nothing-personal/_header.scss
+++ b/media/css/firefox/nothing-personal/_header.scss
@@ -2,6 +2,12 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+@media (prefers-reduced-motion: no-preference) {
+ html {
+ scroll-padding-top: 120px; /* height of sticky header */
+ }
+}
+
.c-page-header {
background-color: $browser-background;
border-bottom: $border-black;
@@ -56,11 +62,11 @@
justify-self: end;
p {
- @include text-body-lg;
display: block;
font-family: 'Fira Mono', 'Andale Mono', monospace;
font-weight: 500;
margin: 0 $spacing-md 0 0;
+ @include text-body-lg;
}
}
}
diff --git a/media/css/firefox/nothing-personal/_primary-cta.scss b/media/css/firefox/nothing-personal/_primary-cta.scss
index 67182c7276d..68b7a5410d6 100644
--- a/media/css/firefox/nothing-personal/_primary-cta.scss
+++ b/media/css/firefox/nothing-personal/_primary-cta.scss
@@ -121,7 +121,6 @@ html.android {
.mzp-c-button,
#protocol-nav-download-firefox > .mzp-c-button {
- @include text-body-lg;
padding: $spacing-sm $spacing-lg;
background-color: $color-yellow-20;
background-image: linear-gradient(to right,$color-yellow-20, $color-orange-50, $color-yellow-20, $color-yellow-20);
@@ -130,6 +129,7 @@ html.android {
color: $color-black;
border-color: $color-black;
transition: all 0.3s ease-out;
+ @include text-body-lg;
@media (prefers-reduced-motion: reduce) {
background-image: linear-gradient(to right,$color-yellow-20, $color-orange-50);
diff --git a/media/css/firefox/nothing-personal/_sticky-note.scss b/media/css/firefox/nothing-personal/_sticky-note.scss
index 7f7f9fe7fb1..483dcef66ca 100644
--- a/media/css/firefox/nothing-personal/_sticky-note.scss
+++ b/media/css/firefox/nothing-personal/_sticky-note.scss
@@ -3,7 +3,6 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
.c-sticky-note {
- @include text-body-lg;
background-image: url('/media/img/firefox/nothing-personal/sticky-note-bg.svg');
background-repeat: no-repeat;
background-size: contain;
@@ -13,6 +12,7 @@
padding: $spacing-xl;
transform: rotate(11deg);
text-align: center;
+ @include text-body-lg;
&.c-detached-sticky {
position: relative;
@@ -67,11 +67,11 @@
margin-bottom: 0;
a {
- @include text-body-lg;
border: 0;
background: transparent;
color: $color-black;
padding: 0;
+ @include text-body-lg;
&:hover,
&:focus,
diff --git a/media/css/firefox/nothing-personal/styles.scss b/media/css/firefox/nothing-personal/styles.scss
index 4698656d81e..0bbb5fb412f 100644
--- a/media/css/firefox/nothing-personal/styles.scss
+++ b/media/css/firefox/nothing-personal/styles.scss
@@ -86,8 +86,8 @@ $mq-tad-smaller-sm: 455px;
}
.c-sign-off {
- @include text-title-xs;
margin: $layout-lg 0;
+ @include text-title-xs;
.c-nothing-personal {
padding: 12px;