@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,126 @@
1
+ @import 'variables';
2
+ /// Visually hide an element while still
3
+ /// allowing it to be read by a screenreader
4
+ @mixin oPrivateNormaliseVisuallyHidden {
5
+ position: absolute;
6
+ clip: rect(0 0 0 0);
7
+ clip-path: polygon(0 0, 0 0);
8
+ margin: -1px;
9
+ border: 0;
10
+ overflow: hidden;
11
+ padding: 0;
12
+ width: 2px;
13
+ height: 2px;
14
+ white-space: nowrap;
15
+ }
16
+
17
+ /// Clearfix helper styles
18
+ /// Outputs clearfix styles on the current element
19
+ @mixin oPrivateNormaliseClearfix {
20
+ zoom: 1;
21
+
22
+ &:before,
23
+ &:after {
24
+ content: '';
25
+ display: table;
26
+ display: flex; // stylelint-disable-line declaration-block-no-duplicate-properties
27
+ }
28
+ &:after {
29
+ clear: both;
30
+ }
31
+ }
32
+
33
+ /// Adds box sizing to current and all child elements
34
+ @mixin oPrivateNormaliseBoxSizing {
35
+
36
+ /*autoprefixer: off*/
37
+ -webkit-box-sizing: border-box; // stylelint-disable-line property-no-vendor-prefix
38
+ -moz-box-sizing: border-box; // stylelint-disable-line property-no-vendor-prefix
39
+ box-sizing: border-box;
40
+
41
+ & *,
42
+ & *:before,
43
+ & *:after {
44
+ /*autoprefixer: off*/
45
+ -webkit-box-sizing: inherit; // stylelint-disable-line property-no-vendor-prefix
46
+ -moz-box-sizing: inherit; // stylelint-disable-line property-no-vendor-prefix
47
+ box-sizing: inherit;
48
+ }
49
+ }
50
+
51
+ /// Apply a focus style using `:focus-visible` with `:focus` fallback.
52
+ ///
53
+ /// @example scss - Apply a focus style to a button using `:focus-visible` with `:focus` fallback.
54
+ /// button {
55
+ /// @include oNormaliseFocusApply() {
56
+ /// @include oNormaliseFocusContent();
57
+ /// };
58
+ /// }
59
+ @mixin oPrivateNormaliseFocusApply {
60
+ @at-root {
61
+ &:focus {
62
+ @content;
63
+ }
64
+
65
+ // Unset :focus styles where :focus-visible is supported.
66
+ // Ideally we would set `:focus-visible` by default and use
67
+ // `@supports not selector(:focus-visible)` to provide a
68
+ // `:focus` fallback, however some of our supported browsers
69
+ // do not understand `@supports: selector()`.
70
+ @supports selector(:focus-visible) {
71
+ &:focus {
72
+ @include oPrivateNormaliseFocusUnsetContent();
73
+ }
74
+
75
+ &:focus-visible {
76
+ @content;
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ /// Output focus state styles to apply explicitly to a given element.
83
+ ///
84
+ /// @see oNormaliseFocusContentInverse - An alternative focus style, optimised for "inverse" elements (light on dark background).
85
+ /// @see oNormaliseFocusContentForElementColour - Dynamically apply either `oNormaliseFocusContent` or `oNormaliseFocusContentInverse` based on the background colour of the focused element.
86
+ @mixin oPrivateNormaliseFocusContent() {
87
+ box-shadow: $_o-private-normalise-focus-ring;
88
+ }
89
+
90
+ /// Output focus state styles to apply explicitly to a given element with "inverse" theme (light on dark background).
91
+ ///
92
+ /// @see oNormaliseFocusContent - An alternative focus style, the default, optimised for dark elements on a light background.
93
+ /// @see oNormaliseFocusContentForElementColour - Dynamically apply either `oNormaliseFocusContent` or `oNormaliseFocusContentInverse` based on the background colour of the focused element.
94
+ @mixin oPrivateNormaliseFocusContentInverse() {
95
+ box-shadow: $_o-private-normalise-reverse-focus-ring;
96
+ }
97
+
98
+ /// Output focus state styles for a block element of a given colour.
99
+ /// Where the given colour refers to the background colour of the focused element,
100
+ /// not the page background.
101
+ ///
102
+ /// This is useful when dynamically creating new themes, where the colour of the
103
+ /// element is not known in advance. Otherwise set either `oNormaliseFocusContent` or
104
+ /// `oNormaliseFocusContentInverse` explicitly instead.
105
+ ///
106
+ /// @see oNormaliseFocusContent - An alternative focus style, the default, optimised for dark elements on a light background.
107
+ /// @see oNormaliseFocusContentInverse - An alternative focus style, optimised for "inverse" elements (light on dark background).
108
+ ///
109
+ /// @param {String|Color} $color - The background colour of the focused element.
110
+ @mixin oPrivateNormaliseFocusContentForElementColour($color) {
111
+ $black-contrast: oPrivateColorsGetContrastRatio($color, black);
112
+ $white-contrast: oPrivateColorsGetContrastRatio($color, white);
113
+ $shadow: if(
114
+ $black-contrast <= $white-contrast,
115
+ $_o-private-normalise-focus-ring,
116
+ $_o-private-normalise-reverse-focus-ring
117
+ );
118
+
119
+ box-shadow: $shadow;
120
+ }
121
+
122
+ /// Undo a focus style applied by o-normalise.
123
+ @mixin oPrivateNormaliseFocusUnsetContent {
124
+ outline: unset;
125
+ box-shadow: unset;
126
+ }
@@ -0,0 +1,10 @@
1
+ /// @access private
2
+ $_o-private-normalise-focus-ring: oPrivateFoundationGet(
3
+ 'o3-focus-use-case-ring-inner'
4
+ ),
5
+ oPrivateFoundationGet('o3-focus-use-case-ring-outer');
6
+
7
+ $_o-private-normalise-reverse-focus-ring: oPrivateFoundationGet(
8
+ 'o3-focus-use-case-ring-inverse-inner'
9
+ ),
10
+ oPrivateFoundationGet('o3-focus-use-case-ring-inverse-outer');
@@ -0,0 +1,4 @@
1
+ @import '../o-colors/main';
2
+
3
+ @import 'variables';
4
+ @import 'mixins';
@@ -0,0 +1,29 @@
1
+ /// Represents the baseline number (pixels) to base spaces off.
2
+ /// @type Number
3
+ /// @access private
4
+ $o-pf-spacing-baseline: 4;
5
+
6
+ /// The named spaces. Where the key is the name and the number value is the
7
+ /// increment of the baseline value.
8
+ /// @type Map
9
+ /// @access private
10
+ $o-pf-spacing-sizes: (
11
+ 's1': 1,
12
+ 's2': 2,
13
+ 's3': 3,
14
+ 's4': 4,
15
+ 's6': 6,
16
+ 's8': 8,
17
+ 'm12': 12,
18
+ 'm16': 16,
19
+ 'l18': 18,
20
+ 'l24': 24,
21
+ );
22
+
23
+ /// When true output relative `rem` space values, not `px`.
24
+ /// Relative spaces will respect the browser's configured font size.
25
+ ///
26
+ /// For legacy reasons, this defaults to `false` (outputs px units).
27
+ /// Projects may need to be updated to support relative units.
28
+ /// @type Bool
29
+ $o-pf-spacing-relative-units: false !default;
@@ -0,0 +1,28 @@
1
+ @import 'variables';
2
+
3
+ /// @param {String} $size-name - Get a recommended space size by name.
4
+ /// @return {Number} - A px value (or rem value if relative units have been enabled).
5
+ @function oPrivateSpacingByName($size-name) {
6
+ $value: map-get($o-pf-spacing-sizes, $size-name);
7
+ @if(type-of($value) != 'number') {
8
+ @error 'There is no recommended space named "#{$size-name}". Should be one of #{map-keys($o-pf-spacing-sizes)}.';
9
+ }
10
+ @return oPrivateSpacingByIncrement($value);
11
+ }
12
+
13
+ /// @param {Number} $increment - The number to multiply the baseline size by.
14
+ /// @return {Number} - A px value (or rem value if relative units have been enabled).
15
+ @function oPrivateSpacingByIncrement($increment) {
16
+ @if(type-of($increment) != 'number' and floor($increment) != $increment) {
17
+ @error 'Expected a whole number but was given "#{$increment}".';
18
+ }
19
+ @return $increment * oPrivateSpacingGetBaselineValue();
20
+ }
21
+
22
+ /// @return {Number} - A px value representing our spacing baseline (or rem value if relative units have been enabled).
23
+ @function oPrivateSpacingGetBaselineValue() {
24
+ @if($o-pf-spacing-relative-units) {
25
+ @return div($o-pf-spacing-baseline, 16) * 1rem;
26
+ }
27
+ @return $o-pf-spacing-baseline * 1px;
28
+ }
@@ -0,0 +1,428 @@
1
+ /// @see _oPrivateTypographyFor
2
+ @mixin oPrivateTypographySans(
3
+ $scale: null,
4
+ $line-height: null,
5
+ $weight: null,
6
+ $style: null
7
+ ) {
8
+ $font: 'metric';
9
+ @include _oPrivateTypographyFor($font, $scale, $line-height, $weight, $style);
10
+ }
11
+
12
+ /// @see _oPrivateTypographyFor
13
+ @mixin oPrivateTypographySerif(
14
+ $scale: null,
15
+ $line-height: null,
16
+ $weight: null,
17
+ $style: null
18
+ ) {
19
+ $font: 'georgia';
20
+ @include _oPrivateTypographyFor($font, $scale, $line-height, $weight, $style);
21
+ }
22
+
23
+ /// @see _oPrivateTypographyFor
24
+ @mixin oPrivateTypographyDisplay(
25
+ $scale: null,
26
+ $line-height: null,
27
+ $weight: null,
28
+ $style: null
29
+ ) {
30
+ $font: 'financier-display';
31
+ @include _oPrivateTypographyFor($font, $scale, $line-height, $weight, $style);
32
+ }
33
+
34
+ /// @param {Number} $scale [null] - a scale number to output a font-size and line-height property
35
+ /// @param {Number} $line-height [null] - custom line-height value to use instead of the scale's default
36
+ /// @param {Null | String} $weight [null] - output a font-weight property, e.g. 'bold', 'semibold'
37
+ /// @param {Null | String} $style [null] - output a font-style property, e.g. 'italic'
38
+ @mixin _oPrivateTypographyFor(
39
+ $font,
40
+ $scale: null,
41
+ $line-height: null,
42
+ $weight: null,
43
+ $style: null
44
+ ) {
45
+ @if $scale {
46
+ // The font scale to use. o3 includes multiple scales.
47
+ // Adjust scale down, to support migrating from
48
+ // Metric2 to Metric. Metric2 renders larger for the same font-size.
49
+ $scale-key: '-'; // Default scale
50
+ @if ($font == 'metric') {
51
+ $scale-key: '-metric2-'; // Metric2 scale
52
+ $scale: $scale - 1;
53
+ }
54
+
55
+ // The font scale number as a key.
56
+ $scale-item-key: '#{$scale}';
57
+ @if ($scale < 0) {
58
+ $scale-item-key: 'negative#{$scale}';
59
+ }
60
+ font-family: oPrivateFoundationGet('o3-font-family-#{$font}');
61
+ font-size: oPrivateFoundationGet(
62
+ 'o3-font-size#{$scale-key}#{$scale-item-key}'
63
+ );
64
+ line-height: oPrivateFoundationGet(
65
+ 'o3-font-lineheight#{$scale-key}#{$scale-item-key}'
66
+ );
67
+ }
68
+
69
+ font-weight: if(
70
+ $weight,
71
+ oPrivateFoundationGet('o3-font-weight-#{$weight}'),
72
+ null
73
+ );
74
+ }
75
+
76
+ @mixin oPrivateTypographyCaption {
77
+ @include oPrivateTypographySans($scale: -1);
78
+ margin-top: oPrivateFoundationGet('o3-spacing-4xs');
79
+ margin-bottom: 0;
80
+ color: oPrivateFoundationGet('o3-color-use-case-body-text');
81
+ }
82
+
83
+ /// Output link styles.
84
+ ///
85
+ /// @example Output the styles for a standard link.
86
+ /// .my-link {
87
+ /// @include oPrivateTypographyLink();
88
+ /// }
89
+ ///
90
+ /// @example Output a Origami supported theme.
91
+ /// .my-inverse-link {
92
+ /// @include oPrivateTypographyLink($theme: 'inverse');
93
+ /// }
94
+ ///
95
+ /// @param {String|Null} $theme [null] - An Origami theme to change the look of a link.
96
+ @mixin oPrivateTypographyLink($theme: null) {
97
+ $underline-size: 0.25ex; // 2px for 18px MetricWeb
98
+
99
+ &[target='_blank'] {
100
+ // Visually hidden content is positioned absolutely. Position relative on the anchor means the hidden
101
+ // content is positioned relative to the anchor element. This ensures it is clipped by the overflow
102
+ // property of an ancestor; otherwise the pseudo element which contains the hidden content will not
103
+ // be clipped by the overflow of any ancestor between it and its containing block.
104
+ // https://drafts.csswg.org/css2/#visufx
105
+ position: relative;
106
+
107
+ &:after {
108
+ @include oPrivateNormaliseVisuallyHidden();
109
+ content: '(opens a new window)';
110
+ }
111
+ }
112
+
113
+ // Output base styles shared by all links.
114
+ text-decoration: none;
115
+ cursor: pointer;
116
+ border-bottom: $underline-size solid;
117
+
118
+ @supports (text-decoration-thickness: $underline-size) {
119
+ border-bottom: 0;
120
+ text-decoration-thickness: $underline-size; //sass-lint:disable-line no-misspelled-properties
121
+ text-decoration-line: underline;
122
+ }
123
+
124
+ // Colours for theme
125
+ // Professional is a theme in o2 and a brand in o3.
126
+ // Map "professional" themes to a brand to fetch tokens.
127
+ $sub-brand: null;
128
+ @if ($theme == 'professional' or $theme == 'professional-inverse') {
129
+ $sub-brand: 'professional';
130
+ }
131
+
132
+ $token-prefix: 'o3-color-use-case-link-';
133
+ @if ($theme == 'professional-inverse') {
134
+ $token-prefix: 'o3-color-use-case-link-inverse-';
135
+ }
136
+ // Standard link colours.
137
+ $base-color: oPrivateFoundationGet(#{$token-prefix + 'text'}, $sub-brand);
138
+ $hover-color: oPrivateFoundationGet(
139
+ #{$token-prefix + 'text-hover'},
140
+ $sub-brand
141
+ );
142
+ $decoration-color: oPrivateFoundationGet(
143
+ #{$token-prefix + 'underline'},
144
+ $sub-brand
145
+ );
146
+ $hover-decoration-color: oPrivateFoundationGet(
147
+ #{$token-prefix + 'underline-hover'},
148
+ $sub-brand
149
+ );
150
+
151
+ @include _oPrivateTypographyLinkTheme(
152
+ $base-color,
153
+ $decoration-color,
154
+ $hover-color,
155
+ $hover-decoration-color
156
+ );
157
+ }
158
+
159
+ /// Output link styles.
160
+ ///
161
+ /// @example Output a custom, claret coloured link to go on the default background colour (paper for the core brand, white otherwise).
162
+ /// .my-claret-link {
163
+ /// @include oPrivateTypographyLink();
164
+ /// @include oPrivateTypographyLinkThemeOverride($theme: (
165
+ /// 'base': 'claret',
166
+ /// 'hover': 'claret-30',
167
+ /// ));
168
+ /// }
169
+ ///
170
+ /// @example Output a custom, lemon coloured link to go on a slate background.
171
+ /// .my-inverse-link {
172
+ /// @include oPrivateTypographyLink();
173
+ /// @include oPrivateTypographyLinkThemeOverride($theme: (
174
+ /// 'base': 'lemon',
175
+ /// 'hover': 'lemon-30',
176
+ /// 'context': 'slate',
177
+ /// ));
178
+ /// }
179
+ ///
180
+ /// @param {Map} $theme - A custom theme to change the look of a link, with colours for properties `base` (the main link colour), `hover` (the links over colour), and optional `context` key. Context is the colour the link will be placed on, it defaults to the page background (paper for the core brand, white otherwise).
181
+ @mixin oPrivateTypographyLinkThemeOverride($theme) {
182
+ $base-color: map-get($theme, 'base');
183
+ $base-color: _oPrivateTypographyGetColourFrom($base-color);
184
+
185
+ $hover-color: map-get($theme, 'hover');
186
+ $hover-color: _oPrivateTypographyGetColourFrom($hover-color);
187
+
188
+ $context-color: map-get($theme, 'context');
189
+ $context-color: _oPrivateTypographyGetColourFrom($context-color);
190
+ @if (not $context-color) {
191
+ $context-color: oPrivateFoundationGet('o3-color-use-case-page-background');
192
+ }
193
+
194
+ $decoration-color: map-get($theme, 'base-decoration');
195
+ $decoration-color: _oPrivateTypographyGetColourFrom($decoration-color);
196
+
197
+ $hover-decoration-color: map-get($theme, 'hover-decoration');
198
+ $hover-decoration-color: _oPrivateTypographyGetColourFrom(
199
+ $hover-decoration-color
200
+ );
201
+
202
+ // Validate required theme colours.
203
+ @if (type-of($base-color) != 'color') {
204
+ @error 'A custom link theme must have a `base` property with a colour or palette colour name e.g. `claret`. But found #{$base-color}.';
205
+ }
206
+ @if (type-of($hover-color) != 'color') {
207
+ @error 'A custom link theme must have a `hover` property with a color or palette colour name e.g. `claret`. But found #{$hover-color}.';
208
+ }
209
+ @if (type-of($context-color) != 'color') {
210
+ @error 'A custom link theme may optionally have a `context` property with a color or palette colour name, to indicate the colour of the page behind the link, e.g. `null` or `paper`. But found #{$context-color}.';
211
+ }
212
+
213
+ // Generate optional theme colours.
214
+ @if (not $decoration-color) {
215
+ // TODO: replace oColorsMix
216
+ $decoration-color: oColorsMix($base-color, $context-color, $percentage: 20);
217
+ }
218
+
219
+ @if (not $hover-decoration-color) {
220
+ // TODO: replace oColorsMix
221
+ $hover-decoration-color: oColorsMix(
222
+ $base-color,
223
+ $context-color,
224
+ $percentage: 40
225
+ );
226
+ }
227
+
228
+ // Output theme colours.
229
+ @include _oPrivateTypographyLinkTheme(
230
+ $base-color,
231
+ $decoration-color,
232
+ $hover-color,
233
+ $hover-decoration-color
234
+ );
235
+ }
236
+
237
+ /// Apply theme colours to a link.
238
+ /// @param {Color} $base-color - The main link colour.
239
+ /// @param {Color} $decoration-color - The colour of the underline.
240
+ /// @param {Color} $hover-color - The link colour on hover.
241
+ /// @param {Color} $hover-decoration-color - The colour of the underline on hover.
242
+ @mixin _oPrivateTypographyLinkTheme(
243
+ $base-color,
244
+ $decoration-color,
245
+ $hover-color,
246
+ $hover-decoration-color
247
+ ) {
248
+ color: $base-color;
249
+
250
+ border-bottom: 0;
251
+ text-decoration-color: $decoration-color;
252
+
253
+ &:hover {
254
+ color: $hover-color;
255
+ text-decoration-color: $hover-decoration-color;
256
+ }
257
+
258
+ &:focus {
259
+ color: $hover-color;
260
+ text-decoration-color: transparent;
261
+ }
262
+ }
263
+
264
+ /// Output styles for lists.
265
+ /// Styles child `li` elements. Apply to a
266
+ /// containing list element such as `ul` or `ol`.
267
+ /// Does not output font styles, these are
268
+ /// inherited.
269
+ ///
270
+ /// @example Output the styles for an unordered list.
271
+ /// .my-unordered-list {
272
+ /// @include oPrivateTypographyList('unordered');
273
+ /// }
274
+ ///
275
+ /// @param {String|Null} $type [null] - "ordered", "unordered", or null for just the base styles shared by all lists
276
+ @mixin oPrivateTypographyList($type: null) {
277
+ // Undo browser defaults.
278
+ margin: 0 0 oPrivateFoundationGet('o3-spacing-s');
279
+ padding: 0;
280
+ list-style: none;
281
+
282
+ // Reset number counter for new ordered list.
283
+ @if ($type == 'ordered') {
284
+ counter-reset: item;
285
+ }
286
+ > li {
287
+ position: relative;
288
+ // Undo browser default.
289
+ margin: 0;
290
+ // Allow space for 2-3 numbers for both ordered and unordered lists,
291
+ // so content aligns between both list types.
292
+ padding-left: calc(2ch + #{oPrivateFoundationGet('o3-spacing-5xs')});
293
+
294
+ &:before {
295
+ @include oPrivateTypographySans();
296
+ display: inline-block;
297
+ position: absolute;
298
+ left: 0;
299
+ transform-origin: center left;
300
+
301
+ @if ($type == 'unordered') {
302
+ content: '\2022'; // dot character
303
+ color: inherit;
304
+ // 28px marker given a parent font-size of 18px
305
+ transform: scale(#{div(28, 18)});
306
+ // magic number to center marker
307
+ margin-top: #{div(28, 18) * -0.16ch};
308
+ }
309
+
310
+ @if ($type == 'ordered') {
311
+ font-family: oPrivateFoundationGet(
312
+ 'o3-type-body-highlight-font-family'
313
+ );
314
+ font-size: oPrivateFoundationGet('o3-type-body-highlight-font-size');
315
+ font-weight: oPrivateFoundationGet(
316
+ 'o3-type-body-highlight-font-weight'
317
+ );
318
+ line-height: oPrivateFoundationGet(
319
+ 'o3-type-body-highlight-line-height'
320
+ );
321
+ content: counter(item);
322
+ counter-increment: item;
323
+ font-feature-settings: 'tnum';
324
+ // 16px marker given a parent font-size of 18px
325
+ transform: scale(#{div(16, 18)});
326
+ // magic number to make marker flush to the left
327
+ margin-left: #{div(16, 18) * -0.16ch};
328
+ }
329
+ }
330
+ }
331
+ }
332
+
333
+ /// Returns a maximum line width based on the given scale
334
+ ///
335
+ /// @param {Number} $optimal-characters-per-line - number of the characters per line
336
+ /// @returns {String} maximum line width in ch
337
+ @function oPrivateTypographyMaxLineWidth($optimal-characters-per-line: 65) {
338
+ // a ch unit represents the width of the glyph "0"
339
+ // it's a wide glyph so we'll reduce the ch value by an arbitrary amount
340
+ // to bring our characters per line closer to the requested number on average
341
+ $magic-number: 0.75;
342
+ @return $optimal-characters-per-line * $magic-number * 1ch;
343
+ }
344
+
345
+ /// Body text styles
346
+ @mixin oPrivateTypographyBody() {
347
+ @include oPrivateTypographySans(1);
348
+ margin: 0 0 oPrivateSpacingByName('s6');
349
+ color: oPrivateFoundationGet('o3-color-use-case-body-text');
350
+ }
351
+
352
+ /// Output styles for page headings.
353
+ /// @example Output heading level 1 styles.
354
+ /// h1 {
355
+ /// @include oPrivateTypographyHeading($level: 1);
356
+ /// }
357
+ /// @example Output heading level 5 styles.
358
+ /// h5 {
359
+ /// @include oPrivateTypographyHeading($level: 5);
360
+ /// }
361
+ /// @param {Number} $level - The heading level 1-5.
362
+ @mixin oPrivateTypographyHeading($level) {
363
+ $headings: (
364
+ 'heading-level-one',
365
+ 'heading-level-two',
366
+ 'heading-level-three',
367
+ 'heading-level-four',
368
+ 'heading-level-five',
369
+ 'heading-level-six'
370
+ );
371
+
372
+ @if (type-of($level) != 'number' or $level < 1 or $level > 6) {
373
+ @error 'Heading level must be a Number 1-6. Found #{inspect($level)}.';
374
+ }
375
+
376
+ $heading-key: nth($headings, $level);
377
+
378
+ $heading-levels-with-attributes: (
379
+ 'heading-level-one': (
380
+ 'scale': 5,
381
+ 'weight': 'semibold',
382
+ ),
383
+ 'heading-level-two': (
384
+ 'scale': 4,
385
+ 'weight': 'semibold',
386
+ ),
387
+ 'heading-level-three': (
388
+ 'scale': 3,
389
+ 'weight': 'semibold',
390
+ ),
391
+ 'heading-level-four': (
392
+ 'scale': 2,
393
+ 'weight': 'semibold',
394
+ ),
395
+ 'heading-level-five': (
396
+ 'scale': 1,
397
+ 'weight': 'semibold',
398
+ ),
399
+ 'heading-level-six': (
400
+ 'scale': 0,
401
+ 'weight': 'semibold',
402
+ ),
403
+ );
404
+
405
+ $heading-attributes: map-get($heading-levels-with-attributes, $heading-key);
406
+ @include oPrivateTypographySans(
407
+ $scale: map-get($heading-attributes, 'scale'),
408
+ $weight: map-get($heading-attributes, 'weight')
409
+ );
410
+ color: oPrivateFoundationGet('o3-color-use-case-body-text');
411
+ margin: 0 0 oPrivateSpacingByName('s4');
412
+ }
413
+
414
+ /// A string representation of a hex value should be treated as a colour.
415
+ /// @param {String|Color|Null} $theme-value - A colour or palette colour name.
416
+ /// @return {Color|Null} - A colour, or pass through null.
417
+ @function _oPrivateTypographyGetColourFrom($theme-value) {
418
+ @if (type-of($theme-value) == 'string') {
419
+ $theme-value: unquote($theme-value);
420
+ }
421
+ // If we still have a string, assume it's a palette colour name.
422
+ $theme-value: if(
423
+ type-of($theme-value) == 'string',
424
+ oPrivateFoundationGet('o3-color-palette-#{$theme-value}'),
425
+ $theme-value
426
+ );
427
+ @return $theme-value;
428
+ }
@@ -0,0 +1,4 @@
1
+ @import '@financial-times/o-colors/main';
2
+
3
+ @import 'scss/shadows';
4
+ @import 'scss/variables';
@@ -0,0 +1,31 @@
1
+ /// Elevation
2
+ /// @param {String} $elevation [] - 'ultra', 'low', 'mid' or 'high'
3
+ /// @param {Color} $color []
4
+ /// @output A repeating linear gradient background
5
+ @mixin oPrivateVisualEffectsShadowContent($elevation: 'low', $color: $_o-pf-visual-effects-shadow-color) {
6
+ box-shadow: oPrivateVisualEffectsShadow($elevation, $color);
7
+ }
8
+
9
+ /// Elevation
10
+ /// @param {String} $elevation [] - 'ultra', 'low', 'mid' or 'high'
11
+ /// @param {Color} $color []
12
+ /// @output A repeating linear gradient background
13
+ @function oPrivateVisualEffectsShadow($elevation: 'low', $color: $_o-pf-visual-effects-shadow-color) {
14
+ @if $elevation == 'ultralow' {
15
+ @return 0 2px 2px rgba($color, 0.12), 0 4px 6px rgba($color, 0.1);
16
+ }
17
+
18
+ @if $elevation == 'low' {
19
+ @return 0 1px 2px rgba($color, 0.25), 0 4px 6px rgba($color, 0.1);
20
+ }
21
+
22
+ @if $elevation == 'mid' {
23
+ @return 0 1px 3px rgba($color, 0.2), 0 6px 10px rgba($color, 0.15);
24
+ }
25
+
26
+ @if $elevation == 'high' {
27
+ @return 0 1px 4px rgba($color, 0.15), 0 8px 14px rgba($color, 0.2);
28
+ }
29
+
30
+ @error 'A shadow with elevation "#{$elevation}" is not supported. Must be one of: "ultralow", "low", "mid", or "high".';
31
+ }
@@ -0,0 +1,13 @@
1
+ /// Timing function for elements that slide in and out
2
+ $o-pf-visual-effects-timing-slide: cubic-bezier(1, 0, 0.5, 1.275) !default;
3
+
4
+ /// Timing function for elements that expand and contract
5
+ $o-pf-visual-effects-timing-expand: cubic-bezier(0.215, 0.61, 0.355, 1) !default;
6
+
7
+ /// Timing function for elements that fade in and out
8
+ $o-pf-visual-effects-timing-fade: cubic-bezier(0.165, 0.84, 0.44, 1) !default;
9
+
10
+ /// The base dropdown shadow colour.
11
+ /// Used with opacity for shadows of different levels.
12
+ /// @type Color
13
+ $_o-pf-visual-effects-shadow-color: oPrivateFoundationGet('o3-color-palette-black-70');