mp-design-system 1.2.30 → 1.2.35

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. package/dist/build/js/app.js +1 -1
  2. package/dist/build/js/app.js.map +1 -1
  3. package/dist/build/scss/library.css +1 -1
  4. package/dist/build/scss/library.css.map +1 -1
  5. package/dist/build/scss/main.css +1 -1
  6. package/dist/build/scss/main.css.map +1 -1
  7. package/package.json +1 -1
  8. package/src/_includes/components/card/card.njk +1 -1
  9. package/src/_includes/components/eyebrow/eyebrow.scss +1 -1
  10. package/src/_includes/components/hero/hero.njk +18 -1
  11. package/src/_includes/components/hero/hero.scss +29 -1
  12. package/src/_includes/components/input/input.njk +1 -1
  13. package/src/_includes/components/internal-nav/internal-nav.config.js +1 -1
  14. package/src/_includes/components/internal-nav/internal-nav.scss +5 -4
  15. package/src/_includes/components/scroll-spy/scroll-spy.scss +1 -1
  16. package/src/_includes/components/signpost/signpost.config.js +8 -1
  17. package/src/_includes/components/signpost/signpost.njk +9 -2
  18. package/src/_includes/components/signpost/signpost.scss +18 -2
  19. package/src/_includes/components/twi/twi.scss +1 -0
  20. package/src/assets/js/imports/internal-nav.js +20 -2
  21. package/src/assets/js/imports/scroll-spy.js +10 -2
  22. package/src/assets/scss/objects/grid.scss +12 -1
  23. package/src/brand/resources.njk +28 -23
  24. package/src/prototype/events-hub.njk +80 -19
  25. package/src/prototype/index.njk +27 -12
  26. package/src/prototype/range.njk +1 -1
  27. package/src/static/pdf/Power of one Content guidance.pdf +0 -0
  28. package/src/static/svg/icon-globe-alt--white.svg +4 -0
  29. package/src/static/svg/icon-globe-alt.svg +1 -1
  30. package/src/static/svg/icon-live-webinars--white.svg +6 -0
  31. package/src/static/svg/icon-live-webinars.svg +3 -3
  32. package/src/static/svg/icon-recorded-webinars--white.svg +4 -0
  33. package/src/static/svg/icon-recorded-webinars.svg +1 -1
  34. package/src/static/svg/{icon-user-trainings.svg → icon-user-training--white.svg} +2 -2
  35. package/src/static/svg/icon-user-training.svg +5 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mp-design-system",
3
- "version": "1.2.30",
3
+ "version": "1.2.35",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "dev": "npm-run-all --parallel bundle:*",
@@ -65,7 +65,7 @@
65
65
  {% if hasImage %}
66
66
  <figure class="c-card__image">
67
67
  <a href="{{ link }}">
68
- <img src="{{ params.image.src }}" alt="{{ params.image.alt }}" />
68
+ <img class="{{ params.image.classes }}" src="{{ params.image.src }}" alt="{{ params.image.alt }}" />
69
69
  </a>
70
70
  </figure>
71
71
  {% endif %}
@@ -33,7 +33,7 @@
33
33
  }
34
34
 
35
35
  &--utility-orange {
36
- background-color: color('utility-orange');
36
+ background-color: color('utility-orange', 'step-1');
37
37
  color: color('grey');
38
38
  }
39
39
  }
@@ -1,7 +1,7 @@
1
- {% from "components/button/macro.njk" import button %}
2
1
  {% from "components/breadcrumb/macro.njk" import breadcrumb %}
3
2
  {% from "components/button/macro.njk" import button %}
4
3
  {% from "components/icon/macro.njk" import icon %}
4
+ {% from "components/input/macro.njk" import input %}
5
5
 
6
6
  {%- set classes = 'mp c-hero' -%}
7
7
  {% if params.classes %}{%- set classes = classes + ' ' + params.classes -%}{% endif %}
@@ -29,6 +29,23 @@
29
29
  <header class="u-flow--m">
30
30
  <h1 class="c-h c-h--page-title">{{ params.title }}</h1>
31
31
  {% if params.subtitle %}<p class="u-step-1">{{ params.subtitle }}</p>{% endif %}
32
+ {% if params.search %}
33
+ <form class="c-hero__search u-split">
34
+ {{ input({
35
+ name: 'hero-search',
36
+ id: 'hero-search',
37
+ type: 'search',
38
+ hideLabel: true,
39
+ placeholder: params.search.placeholder
40
+ }) }}
41
+ {{ button({
42
+ name: 'hero-search-submit',
43
+ id: 'hero-search-submit',
44
+ label: params.search.buttonText or 'Search',
45
+ link: ''
46
+ }) }}
47
+ </form>
48
+ {% endif %}
32
49
  {{ params.content | safe }}
33
50
  </header>
34
51
 
@@ -34,8 +34,9 @@
34
34
  bottom: 0;
35
35
  @include space('right', 'gutter');
36
36
  z-index: 2;
37
- }
38
37
 
38
+ }
39
+
39
40
  &:after {
40
41
  content: '';
41
42
  box-shadow: -1px 0 color('white');
@@ -48,6 +49,17 @@
48
49
  bottom: 0;
49
50
  right: 0;
50
51
  }
52
+
53
+ @at-root {
54
+ .c-hero--extend .u-wrap {
55
+ &:before {
56
+ right: 0;
57
+ }
58
+ &:after {
59
+ right: calc(-1 * var(--gutter));
60
+ }
61
+ }
62
+ }
51
63
  }
52
64
 
53
65
  &__content {
@@ -55,6 +67,10 @@
55
67
  z-index: 5;
56
68
  max-width: 828px;
57
69
 
70
+ .c-hero--padded & {
71
+ @include padding('m-l', 0)
72
+ }
73
+
58
74
  & > * + * {
59
75
  @include margin-top('m');
60
76
  }
@@ -325,4 +341,16 @@
325
341
  z-index: 1;
326
342
  }
327
343
  }
344
+
345
+ &:has(+ .u-margin-top-negative-2xl) {
346
+ .u-wrap {
347
+ @include space('padding-bottom', '4xl')
348
+ }
349
+ }
350
+
351
+ &__search {
352
+ :first-child {
353
+ flex-grow: 1;
354
+ }
355
+ }
328
356
  }
@@ -10,4 +10,4 @@
10
10
  {% if params.button %}
11
11
  </div>
12
12
  {% endif %}
13
- {% endinputWrapper %}
13
+ {% endinputWrapper %}
@@ -17,7 +17,7 @@ module.exports = {
17
17
  {
18
18
  title: 'Sticky on scroll',
19
19
  context: {
20
- classes: 'u-sticky',
20
+ classes: 'c-internal-nav--sticky',
21
21
  title: 'Mastersizer range',
22
22
  links: [
23
23
  { link: '#overview', label: 'Overview' },
@@ -3,6 +3,11 @@
3
3
  border-bottom: 1px solid transparent;
4
4
  transition: 200ms all;
5
5
 
6
+ &--sticky {
7
+ position: sticky;
8
+ top: -1px;
9
+ }
10
+
6
11
  &--stuck {
7
12
  @extend .u-bg-white;
8
13
  border-bottom-color: color('grey', 'step-2');
@@ -66,8 +71,4 @@
66
71
 
67
72
  .c-hero + .c-internal-nav {
68
73
  margin-top: calc(var(--gutter) * -1);
69
- }
70
-
71
- .c-internal-nav.u-sticky {
72
- top: -1px;
73
74
  }
@@ -51,4 +51,4 @@
51
51
  margin-bottom: 0.5em;
52
52
  vertical-align: top;
53
53
  }
54
- }
54
+ }
@@ -21,9 +21,16 @@ module.exports = {
21
21
  direction: 'vertical',
22
22
  size: 'l',
23
23
  color: 'blue',
24
- icon: 'icon-user-training',
24
+ icon: 'icon-user-training--white',
25
25
  description: false
26
26
  }
27
+ },
28
+ {
29
+ title: "Bordered",
30
+ preview: 'cards-two',
31
+ context: {
32
+ name: 'bordered'
33
+ }
27
34
  }
28
35
  ]
29
36
  }
@@ -1,6 +1,13 @@
1
+ {% set className %}{{
2
+ "c-signpost--vertical " if params.direction == "vertical" }}{{
3
+ "c-signpost--l " if params.size == "l" }}{{
4
+ "c-signpost--bordered " if params.name == "bordered" }}{{
5
+ "u-white u-bg-" if params.color }}{{params.color}}
6
+ {% endset %}
7
+
1
8
  <article
2
- class="mp c-signpost {{ "c-signpost--vertical" if params.direction == "vertical" }} {{ "c-signpost--l" if params.size == "l" }} {{ params.classes }}">
3
- <a class="c-signpost__link {{ "u-white u-bg-" if params.color }}{{params.color}}" href="{{ params.link }}">
9
+ class="mp c-signpost {{ className }} {{ params.classes }}">
10
+ <a class="c-signpost__link" href="{{ params.link }}">
4
11
  <figure class="c-signpost__image">
5
12
  <img src="/static/svg/{{ params.icon }}.svg" />
6
13
  </figure>
@@ -1,7 +1,19 @@
1
1
  .c-signpost {
2
+ &--bordered {
3
+ @extend .u-border;
4
+ display: flex;
5
+ }
6
+
2
7
  &__link {
3
8
  display: flex;
4
9
  align-items: center;
10
+
11
+ .c-signpost--bordered & {
12
+ @include padding('xs');
13
+ align-self: stretch;
14
+ flex-grow: 1;
15
+ justify-content: center;
16
+ }
5
17
  }
6
18
 
7
19
  &__image {
@@ -36,15 +48,19 @@
36
48
  }
37
49
 
38
50
  .c-signpost--vertical {
51
+ @include cutoff($size: #{var(--space-m)});
52
+ display: flex;
53
+
39
54
  .c-signpost__link {
40
- @include cutoff($size: #{var(--space-m)});
41
- @include padding('m');
42
55
  flex-direction: column;
56
+ flex-grow: 1;
57
+ @include padding('m');
43
58
  text-align: center;
44
59
  }
45
60
 
46
61
  .c-signpost__image {
47
62
  @include margin-bottom('s-m');
63
+ flex-grow: 0;
48
64
  margin-right: 0;
49
65
  }
50
66
  }
@@ -15,6 +15,7 @@
15
15
  margin-left: $twi-space;
16
16
  font-size: 1.25em;
17
17
  position: static !important;
18
+ flex-shrink: 0;
18
19
  }
19
20
 
20
21
  &--left svg {
@@ -1,5 +1,5 @@
1
1
  function InternalNav() {
2
- const internalNav = document.querySelector('.c-internal-nav.u-sticky');
2
+ const internalNav = document.querySelector('.c-internal-nav--sticky');
3
3
 
4
4
  if (!internalNav) {
5
5
  return;
@@ -18,6 +18,24 @@ function InternalNav() {
18
18
 
19
19
  const observer = new IntersectionObserver(intersectionCallback, observerOptions);
20
20
  observer.observe(internalNav);
21
+
22
+ let internalNavHeight = internalNav.offsetHeight;
23
+
24
+ const updateInternalNavHeight = () => {
25
+ internalNavHeight = internalNav.offsetHeight;
26
+ const anchors = Array.from(internalNav.querySelectorAll('a'));
27
+ anchors.forEach(anchor => {
28
+ const id = anchor.getAttribute('href').replace('#', '');
29
+ const target = document.getElementById(id);
30
+ if (target) {
31
+ target.style.scrollMarginTop = `${internalNavHeight}px`;
32
+ }
33
+ });
34
+ };
35
+
36
+ window.addEventListener('resize', updateInternalNavHeight);
37
+
38
+ updateInternalNavHeight();
21
39
  }
22
40
 
23
- export default InternalNav;
41
+ export default InternalNav;
@@ -1,9 +1,14 @@
1
1
  function ScrollSpy() {
2
+ const internalNav = document.querySelector('.c-internal-nav--sticky');
3
+ const internalNavHeight = internalNav ? internalNav.offsetHeight : 0;
4
+
2
5
  const spies = Array.from(document.querySelectorAll('.c-scroll-spy'));
3
- spies.forEach(setup);
6
+ spies.forEach(spy => {
7
+ setup(spy, internalNavHeight);
8
+ });
4
9
  }
5
10
 
6
- function setup(element) {
11
+ function setup(element, internalNavHeight) {
7
12
  const anchors = Array.from(element.querySelectorAll('a'));
8
13
  const observer = new IntersectionObserver(observation(anchors));
9
14
 
@@ -14,6 +19,9 @@ function setup(element) {
14
19
 
15
20
  observer.observe(target);
16
21
  });
22
+
23
+ const currentTop = parseFloat(window.getComputedStyle(element).top);
24
+ element.style.top = `${currentTop + internalNavHeight}px`;
17
25
  }
18
26
 
19
27
  /**
@@ -28,7 +28,7 @@ $grid-gutter-width: 36;
28
28
  & > * {
29
29
  width: calc(($width - (($columns - 1) * space-unit() / $columns)) - 0.1px);
30
30
  width: calc(($width - (($columns - 1) * var(--gutter) / $columns)) - 0.1px);
31
- @include margin-bottom("gutter");
31
+ // @include margin-bottom(0);
32
32
 
33
33
  & + * {
34
34
  @include margin-left("gutter");
@@ -79,6 +79,7 @@ $grid-gutter-width: 36;
79
79
  }
80
80
 
81
81
  & > * {
82
+ @include margin-bottom("gutter");
82
83
  width: 100%;
83
84
  }
84
85
 
@@ -162,6 +163,16 @@ $grid-gutter-width: 36;
162
163
  }
163
164
  }
164
165
 
166
+ &--of-five {
167
+ @media (min-width: 22.4em) and (max-width: 64.9375em) {
168
+ @include o-grid(3)
169
+ }
170
+
171
+ @media (min-width: 65em) {
172
+ @include o-grid(5)
173
+ }
174
+ }
175
+
165
176
  &--swipeable {
166
177
  @media (max-width: 54.9375em) {
167
178
  @include breakout('gutter');
@@ -9,54 +9,59 @@ tags: brand
9
9
  {% from "components/card/macro.njk" import card %}
10
10
  {% from "components/twi/macro.njk" import twi %}
11
11
 
12
- {% set content %}
13
- ## Figma
14
-
15
- Franklin is available as a UI design kit in Figma. It contains text and color styles, grids and spacing, icons, and a complete library of components.
16
-
17
- Visit our profile at [figma.com/@malpan](https://www.figma.com/@malpan) and duplicate the project to add it to your account. You can then use Franklin in your own designs.
18
-
19
- The Figma project is updated regularly to keep it in line with the CSS/JS/HTML version of Franklin. Also every [component](/components) page on this site has a link to its Figma counterpart.
20
- {% endset %}
21
-
22
12
  <div class="u-flow--l u-margin-top-xl">
23
13
 
14
+ <div class="o-grid o-grid--of-two">
15
+
24
16
  {{ twi({
25
17
  link: "/static/zip/MP_logo.zip",
26
18
  label: "Malvern Panalytical logo",
27
- classes: "u-link",
19
+ classes: "u-link u-border u-pad-s",
28
20
  icon: "file"
29
21
  }) }}
30
22
 
31
- <br>
32
-
33
23
  {{ twi({
34
- link: '/static/pdf/PN12558_Physical_branding_v23.pdf',
35
- label: 'Brand guidelines quick-start guide',
36
- classes: 'u-link',
37
- icon: 'file'
24
+ link: "/static/pdf/PN12558_Physical_branding_v23.pdf",
25
+ label: "Brand guidelines quick-start guide",
26
+ classes: "u-link u-border u-pad-s",
27
+ icon: "file"
38
28
  }) }}
39
29
 
40
- <br>
41
-
42
30
  {{ twi({
43
31
  link: "https://malvern.sharepoint.com/:b:/r/sites/Intranet/Shared%20Documents/FINAL%20Tone%20of%20voice%20guidelines%20April%202021.pdf?csf=1&web=1&e=vW1Qzs",
44
32
  label: "Tone of voice guidelines",
45
- classes: "u-link",
33
+ classes: "u-link u-border u-pad-s",
46
34
  icon: "file"
47
35
  }) }}
48
36
 
49
- <br>
50
-
51
37
  {{ twi({
52
38
  link: "https://malvern.sharepoint.com/:p:/r/sites/SVP/Shared%20Documents/Elevator%20Pitch%20(different%20languages)/Elevator%20pitch%20PPT%20(internal-external).pptx?d=w5ae5e5afa8c042f9968f95878a910471&csf=1&web=1&e=ui0qAk",
53
39
  label: "Elevator pitch - Powerpoint presentation",
54
- classes: "u-link",
40
+ classes: "u-link u-border u-pad-s",
55
41
  icon: "file"
56
42
  }) }}
57
43
 
44
+ {{ twi({
45
+ link: "/static/pdf/Power of one Content guidance.pdf",
46
+ label: "Channel Partner & Field Marketing guide - Product rebranding and naming conventions",
47
+ classes: "u-link u-border u-pad-s",
48
+ icon: "file"
49
+ }) }}
50
+
51
+ </div>
52
+
58
53
  <hr>
59
54
 
55
+ {% set content %}
56
+ ## Figma
57
+
58
+ Franklin is available as a UI design kit in Figma. It contains a detailed component library, as well as text and color styles, grids, spacing, and icons.
59
+
60
+ Visit our profile at [figma.com/@malpan](https://www.figma.com/@malpan) and duplicate the project to add it to your account. You can then use Franklin in your own designs.
61
+
62
+ The Figma project is updated regularly to keep it in line with the CSS/JS/HTML version of Franklin. Also most [component](/components) pages on this site have a link to their Figma counterpart.
63
+ {% endset %}
64
+
60
65
  {{ markdown({ content: content }) }}
61
66
 
62
67
  </div>
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: Events hub
3
3
  tags: prototype
4
- tagTitle: Webinars
4
+ tagTitle: Events hub
5
5
  ---
6
6
 
7
7
  {% from "components/button/macro.njk" import button %}
@@ -19,13 +19,19 @@ tagTitle: Webinars
19
19
 
20
20
  {{ hero({
21
21
  cover: true,
22
- title: 'Webinars and events'
22
+ title: 'Webinars and events',
23
+ subtitle: 'Science moves faster when we share what we know',
24
+ strapline: 'Science moves faster when we share what we know',
25
+ search: {
26
+ placeholder: 'Search by product type, industry, or measurement type'
27
+ },
28
+ classes: 'c-hero--padded c-hero--with-search c-hero--extend u-pad-bottom-3xl',
29
+ wrapper: false
23
30
  }) }}
24
31
 
25
- <div class="u-flow--3xl u-pad-bottom-xl">
26
-
27
32
  {# Big nav cards #}
28
- <div class="u-wrap u-margin-top-negative-2xl">
33
+ {#
34
+ <div class="u-wrap">
29
35
  <div class="o-grid o-grid--of-four o-grid--of-four-early">
30
36
  {{ signpost({
31
37
  direction: 'vertical',
@@ -65,12 +71,46 @@ tagTitle: Webinars
65
71
  }) }}
66
72
  </div>
67
73
  </div>
74
+ #}
75
+
76
+ <div class="u-wrap">
77
+ <div class="o-grid o-grid--of-four o-grid--of-four-early">
78
+ {{ signpost ({
79
+ link: '/prototype',
80
+ icon: 'icon-live-webinars',
81
+ title: 'Live webinars',
82
+ name: 'bordered'
83
+ }) }}
84
+ {{ signpost ({
85
+ link: '/prototype',
86
+ icon: 'icon-recorded-webinars',
87
+ title: 'Recorded webinars',
88
+ name: 'bordered'
89
+ }) }}
90
+ {{ signpost ({
91
+ link: '/prototype',
92
+ icon: 'icon-user-training',
93
+ title: 'User training',
94
+ name: 'bordered'
95
+ }) }}
96
+ {{ signpost ({
97
+ link: '/prototype',
98
+ icon: 'icon-globe-alt',
99
+ title: 'In-person events',
100
+ name: 'bordered'
101
+ }) }}
102
+ </div>
103
+ </div>
104
+
105
+ <div class="u-flow--3xl u-pad-bottom-xl u-margin-top-xl ">
68
106
 
69
107
  {# This week #}
70
108
  <div class="c-slat--white">
71
- <div id="this-week" class="u-wrap u-flow">
72
- <p class="c-h c-h--upper">Featured</p>
73
- <h2 class="c-h c-h--step-5">This week</h2>
109
+ <section id="this-week" class="u-wrap u-flow">
110
+ <header>
111
+ <p class="c-h c-h--upper">Featured</p>
112
+ <h2 class="c-h c-h--step-5">This week</h2>
113
+ </header>
74
114
 
75
115
  {{ card({
76
116
  theme: {
@@ -115,12 +155,12 @@ tagTitle: Webinars
115
155
  tag: 'Live webinar'
116
156
  }) }}
117
157
 
118
- </div>
158
+ </section>
119
159
  </div>
120
160
 
121
161
  {# Upcoming #}
122
162
  <div class="c-slat--white">
123
- <div id="upcoming" class="u-wrap u-flow">
163
+ <section id="upcoming" class="u-wrap u-flow">
124
164
  <div class="u-split">
125
165
  <h2 class="c-h c-h--step-5">Coming soon</h2>
126
166
  {{ twi({ classes: 'u-link', label: "See all upcoming webinars", icon: 'arrow-right', align: 'left', link: "#" }) }}
@@ -207,17 +247,17 @@ tagTitle: Webinars
207
247
  tag: 'Live webinar'
208
248
  }) }}
209
249
  </div>
210
- </div>
250
+ </section>
211
251
  </div>
212
252
 
213
253
  {# Recorded #}
214
254
  <div class="c-slat--white">
215
- <div id="recorded" class="u-wrap u-flow">
255
+ <section id="recorded" class="u-wrap u-flow">
216
256
  <div class="u-split">
217
257
  <h2 class="c-h c-h--step-5">Recorded webinars</h2>
218
258
  {{ twi({ classes: 'u-link', label: "See all recorded webinars", icon: 'arrow-right', align: 'left', link: "#" }) }}
219
259
  </div>
220
- <div class="o-grid o-grid--of-four o-grid--of-four-early o-grid--swipeable">
260
+ <div class="o-grid o-grid--of-five o-grid--swipeable">
221
261
  {{ card({
222
262
  theme: {
223
263
  layout: 'single',
@@ -298,13 +338,34 @@ tagTitle: Webinars
298
338
  link: '#',
299
339
  tag: 'Recorded webinar'
300
340
  }) }}
341
+ {{ card({
342
+ theme: {
343
+ layout: 'single',
344
+ size: 'small',
345
+ name: 'alt'
346
+ },
347
+ image: {
348
+ src: 'https://p3.aprimocdn.net/malvernpanalytical/2af3b8d9-48a0-48ce-a98b-aff800ba4096/placeholder-concentric-rings_Original%20file.svg?quality=60&width=430&crop=2:1',
349
+ alt: 'Alt',
350
+ classes: 'u-2/1'
351
+ },
352
+ header: {
353
+ title: 'Malvern Panalytical VIS-NIR Seminar ASD/Malvern Panalytical VIS-NIR Seminarium: Teoria i zastosowania spektrometrów ASD',
354
+ date: {
355
+ date: '8th Sep',
356
+ formatted: true
357
+ }
358
+ },
359
+ link: '#',
360
+ tag: 'Recorded webinar'
361
+ }) }}
301
362
  </div>
302
- </div>
363
+ </section>
303
364
  </div>
304
365
 
305
366
  {# Explore #}
306
367
  <div class="c-slat--white">
307
- <div id="explore" class="u-wrap u-flow">
368
+ <section id="explore" class="u-wrap u-flow">
308
369
  <h2 class="c-h c-h--step-3">Explore topics from over 1,000 expert sessions</h2>
309
370
  <div class="o-grid o-grid--of-four">
310
371
  {{ productSignpost ({
@@ -356,12 +417,12 @@ tagTitle: Webinars
356
417
  classes: 'c-product-signpost--bordered u-pad-m'
357
418
  }) }}
358
419
  </div>
359
- </div>
420
+ </section>
360
421
  </div>
361
422
 
362
423
  {# Series #}
363
424
  <div class="c-slat u-bg-blue-step-3 c-slat--padded c-slat--concentric">
364
- <div id="featured" class="u-wrap u-flow">
425
+ <section id="featured" class="u-wrap u-flow">
365
426
  <div class="o-grid o-grid--layout o-grid--8/4-switch">
366
427
  <div class="u-flow">
367
428
  <p class="c-h c-h--upper">Featured</p>
@@ -369,7 +430,7 @@ tagTitle: Webinars
369
430
  <p>Learn everything there is to know about elemental analysis using X-ray fluorescence (XRF) in this series of webinars.</p>
370
431
  {{ twi({ classes: 'u-link', label: "View the complete series", icon: 'arrow-right', align: 'left', link: "#" }) }}
371
432
  </div>
372
- <div class="o-grid o-grid--of-three">
433
+ <div class="o-grid o-grid--of-three o-grid--of-three-early">
373
434
  {{ card({
374
435
  theme: {
375
436
  border: false,
@@ -456,7 +517,7 @@ tagTitle: Webinars
456
517
  }) }}
457
518
  </div>
458
519
  </div>
459
- </div>
520
+ </section>
460
521
  </div>
461
522
 
462
523
  </div>