Skip to content

Commit 081e643

Browse files
Mazizovaclaude
andcommitted
Wire the footer newsletter form to Brevo
Replaces the disabled "coming soon" form with Brevo's hosted signup form (posts directly to Brevo, no API key on the frontend). Keeps Brevo's structural ids/classes so its own script can intercept the submit and toggle success/error messages inline, but drops its inline styles in favor of the site's own SCSS so it matches the existing dark/light footer design. Updates the Privacy Policy's newsletter provider reference from Mailchimp to Brevo. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent c843080 commit 081e643

4 files changed

Lines changed: 148 additions & 18 deletions

File tree

‎assets/scss/_footer.scss‎

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,27 +36,90 @@
3636
}
3737
}
3838

39+
.footer-newsletter-form-container {
40+
flex: 1;
41+
max-width: 480px;
42+
min-width: 280px;
43+
}
44+
45+
.footer-newsletter-message {
46+
display: none;
47+
font-size: 0.8125rem;
48+
border-radius: 8px;
49+
padding: 0.625rem 0.875rem;
50+
margin-bottom: 0.625rem;
51+
52+
// Brevo's script toggles this modifier class (not inline style) to reveal
53+
// whichever panel applies after a submit — it ships its own stylesheet
54+
// that defines this rule, which we don't load, so we define it ourselves.
55+
&.sib-form-message-panel--active {
56+
display: block;
57+
}
58+
59+
&--error {
60+
color: #ff8080;
61+
background: rgba(#ff4949, 0.12);
62+
border: 1px solid rgba(#ff4949, 0.3);
63+
}
64+
65+
&--success {
66+
color: #4ade80;
67+
background: rgba(#13ce66, 0.12);
68+
border: 1px solid rgba(#13ce66, 0.3);
69+
}
70+
}
71+
3972
.footer-newsletter-form {
4073
display: flex;
4174
gap: 0.625rem;
4275
flex-wrap: wrap;
43-
flex: 1;
44-
max-width: 480px;
45-
min-width: 280px;
76+
align-items: flex-start;
4677

47-
input {
78+
.footer-newsletter-field {
79+
flex: 1;
80+
min-width: 0;
81+
}
82+
83+
.footer-newsletter-label {
84+
position: absolute;
85+
width: 1px;
86+
height: 1px;
87+
overflow: hidden;
88+
clip: rect(0, 0, 0, 0);
89+
white-space: nowrap;
90+
}
91+
92+
.footer-newsletter-field-error {
93+
display: block;
94+
font-size: 0.75rem;
95+
color: #ff8080;
96+
margin-top: 0.375rem;
97+
min-height: 0;
98+
}
99+
100+
.footer-newsletter-honeypot {
101+
display: none;
102+
}
103+
104+
input#EMAIL {
48105
font-family: $font-sans;
49106
font-size: 0.9375rem;
50107
color: $off-white;
51108
background: $dark-card;
52109
border: 1px solid rgba($accent, 0.35);
53110
border-radius: 8px;
54111
padding: 0.875rem 1.125rem;
55-
flex: 1;
56-
min-width: 0;
112+
width: 100%;
57113

58114
&::placeholder { color: darken($muted, 8%); }
59-
&:disabled { cursor: not-allowed; }
115+
}
116+
117+
.sib-form-block__button-with-loader {
118+
border: none;
119+
cursor: pointer;
120+
white-space: nowrap;
121+
122+
.sib-hide-loader-icon { display: none; }
60123
}
61124
}
62125

‎assets/scss/_light-theme.scss‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1035,13 +1035,29 @@
10351035
span { color: #64748b; }
10361036
}
10371037

1038-
.footer-newsletter-form input {
1038+
.footer-newsletter-form input#EMAIL {
10391039
background: #f8f9fc;
10401040
border-color: rgba(0, 200, 255, 0.4);
10411041
color: #0f172a;
10421042
&::placeholder { color: #94a3b8; }
10431043
}
10441044

1045+
.footer-newsletter-message {
1046+
&--error {
1047+
color: #b91c1c;
1048+
background: rgba(#ff4949, 0.08);
1049+
border-color: rgba(#ff4949, 0.25);
1050+
}
1051+
1052+
&--success {
1053+
color: #087f43;
1054+
background: rgba(#13ce66, 0.1);
1055+
border-color: rgba(#13ce66, 0.3);
1056+
}
1057+
}
1058+
1059+
.footer-newsletter-field-error { color: #b91c1c; }
1060+
10451061
.footer-main { border-bottom-color: #dde3ed; }
10461062

10471063
.footer-brand {

‎content/privacy-policy.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ We do not knowingly collect more information than is necessary for the purposes
3636
We use the information we collect to:
3737

3838
- Respond to inquiries submitted through the Contact Us form.
39-
- Send newsletters and updates to subscribers, and manage those communications through Mailchimp.
39+
- Send newsletters and updates to subscribers, and manage those communications through Brevo.
4040
- Maintain and update contact and relationship records in our CRM.
4141
- Understand how visitors use the Site and improve its content and performance, using Google Analytics and Plausible.
4242
- Process form submissions collected via third-party form tools (such as Typeform or Google Forms) for specific initiatives (e.g., event registration, surveys, membership interest forms).
@@ -54,7 +54,7 @@ We work with the following categories of third-party service providers, who proc
5454

5555
- **Google Analytics** — website analytics
5656
- **Plausible** — website analytics
57-
- **Mailchimp** — email newsletter delivery and management
57+
- **Brevo** — email newsletter delivery and management
5858
- **CRM provider** — contact and relationship management
5959
- **Typeform / Google Forms** (or similar) — specific form-based data collection (e.g., event registration, surveys)
6060

‎layouts/partials/footer.html‎

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,46 @@
11
<footer class="site-footer">
22
<div class="footer-inner">
33

4-
{{/* Newsletter isn't wired to a real list yet (Privacy Policy already
5-
commits to Mailchimp for this) — shown disabled rather than faking
6-
a signup, same "Coming soon" treatment as the Press Releases page's
7-
Newsletter channel card. */}}
4+
{{/* Newsletter signup, wired to Brevo. The form posts directly to Brevo's
5+
hosted endpoint (no API key on the frontend); Brevo's own script
6+
(loaded at the bottom of this partial) intercepts the submit and
7+
shows #error-message / #success-message inline instead of
8+
navigating away. Structural ids/classes below (sib-form, EMAIL,
9+
email_address_check, locale, sib-form-block__button-with-loader,
10+
sib-hide-loader-icon) come straight from Brevo's generated embed
11+
code and must stay as-is for that script to find the field. */}}
812
<div class="footer-newsletter">
913
<div class="footer-newsletter-text">
1014
<strong>Stay in the loop</strong>
1115
<span>One email, every so often. No noise — just what matters for MySQL.</span>
1216
</div>
13-
<form class="footer-newsletter-form" title="Coming soon">
14-
<input type="email" placeholder="you@email.com" disabled>
15-
<button type="submit" class="about-btn about-btn--primary about-btn--disabled" disabled>Subscribe</button>
16-
</form>
17+
18+
<div id="sib-form-container" class="footer-newsletter-form-container">
19+
{{/* Brevo's script overwrites this inner text with its own copy once
20+
a submit resolves, so the strings here only matter for the
21+
instant before that happens — kept identical to avoid a flash
22+
of different text. */}}
23+
<div id="error-message" class="sib-form-message-panel footer-newsletter-message footer-newsletter-message--error">
24+
<span class="sib-form-message-panel__inner-text">Your subscription could not be saved. Please try again.</span>
25+
</div>
26+
<div id="success-message" class="sib-form-message-panel footer-newsletter-message footer-newsletter-message--success">
27+
<span class="sib-form-message-panel__inner-text">Your subscription has been successful.</span>
28+
</div>
29+
30+
<form id="sib-form" method="POST" action="https://64f8c957.sibforms.com/serve/MUIFAJ9Hor_z_M6MDKVaoYCTLL191egrhA0H-adYyLsYs26X-XB5NlRM0VoLjVPWLLLwN2VbHg4TmYyTlcBbVXtPX6fEYgO8uH1g2N9S0RDkBdRVtd_SY2BwyCz3FnKaBzq1g-75lcnWlGAffahgO1K1UwVMa0C1B2N8xaY-l3vuxgxy5OjEbkvdmqFIYOEoH0xwvCkNaiScMi5zZA==" data-type="subscription" class="footer-newsletter-form">
31+
<div class="footer-newsletter-field">
32+
<label for="EMAIL" class="footer-newsletter-label">Email address</label>
33+
<input class="input" type="text" id="EMAIL" name="EMAIL" autocomplete="email" inputmode="email" placeholder="you@email.com" data-required="true" required>
34+
<label class="entry__error entry__error--primary footer-newsletter-field-error"></label>
35+
</div>
36+
<button class="sib-form-block__button sib-form-block__button-with-loader about-btn about-btn--primary" form="sib-form" type="submit">
37+
<svg class="icon clickable__icon progress-indicator__icon sib-hide-loader-icon" viewBox="0 0 512 512" aria-hidden="true"><path d="M460.116 373.846l-20.823-12.022c-5.541-3.199-7.54-10.159-4.663-15.874 30.137-59.886 28.343-131.652-5.386-189.946-33.641-58.394-94.896-95.833-161.827-99.676C261.028 55.961 256 50.751 256 44.352V20.309c0-6.904 5.808-12.337 12.703-11.982 83.556 4.306 160.163 50.864 202.11 123.677 42.063 72.696 44.079 162.316 6.031 236.832-3.14 6.148-10.75 8.461-16.728 5.01z"/></svg>
38+
Subscribe
39+
</button>
40+
<input type="text" name="email_address_check" value="" class="footer-newsletter-honeypot" tabindex="-1" autocomplete="off">
41+
<input type="hidden" name="locale" value="en">
42+
</form>
43+
</div>
1744
</div>
1845

1946
<div class="footer-main">
@@ -93,3 +120,27 @@ <h4>Resources</h4>
93120

94121
</div>
95122
</footer>
123+
124+
{{/* Brevo's own signup-form script: reads window.LOCALE/*_MESSAGE globals
125+
and binds to the #sib-form markup above to submit via AJAX and toggle
126+
#error-message/#success-message instead of navigating away. */}}
127+
<script>
128+
window.REQUIRED_CODE_ERROR_MESSAGE = 'Please choose a country code';
129+
window.LOCALE = 'en';
130+
window.EMAIL_INVALID_MESSAGE = window.SMS_INVALID_MESSAGE = "The information provided is invalid. Please review the field format and try again.";
131+
window.REQUIRED_ERROR_MESSAGE = "This field cannot be left blank. ";
132+
window.GENERIC_INVALID_MESSAGE = "The information provided is invalid. Please review the field format and try again.";
133+
window.INVALID_NUMBER = "The information provided is invalid. Please review the field format and try again.";
134+
window.INVALID_DATE = "Please enter a valid date";
135+
window.REQUIRED_MULTISELECT_MESSAGE = 'Please select at least 1 option';
136+
window.translation = {
137+
common: {
138+
selectedList: '{quantity} list selected',
139+
selectedLists: '{quantity} lists selected',
140+
selectedOption: '{quantity} selected',
141+
selectedOptions: '{quantity} selected',
142+
}
143+
};
144+
var AUTOHIDE = Boolean(0);
145+
</script>
146+
<script defer src="https://sibforms.com/forms/end-form/build/main.js"></script>

0 commit comments

Comments
 (0)