@financial-times/o-private-foundation 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +108 -0
  2. package/demos/src/demo.mustache +0 -0
  3. package/demos/src/demo.scss +1 -0
  4. package/main.js +60 -0
  5. package/main.scss +32 -0
  6. package/origami.json +26 -0
  7. package/package.json +33 -0
  8. package/src/scss/_brand.scss +68 -0
  9. package/src/scss/_tokens.scss +15 -0
  10. package/src/scss/_variables.scss +1 -0
  11. package/src/scss/o-buttons/custom-themes.scss +631 -0
  12. package/src/scss/o-buttons/main.scss +255 -0
  13. package/src/scss/o-colors/_functions.scss +354 -0
  14. package/src/scss/o-colors/_palette.scss +2 -0
  15. package/src/scss/o-colors/_variables.scss +50 -0
  16. package/src/scss/o-colors/main.scss +6 -0
  17. package/src/scss/o-grid/_functions.scss +90 -0
  18. package/src/scss/o-grid/_mixins.scss +384 -0
  19. package/src/scss/o-grid/_variables.scss +105 -0
  20. package/src/scss/o-grid/main.scss +5 -0
  21. package/src/scss/o-icons/_mixins.scss +71 -0
  22. package/src/scss/o-icons/main.scss +1 -0
  23. package/src/scss/o-normalise/_mixins.scss +126 -0
  24. package/src/scss/o-normalise/_variables.scss +10 -0
  25. package/src/scss/o-normalise/main.scss +4 -0
  26. package/src/scss/o-spacing/_variables.scss +29 -0
  27. package/src/scss/o-spacing/main.scss +28 -0
  28. package/src/scss/o-typography/main.scss +428 -0
  29. package/src/scss/o-visual-effects/main.scss +4 -0
  30. package/src/scss/o-visual-effects/scss/_shadows.scss +31 -0
  31. package/src/scss/o-visual-effects/scss/_variables.scss +13 -0
  32. package/src/scss/tokens/core.scss +563 -0
  33. package/src/scss/tokens/internal.scss +456 -0
  34. package/src/scss/tokens/professional.scss +537 -0
  35. package/src/scss/tokens/sustainable-views.scss +493 -0
  36. package/src/scss/tokens/whitelabel.scss +465 -0
@@ -0,0 +1,90 @@
1
+ /// Get the grid gutter at a given layout (breakpoint).
2
+ ///
3
+ /// @param {String|null|Boolean} $layout-name [default] - One of $o-pf-grid-layouts breakpoints e.g. S, M, L...
4
+ @function oPrivateGridGutter($layout-name: default) {
5
+ // This layout was assigned a gutter directly
6
+ @if map-get($o-pf-grid-gutters, $layout-name) {
7
+ @return map-get($o-pf-grid-gutters, $layout-name);
8
+ }
9
+
10
+ // Checking the position of the layout in the list of layouts
11
+ $layout-index: index($_o-pf-grid-layout-names, $layout-name);
12
+
13
+ // The first layout (S) should get the default gutter
14
+ @if $layout-index == 1 {
15
+ @return oPrivateGridGutter();
16
+ }
17
+
18
+ // No gutter found for this layout, let's try again with a smaller one
19
+ $layout: nth($_o-pf-grid-layout-names, $layout-index - 1);
20
+ @return oPrivateGridGutter($layout);
21
+ }
22
+
23
+ /// Get the max width of a layout (breakpoint).
24
+ ///
25
+ /// @example
26
+ /// .my-large-container { width: oPrivateGridGetMaxWidthForLayout(L); }
27
+ ///
28
+ /// @param {String} $layout-name - one of $o-pf-grid-layouts
29
+ /// @param {String} $grid-mode [$o-pf-grid-mode]
30
+ @function oPrivateGridGetMaxWidthForLayout($layout-name, $grid-mode: $o-pf-grid-mode) {
31
+ $grid-is-responsive: $grid-mode != 'fixed';
32
+
33
+ $index: index($_o-pf-grid-layout-names, $layout-name);
34
+
35
+ // Largest layout: return its width directly
36
+ @if $index == length($_o-pf-grid-layout-names) {
37
+ @return $_o-pf-grid-max-width;
38
+ }
39
+
40
+ // Smaller layouts:
41
+ @if $grid-is-responsive {
42
+ // - The grid is responsive (fluid or snappy):
43
+ // return the next larger layout width
44
+ $next-layout: nth($_o-pf-grid-layout-names, $index + 1);
45
+ @return map-get($o-pf-grid-layouts, $next-layout);
46
+ } @else {
47
+ // - The grid is fixed, return the current layout width
48
+ @return map-get($o-pf-grid-layouts, $layout-name);
49
+ }
50
+ }
51
+
52
+ /// % width of an element in the grid
53
+ ///
54
+ /// @example
55
+ /// .one-half { width: oPrivateGridColspan(1/2); } // 50%
56
+ /// .other-half { width: oPrivateGridColspan(one-half); } // 50%
57
+ /// .sidebar { width: oPrivateGridColspan(5); } // 41.66667%
58
+ /// .two-thirds { width: oPrivateGridColspan(2/3); } // 66.66667%
59
+ /// .4-out-of-6 { width: oPrivateGridColspan(4, 6); } // 66.66667%
60
+ ///
61
+ /// @param {Number | String} $span - Number of columns the element spans over
62
+ /// @param {Number} $total-cols [$_o-pf-grid-columns] - Number of columns in the grid
63
+ ///
64
+ /// @returns {Number} width of the element in the grid, in percents
65
+ @function oPrivateGridColspan($span, $total-cols: $_o-pf-grid-columns) {
66
+ // Match the HTML helper API with human-friendly numbers
67
+ @if $span == 'one-half' { $span: div(1, 2); }
68
+ @if $span == 'one-quarter' { $span: div(1, 4); }
69
+ @if $span == 'one-third' { $span: div(1, 3); }
70
+ @if $span == 'two-thirds' { $span: div(2, 3); }
71
+ @if $span == 'three-quarters' { $span: div(3, 4); }
72
+
73
+ @if $span == 'full-width' {
74
+ @return 100%;
75
+ } @else {
76
+ @if $span >= 1 {
77
+ // A number of columns is supplied: converting it into a fraction
78
+ // of the total number of columns
79
+ @return percentage(div($span, $total-cols));
80
+ } @else {
81
+ // A fraction (1/2) or a number (0.5) is supplied:
82
+ // converting it into a percentage
83
+ @return percentage($span);
84
+ }
85
+ }
86
+ }
87
+
88
+ @function _oPrivateGridQuoteString($value) {
89
+ @return '"#{$value}"';
90
+ }
@@ -0,0 +1,384 @@
1
+ /// Apply styles at a given layout size (breakpoint) as the grid. It should be
2
+ // passed one of $o-pf-grid-layouts e.g. `S`, `M`, etc... depending on which layout
3
+ // size the style should apply at.
4
+ ///
5
+ /// @example
6
+ /// // Turn the color of an element red at medium layout size and up
7
+ /// @include oPrivateGridRespondTo(M) {
8
+ /// element {
9
+ /// color: red;
10
+ /// }
11
+ /// }
12
+ /// // Turn the color of an element blue until medium layout
13
+ /// element {
14
+ /// @include oPrivateGridRespondTo($until: M) {
15
+ /// color: blue;
16
+ /// }
17
+ /// }
18
+ /// // Turn the color of an element green from small layout until medium layout
19
+ /// element {
20
+ /// @include oPrivateGridRespondTo($from: S, $until: M) {
21
+ /// color: green;
22
+ /// }
23
+ /// }
24
+ ///
25
+ /// @param {String} from - one of $o-pf-grid-layouts
26
+ /// @param {String} until - one of $o-pf-grid-layouts
27
+ @mixin oPrivateGridRespondTo($from: false, $until: false) {
28
+ $grid-is-responsive: $o-pf-grid-mode != 'fixed';
29
+ @include mq(
30
+ $from: $from,
31
+ $until: $until,
32
+ $responsive: $grid-is-responsive,
33
+ $breakpoints: $o-pf-grid-layouts,
34
+ $static-breakpoint: $o-pf-grid-fixed-layout
35
+ ) {
36
+ @content;
37
+ }
38
+ }
39
+
40
+ /// Base column styles and responsive layout width
41
+ ///
42
+ /// @example scss Block has column styles
43
+ /// el { @include oPrivateGridColspan(); }
44
+ ///
45
+ /// @example scss 4-column wide block
46
+ /// el { @include oPrivateGridColspan(4); }
47
+ ///
48
+ /// @example scss Half-width block
49
+ /// el { @include oPrivateGridColspan(1/2); }
50
+ ///
51
+ /// @example scss Block is full-width by default, 8-column wide on Medium layouts and hidden on Large layouts
52
+ /// el { @include oPrivateGridColspan((default: 12, M: 8, L: hide)); }
53
+ ///
54
+ /// @param {Number | Map} $span [null]
55
+ @mixin oPrivateGridColspan($span: null, $width-only: false) {
56
+ @if not $width-only {
57
+ box-sizing: border-box;
58
+ float: left;
59
+ flex: 1 1 0%;
60
+ position: relative; // Required for push and pull
61
+
62
+ @if $o-pf-grid-mode == 'fixed' {
63
+ padding-left: oPrivateGridGutter($o-pf-grid-fixed-layout);
64
+ } @else {
65
+ @each $layout-name in map-keys($o-pf-grid-gutters) {
66
+ @if $layout-name == 'default' {
67
+ padding-left: oPrivateGridGutter();
68
+ } @else {
69
+ @include oPrivateGridRespondTo($layout-name) {
70
+ padding-left: oPrivateGridGutter($layout-name);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ @if $span {
77
+ @include _oPrivateGridColumnWidth($span);
78
+ }
79
+ }
80
+
81
+ /// Grid container
82
+ ///
83
+ /// @param {String} $grid-mode [$o-pf-grid-mode]
84
+ /// @param {Boolean} $bleed [false]
85
+ @mixin oPrivateGridContainer($grid-mode: $o-pf-grid-mode, $bleed: false) {
86
+ box-sizing: border-box;
87
+ margin-left: auto;
88
+ margin-right: auto;
89
+ min-width: $_o-pf-grid-min-width;
90
+ // Older browsers get a fixed-width layout
91
+ max-width: oPrivateGridGetMaxWidthForLayout($o-pf-grid-fixed-layout);
92
+ position: relative;
93
+
94
+ @if $bleed {
95
+ padding-left: 0;
96
+ padding-right: 0;
97
+ }
98
+
99
+ @if $grid-mode == 'fixed' {
100
+ // If the grid isn't fluid, we set it to a certain width
101
+ width: oPrivateGridGetMaxWidthForLayout(
102
+ $o-pf-grid-fixed-layout,
103
+ $grid-mode: 'fixed'
104
+ );
105
+ @if not $bleed {
106
+ padding-left: oPrivateGridGutter($o-pf-grid-fixed-layout);
107
+ padding-right: oPrivateGridGutter($o-pf-grid-fixed-layout);
108
+ }
109
+ } @else {
110
+ max-width: $_o-pf-grid-max-width;
111
+
112
+ @each $layout-name in map-keys($o-pf-grid-gutters) {
113
+ @if $layout-name == 'default' {
114
+ @if not $bleed {
115
+ padding-left: oPrivateGridGutter();
116
+ padding-right: oPrivateGridGutter();
117
+ }
118
+ } @else {
119
+ @include oPrivateGridRespondTo($layout-name) {
120
+ @if not $bleed {
121
+ padding-left: oPrivateGridGutter($layout-name);
122
+ padding-right: oPrivateGridGutter($layout-name);
123
+ }
124
+ }
125
+ }
126
+ }
127
+
128
+ @each $layout-name in $_o-pf-grid-layout-names {
129
+ @if index($_o-pf-grid-layout-names, $layout-name) >=
130
+ index($_o-pf-grid-layout-names, $_o-pf-grid-start-snappy-mode-at)
131
+ {
132
+ @include oPrivateGridRespondTo($layout-name) {
133
+ @if $grid-mode == 'snappy' {
134
+ max-width: map-get($o-pf-grid-layouts, $layout-name);
135
+ }
136
+ @if $grid-mode == 'fluid' {
137
+ // If the grid mode is fluid, then use a class to make a row or a set of rows snappy
138
+ .o-grid-snappy &,
139
+ &--snappy {
140
+ max-width: map-get($o-pf-grid-layouts, $layout-name);
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
146
+ }
147
+ }
148
+
149
+ /// Base row styles
150
+ @mixin oPrivateGridRow {
151
+ clear: both;
152
+ flex-wrap: wrap; // Note that this breaks in old Firefox
153
+ display: flex;
154
+
155
+ @media print {
156
+ display: inherit;
157
+ }
158
+
159
+ @if $o-pf-grid-mode == 'fixed' {
160
+ margin-left: -1 * oPrivateGridGutter($o-pf-grid-fixed-layout);
161
+ } @else {
162
+ @each $layout-name in map-keys($o-pf-grid-gutters) {
163
+ @if $layout-name == 'default' {
164
+ margin-left: -1 * oPrivateGridGutter();
165
+ } @else {
166
+ @include oPrivateGridRespondTo($layout-name) {
167
+ margin-left: -1 * oPrivateGridGutter($layout-name);
168
+ }
169
+ }
170
+ }
171
+ }
172
+
173
+ // Clearfix for IE9 and below
174
+ zoom: 1;
175
+
176
+ &:before,
177
+ &:after {
178
+ content: '';
179
+ display: table;
180
+ display: flex; // stylelint-disable-line declaration-block-no-duplicate-properties
181
+ }
182
+ &:after {
183
+ clear: both;
184
+ }
185
+ }
186
+
187
+ /// Surface the layout currently displayed to make it readable in JS.
188
+ ///
189
+ /// @example js
190
+ /// // your-app/main.js
191
+ /// // Return the current layout (e.g. default, S, M, L, XL)
192
+ /// import oPrivateGrid from 'o-private-foundation/o-grid';
193
+ /// let currentLayout = oPrivateGrid.getCurrentLayout();
194
+ /// console.log(currentLayout);
195
+ ///
196
+ /// // Return the current gutter (e.g. 10px, 20px)
197
+ /// import oPrivateGrid from 'o-private-foundation/o-grid';
198
+ /// let currentGutter = oPrivateGrid.getCurrentGutter();
199
+ /// console.log(currentGutter);
200
+ @mixin oPrivateGridSurfaceCurrentLayout {
201
+ html:after {
202
+ content: '{ "layout": "default", "gutter": "' + oPrivateGridGutter() + '" }';
203
+ display: none;
204
+
205
+ @each $breakpoint in $_o-pf-grid-layout-names {
206
+ @include oPrivateGridRespondTo($breakpoint) {
207
+ content: '{ "layout": "' + $breakpoint + '", "gutter": "' +
208
+ oPrivateGridGutter($breakpoint) + '" }';
209
+ }
210
+ }
211
+ }
212
+ }
213
+
214
+ /// Fix a bug in Safari where items wouldn't wrap properly
215
+ /// Remove when Safari 10 support is no longer required.
216
+ /// @link https://github.com/philipwalton/flexbugs#11-min-and-max-size-declarations-are-ignored-when-wrapping-flex-items
217
+ /// @access private
218
+ @mixin _oPrivateGridFixSafariWrap($args...) {
219
+ flex-basis: oPrivateGridColspan($args...);
220
+ }
221
+
222
+ /// Cross browser column widths across layouts
223
+ ///
224
+ /// @access private
225
+ ///
226
+ /// @example scss
227
+ /// el { @include _oPrivateGridColumnWidth(4); }
228
+ /// el { @include _oPrivateGridColumnWidth(1/2); }
229
+ /// el { @include _oPrivateGridColumnWidth(hide); }
230
+ /// el { @include _oPrivateGridColumnWidth((default: 12, M: 8, L: hide)); }
231
+ ///
232
+ /// @param {Number | Map} $span
233
+ @mixin _oPrivateGridColumnWidth($span) {
234
+ // Special case: the column is hidden by default
235
+ @if $span == 'hide' {
236
+ display: none;
237
+ } @else {
238
+ // $span is a number or a keyword, so we're outputting the default width for that column
239
+ @if type-of($span) == number or type-of($span) == string {
240
+ // Restore visibility from `display: none`
241
+ // if `data-o-grid-colspan` was set to `0` or `hide`
242
+ display: block;
243
+
244
+ // Define width in %
245
+ @include _oPrivateGridFixSafariWrap(
246
+ $span
247
+ ); //stylelint-disable-line order/order
248
+ min-width: oPrivateGridColspan($span);
249
+ max-width: oPrivateGridColspan($span);
250
+ }
251
+ }
252
+
253
+ // $span is a map, we're looping through all of the layouts
254
+ @if type-of($span) == map {
255
+ @each $layout-name, $layout-span in $span {
256
+ @if $layout-name == 'default' {
257
+ @include _oPrivateGridColumnWidth($layout-span);
258
+ } @else {
259
+ @if $layout-span == 'hide' {
260
+ @include oPrivateGridRespondTo($layout-name) {
261
+ display: none;
262
+ }
263
+ } @else {
264
+ @include oPrivateGridRespondTo($layout-name) {
265
+ // Restore visibility from `display: none`
266
+ // if `data-o-grid-colspan` was set to `0` or `hide`
267
+ display: block;
268
+ // Define width in %
269
+ @include _oPrivateGridFixSafariWrap(
270
+ $layout-span
271
+ ); // stylelint-disable-line order/order
272
+ min-width: oPrivateGridColspan($layout-span);
273
+ max-width: oPrivateGridColspan($layout-span);
274
+ }
275
+ }
276
+ }
277
+ }
278
+ }
279
+ }
280
+
281
+ /// Remove gutters from columns in a row
282
+ ///
283
+ /// @param {string} $column-selector ["[o-grid-colspan]"] - CSS selector for row element
284
+ @mixin oPrivateGridRowCompact($column-selector: '[o-grid-colspan]') {
285
+ margin-left: 0;
286
+
287
+ > #{unquote($column-selector)} {
288
+ padding-left: 0;
289
+ }
290
+ }
291
+
292
+ /// Add a layout (breakpoint). This can be used to add a new breakpoint to a
293
+ /// project, in addition to the default layouts (S, M, L, XL).
294
+ ///
295
+ /// @example scss
296
+ /// @include oGridAddLayout($layout-name: P, $layout-width: 600px);
297
+ /// @include oGridAddLayout($layout-name: XXL, $layout-width: 1600px, $gutter-width: 30px);
298
+ ///
299
+ /// @param {String} $layout-name - Name of the layout (e.g. S)
300
+ /// @param {Number} $layout-width - Layout width in px
301
+ /// @param {Number} $gutter-width [null] - Gutter width in px
302
+ @mixin oPrivateGridAddLayout($layout-name, $layout-width, $gutter-width: null) {
303
+ $temp-layouts: ();
304
+ $temp-gutters: (
305
+ default: oGridGutter(),
306
+ );
307
+ $current-max-width: map-get(
308
+ $o-pf-grid-layouts,
309
+ nth($_o-pf-grid-layout-names, -1)
310
+ );
311
+
312
+ // Add the new layout in the correct position:
313
+ // (we want $o-grid-layouts and $o-grid-gutters to be ordered from the smallest to the largest layout)
314
+ @if ($layout-width >= $current-max-width) {
315
+ $temp-layouts: map-merge(
316
+ $o-pf-grid-layouts,
317
+ (
318
+ $layout-name: $layout-width,
319
+ )
320
+ );
321
+ $temp-gutters: map-merge(
322
+ $o-pf-grid-gutters,
323
+ (
324
+ $layout-name: $gutter-width,
325
+ )
326
+ );
327
+ } @else {
328
+ @for $index from 1 through length($o-pf-grid-layouts) {
329
+ $previous-layout-width: if(
330
+ $index == 1,
331
+ 0,
332
+ map-get($o-pf-grid-layouts, nth($_o-pf-grid-layout-names, $index - 1))
333
+ );
334
+ $current-layout-name: nth($_o-pf-grid-layout-names, $index);
335
+ $current-layout-width: map-get($o-pf-grid-layouts, $current-layout-name);
336
+
337
+ $current-gutter-width: map-get($o-pf-grid-gutters, $current-layout-name);
338
+
339
+ // Assumes all layouts use the same unit e.g. px or rem (as does the JavaScript)
340
+ @if not(
341
+ $previous-layout-width >
342
+ $layout-width or
343
+ $current-layout-width <
344
+ $layout-width
345
+ )
346
+ {
347
+ $temp-layouts: map-merge(
348
+ $temp-layouts,
349
+ (
350
+ $layout-name: $layout-width,
351
+ )
352
+ );
353
+ $temp-gutters: map-merge(
354
+ $temp-gutters,
355
+ (
356
+ $layout-name: $gutter-width,
357
+ )
358
+ );
359
+ }
360
+
361
+ $temp-layouts: map-merge(
362
+ $temp-layouts,
363
+ (
364
+ $current-layout-name: $current-layout-width,
365
+ )
366
+ );
367
+
368
+ @if $current-gutter-width {
369
+ $temp-gutters: map-merge(
370
+ $temp-gutters,
371
+ (
372
+ $current-layout-name: $current-gutter-width,
373
+ )
374
+ );
375
+ }
376
+ }
377
+ }
378
+ $o-pf-grid-layouts: $temp-layouts !global;
379
+ $_o-pf-grid-layout-names: map-keys($o-pf-grid-layouts) !global;
380
+
381
+ @if $gutter-width {
382
+ $o-pf-grid-gutters: $temp-gutters !global;
383
+ }
384
+ }
@@ -0,0 +1,105 @@
1
+ // ----------------------------------------------------------------------------
2
+ // Responsive behaviour configuration
3
+ // ----------------------------------------------------------------------------
4
+
5
+ /// Grid mode
6
+ /// - fluid: full width up to the largest layout's width
7
+ /// - snappy: fluid width until the layout defined in $_o-pf-grid-start-snappy-mode-at (default: M),
8
+ /// and then snaps into a larger fixed layout at each breakpoint
9
+ /// - fixed: always fixed-width with the layout defined by $o-pf-grid-fixed-layout (default: L)
10
+ ///
11
+ /// @type String - one of fluid (default), snappy, fixed
12
+ $o-pf-grid-mode: if(
13
+ global-variable-exists(o-grid-mode),
14
+ $o-grid-mode,
15
+ 'fluid'
16
+ ) !default;
17
+
18
+ /// Layout to default to when the grid has a fixed width (not fluid)
19
+ ///
20
+ /// @type String - One of $o-pf-grid-layouts
21
+ $o-pf-grid-fixed-layout: if(
22
+ global-variable-exists(o-grid-fixed-layout),
23
+ $o-grid-fixed-layout,
24
+ 'L'
25
+ ) !default;
26
+
27
+ /// When the grid start snapping between fixed-width layouts
28
+ /// in the case where a row has the `o-grid-row--snappy` class
29
+ ///
30
+ /// @type String
31
+ $_o-pf-grid-start-snappy-mode-at: 'M' !default;
32
+
33
+ // ----------------------------------------------------------------------------
34
+ // Grid settings and dimensions
35
+ // ----------------------------------------------------------------------------
36
+
37
+ /// Number of columns
38
+ ///
39
+ /// @type Number (unitless)
40
+ $_o-pf-grid-columns: 12 !default;
41
+
42
+ /// Minimum width, in pixels
43
+ ///
44
+ /// @type Number
45
+ $_o-pf-grid-min-width: 240px !default;
46
+
47
+ /// Layouts
48
+ ///
49
+ /// Each layout is calculated following a specific column width,
50
+ /// in order to base breakpoints on the structure of the grid itself
51
+ ///
52
+ /// @type Map
53
+ $o-pf-grid-layouts: if(
54
+ global-variable-exists(o-grid-layouts),
55
+ $o-grid-layouts,
56
+ (
57
+ S: 490px,
58
+ // column-width: 30px, inner width: 470px
59
+ M: 740px,
60
+ // column-width: 40px, inner width: 700px
61
+ L: 980px,
62
+ // column-width: 60px, inner width: 940px
63
+ XL: 1220px,
64
+ // column-width: 80px, inner width: 1180px
65
+ )
66
+ ) !default;
67
+
68
+ /// Layout names
69
+ ///
70
+ /// @access private
71
+ /// @type List
72
+ $_o-pf-grid-layout-names: map-keys($o-pf-grid-layouts);
73
+
74
+ /// Gutter sizes
75
+ ///
76
+ /// @type Map
77
+
78
+ $o-pf-grid-gutters: if(
79
+ global-variable-exists(o-grid-gutters),
80
+ $o-grid-gutters,
81
+ (
82
+ default: 10px,
83
+ M: 20px,
84
+ )
85
+ ) !default;
86
+
87
+ // If layouts have changed but gutters haven't,
88
+ // prune non-existant layouts.
89
+ @each $layout-name, $gutter-size in $o-pf-grid-gutters {
90
+ @if ($layout-name != 'default') and
91
+ (not map-has-key($o-pf-grid-layouts, $layout-name))
92
+ {
93
+ $o-pf-grid-gutters: map-remove($o-pf-grid-gutters, $layout-name);
94
+ }
95
+ }
96
+
97
+ /// Maximum grid width
98
+ /// Defaults to the largest layout width
99
+ ///
100
+ /// @access private
101
+ /// @type Number
102
+ $_o-pf-grid-max-width: map-get(
103
+ $o-pf-grid-layouts,
104
+ nth($_o-pf-grid-layout-names, -1)
105
+ );
@@ -0,0 +1,5 @@
1
+ @import '@financial-times/math';
2
+ @import '@financial-times/sass-mq';
3
+ @import 'variables';
4
+ @import 'functions';
5
+ @import 'mixins';
@@ -0,0 +1,71 @@
1
+ /// Output styles for an SVG icon.
2
+ /// Styles the icon as a background image, setting a width and height on the element as requested.
3
+ /// A fallback background for Windows High Contrast mode is also output.
4
+ ///
5
+ /// @access public
6
+ /// @param {String} $icon-name - This should be a reference to an icon included in o-icons eg arrow-down
7
+ /// @param {String} $color - This should be a hex colour value. Used to color the icon. We suggest using an o-colors function.
8
+ /// @param {Number|Null} $size [128] - The width and height of the icon (units optional, defaults to px). Set to `null` to set no width or height.
9
+ /// @param {Bool} $include-base-styles [true] - If true, will output style rules for the container. If false will only output the background-image property
10
+ /// @param {Bool} $high-contrast-fallback [true] - To output Microsoft High Contrast fallback for accessibility reasons or not.
11
+ /// @param {Number} $iconset-version [1] - At present only 1 version of the icon set is available.
12
+ @mixin oPrivateIconsContent($icon-name, $color: null, $size: 128, $include-base-styles: true, $high-contrast-fallback: true, $iconset-version: 1) {
13
+ // Error if the global $system-code variable is not set.
14
+ // This is required for image service requests.
15
+ @if(global-variable-exists('system-code') == false or type-of($system-code) != 'string') {
16
+ @error 'A global "$system-code" Sass variable must be set to a valid [Bizops system code](https://biz-ops.in.ft.com/list/Systems).';
17
+ }
18
+
19
+ // If the size of the icons has been given without a unit, default to px.
20
+ @if (type-of($size) == 'number' and unitless($size)) {
21
+ $size: $size + 0px;
22
+ }
23
+
24
+ // Define base image service path.
25
+ $scheme: "fticon-v#{$iconset-version}";
26
+ $service-url: "https://www.ft.com/__origami/service/image/v2/images/raw/#{$scheme}:#{$icon-name}";
27
+
28
+ // Include base styles shared by all icons.
29
+ @if ($include-base-styles == true) {
30
+ @include oPrivateIconsContentBaseStyles;
31
+ }
32
+
33
+ // Set the icon dimentions.
34
+ width: $size;
35
+ height: $size;
36
+
37
+ // Include the icon via the image service.
38
+ // Build an image service url for the requested icon.
39
+ $query: "?source=#{$system-code}";
40
+ @if $color != null {
41
+ $color: str-slice(ie-hex-str($color), 4);
42
+ $query: $query + "&tint=%23#{$color},%23#{$color}";
43
+ }
44
+ background-image: url($service-url + $query + "&format=svg");
45
+
46
+ // Include a fallback for Window's high contrast mode.
47
+ // This mode removes background images unless specifcally included
48
+ // for high contrast mode.
49
+ // sass-lint:disable no-vendor-prefixes
50
+ @if $high-contrast-fallback {
51
+ @media screen and (-ms-high-contrast: active) {
52
+ background-image: url($service-url + "?source=#{$system-code}&tint=%23ffffff,%23ffffff&format=svg");
53
+ }
54
+
55
+ @media screen and (-ms-high-contrast: black-on-white) {
56
+ background-image: url($service-url + "?source=#{$system-code}&tint=%23000000,%23000000&format=svg");
57
+ }
58
+ }
59
+ // sass-lint:enable no-vendor-prefixes
60
+ }
61
+
62
+ /// Base styles for all icons
63
+ /// @access public
64
+ @mixin oPrivateIconsContentBaseStyles() {
65
+ display: inline-block;
66
+ background-repeat: no-repeat;
67
+ background-size: contain;
68
+ background-position: 50%;
69
+ background-color: transparent;
70
+ vertical-align: baseline;
71
+ }
@@ -0,0 +1 @@
1
+ @import "mixins";