pages_core 3.9.0 → 3.10.1
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.
- checksums.yaml +4 -4
- data/Rakefile +1 -3
- data/VERSION +1 -0
- data/app/assets/builds/pages_core/admin-dist.js +13 -13
- data/app/assets/stylesheets/pages/admin/controllers/pages.scss +6 -0
- data/app/controllers/admin/categories_controller.rb +3 -3
- data/app/controllers/admin/invites_controller.rb +1 -1
- data/app/controllers/admin/pages_controller.rb +1 -1
- data/app/controllers/admin/password_resets_controller.rb +7 -7
- data/app/controllers/admin/users_controller.rb +1 -1
- data/app/controllers/concerns/pages_core/error_reporting.rb +2 -0
- data/app/controllers/concerns/pages_core/ranged_response.rb +40 -0
- data/app/controllers/pages_core/attachments_controller.rb +6 -4
- data/app/controllers/pages_core/frontend/pages_controller.rb +1 -1
- data/app/controllers/sessions_controller.rb +5 -6
- data/app/javascript/components/ImageEditor/Form.jsx +1 -1
- data/app/javascript/components/ImageGrid.jsx +1 -1
- data/app/mailers/admin_mailer.rb +1 -1
- data/app/models/attachment.rb +1 -1
- data/app/models/concerns/pages_core/page_model/pathable.rb +1 -1
- data/app/models/invite.rb +0 -2
- data/app/models/page_category.rb +0 -1
- data/app/models/page_exporter.rb +2 -2
- data/app/models/password_reset_token.rb +0 -2
- data/app/models/tagging.rb +0 -2
- data/app/models/user.rb +1 -13
- data/app/views/admin/users/login.html.erb +2 -2
- data/app/views/admin/users/new_password.html.erb +1 -1
- data/app/views/admin_mailer/invite.text.erb +0 -2
- data/app/views/admin_mailer/password_reset.text.erb +0 -2
- data/app/views/feeds/pages.rss.builder +1 -1
- data/config/locales/en.yml +40 -14
- data/db/migrate/20220615160300_remove_username.rb +7 -0
- data/lib/pages_core/static_cache/page_cache_handler.rb +1 -1
- data/lib/pages_core/static_cache.rb +7 -3
- data/lib/rails/generators/pages_core/frontend/frontend_generator.rb +34 -34
- data/lib/rails/generators/pages_core/frontend/templates/{layout.html.erb → application.html.erb} +3 -0
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/GridOverlay.js +66 -0
- data/lib/rails/generators/pages_core/frontend/templates/javascript/lib/ResponsiveEmbeds.js +72 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/application.sass.scss +15 -0
- data/lib/rails/generators/pages_core/frontend/templates/{base.scss.erb → stylesheets/components/base.scss} +9 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/config.scss +26 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/breakpoints.scss +42 -0
- data/lib/rails/generators/pages_core/frontend/templates/{clearfix.scss.erb → stylesheets/framework/clearfix.scss} +0 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/fonts.scss +32 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/grid.scss +168 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/grid_overlay.scss +44 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/colors.scss +8 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/typography.scss +90 -0
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/vendor/normalize.css +349 -0
- metadata +26 -14
- data/lib/rails/generators/pages_core/frontend/templates/application.scss.erb +0 -3
- data/lib/rails/generators/pages_core/frontend/templates/breakpoints.scss.erb +0 -24
- data/lib/rails/generators/pages_core/frontend/templates/normalize.css.erb +0 -425
@@ -0,0 +1,66 @@
|
|
1
|
+
class GridOverlay {
|
2
|
+
constructor() {
|
3
|
+
this.gridOverlay = null;
|
4
|
+
this.showGrid = false;
|
5
|
+
this.init = this.init.bind(this);
|
6
|
+
}
|
7
|
+
|
8
|
+
bindHotkey() {
|
9
|
+
document.addEventListener("keyup", (evt) => {
|
10
|
+
if (evt.ctrlKey && evt.which == 71) {
|
11
|
+
this.toggle();
|
12
|
+
}
|
13
|
+
});
|
14
|
+
}
|
15
|
+
|
16
|
+
init() {
|
17
|
+
this.gridOverlay = document.querySelector(".grid-overlay");
|
18
|
+
if (this.gridOverlay) {
|
19
|
+
this.restoreState();
|
20
|
+
this.bindHotkey();
|
21
|
+
this.updateDOM();
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
ready(callback) {
|
26
|
+
if (document.readyState === "complete" ||
|
27
|
+
(document.readyState !== "loading" &&
|
28
|
+
!document.documentElement.doScroll)) {
|
29
|
+
callback();
|
30
|
+
} else {
|
31
|
+
document.addEventListener("DOMContentLoaded", callback);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
restoreState() {
|
36
|
+
this.showGrid = window.localStorage.getItem("showGrid");
|
37
|
+
}
|
38
|
+
|
39
|
+
saveState() {
|
40
|
+
if (this.showGrid) {
|
41
|
+
window.localStorage.setItem("showGrid", "true");
|
42
|
+
} else {
|
43
|
+
window.localStorage.removeItem("showGrid");
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
start() {
|
48
|
+
this.ready(this.init);
|
49
|
+
}
|
50
|
+
|
51
|
+
toggle() {
|
52
|
+
this.showGrid = !this.showGrid;
|
53
|
+
this.saveState();
|
54
|
+
this.updateDOM();
|
55
|
+
}
|
56
|
+
|
57
|
+
updateDOM() {
|
58
|
+
if (this.showGrid) {
|
59
|
+
this.gridOverlay.classList.add("grid-overlay--active");
|
60
|
+
} else {
|
61
|
+
this.gridOverlay.classList.remove("grid-overlay--active");
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
export default new GridOverlay();
|
@@ -0,0 +1,72 @@
|
|
1
|
+
class ResponsiveEmbeds {
|
2
|
+
readyHandler(fn) {
|
3
|
+
if (document.readyState === "complete" || document.readyState === "interactive") {
|
4
|
+
setTimeout(fn, 1);
|
5
|
+
} else {
|
6
|
+
document.addEventListener("DOMContentLoaded", fn);
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
wrapEmbeds() {
|
11
|
+
let selectors = [ "iframe[src*=\"bandcamp.com\"]",
|
12
|
+
"iframe[src*=\"player.vimeo.com\"]",
|
13
|
+
"iframe[src*=\"youtube.com\"]",
|
14
|
+
"iframe[src*=\"youtube-nocookie.com\"]",
|
15
|
+
"iframe[src*=\"spotify.com\"]",
|
16
|
+
"iframe[src*=\"kickstarter.com\"][src*=\"video.html\"]" ];
|
17
|
+
|
18
|
+
let embeds = Array.prototype.slice.call(
|
19
|
+
document.querySelectorAll(selectors.join(","))
|
20
|
+
);
|
21
|
+
|
22
|
+
function wrapEmbed(embed) {
|
23
|
+
const parent = embed.parentNode;
|
24
|
+
|
25
|
+
// Recycle the existing container if the embed is already responsive.
|
26
|
+
if (parent.tagName === "DIV" &&
|
27
|
+
parent.childNodes.length === 1 &&
|
28
|
+
parent.style.position === "relative") {
|
29
|
+
return parent;
|
30
|
+
}
|
31
|
+
|
32
|
+
let wrapper = document.createElement("div");
|
33
|
+
if (parent.tagName === "P") {
|
34
|
+
parent.parentNode.replaceChild(wrapper, parent);
|
35
|
+
} else {
|
36
|
+
parent.replaceChild(wrapper, embed);
|
37
|
+
}
|
38
|
+
wrapper.appendChild(embed);
|
39
|
+
return wrapper;
|
40
|
+
}
|
41
|
+
|
42
|
+
embeds.forEach(function (embed) {
|
43
|
+
if (embed.parentNode &&
|
44
|
+
embed.parentNode.classList.contains("responsive-embed")) {
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
|
48
|
+
let width = embed.offsetWidth;
|
49
|
+
let height = embed.offsetHeight;
|
50
|
+
let ratio = height / width;
|
51
|
+
let wrapper = wrapEmbed(embed);
|
52
|
+
|
53
|
+
wrapper.classList.add("responsive-embed");
|
54
|
+
wrapper.style.position = "relative";
|
55
|
+
wrapper.style.width = "100%";
|
56
|
+
wrapper.style.paddingTop = 0;
|
57
|
+
wrapper.style.paddingBottom = (ratio * 100) + "%";
|
58
|
+
|
59
|
+
embed.style.position = "absolute";
|
60
|
+
embed.style.width = "100%";
|
61
|
+
embed.style.height = "100%";
|
62
|
+
embed.style.top = "0";
|
63
|
+
embed.style.left = "0";
|
64
|
+
});
|
65
|
+
}
|
66
|
+
|
67
|
+
start() {
|
68
|
+
this.readyHandler(() => this.wrapEmbeds());
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
export default new ResponsiveEmbeds();
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// Entry point for your Sass build
|
2
|
+
@import
|
3
|
+
'vendor/normalize',
|
4
|
+
'config',
|
5
|
+
|
6
|
+
'framework/breakpoints',
|
7
|
+
'framework/clearfix',
|
8
|
+
'framework/grid',
|
9
|
+
'framework/grid_overlay',
|
10
|
+
'framework/fonts',
|
11
|
+
|
12
|
+
'global/colors',
|
13
|
+
'global/typography',
|
14
|
+
|
15
|
+
'components/base';
|
@@ -0,0 +1,26 @@
|
|
1
|
+
$breakpoints: (mobile: 900px,
|
2
|
+
large: 1400px);
|
3
|
+
|
4
|
+
$grids : (default: (column-count: 12,
|
5
|
+
column: 94px,
|
6
|
+
gutter: 24px,
|
7
|
+
padding: 24px),
|
8
|
+
mobile: (column-count: 4,
|
9
|
+
column: 60px,
|
10
|
+
gutter: 16px,
|
11
|
+
padding: 16px));
|
12
|
+
|
13
|
+
$spacings: (1: 8px,
|
14
|
+
2: 16px,
|
15
|
+
3: 24px,
|
16
|
+
4: 32px,
|
17
|
+
5: 40px,
|
18
|
+
6: 48px,
|
19
|
+
8: 64px,
|
20
|
+
9: 72px,
|
21
|
+
10: 80px,
|
22
|
+
16: 128px,
|
23
|
+
20: 160px);
|
24
|
+
|
25
|
+
// Uncomment to limit full width
|
26
|
+
// $limit-width: 1600px;
|
data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/breakpoints.scss
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
// ---- Defaults --------------------------------------------------------------
|
2
|
+
|
3
|
+
$breakpoints: (mobile: 900px,
|
4
|
+
large: 1400px) !default;
|
5
|
+
|
6
|
+
|
7
|
+
// ---- Mixins ----------------------------------------------------------------
|
8
|
+
|
9
|
+
@function breakpoint-value($value) {
|
10
|
+
@if type-of($value) == "string" {
|
11
|
+
@return map-get($breakpoints, $value);
|
12
|
+
}
|
13
|
+
@else {
|
14
|
+
@return $value;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
@mixin breakpoint($min: "", $max: "", $orientation: "") {
|
19
|
+
$query: "screen";
|
20
|
+
|
21
|
+
@if $min != "" {
|
22
|
+
$query: $query + ' and (min-width: #{breakpoint-value($min)})';
|
23
|
+
}
|
24
|
+
|
25
|
+
@if $max != "" {
|
26
|
+
$query: $query + ' and (max-width: #{breakpoint-value($max)})';
|
27
|
+
}
|
28
|
+
|
29
|
+
@if $orientation != "" {
|
30
|
+
$query: $query + ' and (orientation: #{$orientation})';
|
31
|
+
}
|
32
|
+
|
33
|
+
@media #{$query} {
|
34
|
+
@content;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
@mixin mobile {
|
39
|
+
@include breakpoint($max: mobile) {
|
40
|
+
@content
|
41
|
+
}
|
42
|
+
}
|
File without changes
|
@@ -0,0 +1,32 @@
|
|
1
|
+
@use "sass:list";
|
2
|
+
|
3
|
+
@function font-extension($format) {
|
4
|
+
$font-extensions: (opentype: "otf", truetype: "ttf");
|
5
|
+
$value: map-get($font-extensions, $format);
|
6
|
+
@if $value {
|
7
|
+
@return $value;
|
8
|
+
}
|
9
|
+
@else {
|
10
|
+
@return $format;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
@function font-sources($filename, $formats: ()) {
|
15
|
+
$urls: ();
|
16
|
+
@each $f in list.join((woff2 woff), $formats) {
|
17
|
+
$urls: list.append(
|
18
|
+
$urls,
|
19
|
+
url("#{$filename}.#{font-extension($f)}") format("#{$f}")
|
20
|
+
);
|
21
|
+
}
|
22
|
+
@return list.join($urls, (), comma);
|
23
|
+
}
|
24
|
+
|
25
|
+
@mixin font-face($name, $filename, $weight: 400, $style: normal, $formats: ()) {
|
26
|
+
@font-face {
|
27
|
+
font-family: $name;
|
28
|
+
font-style: $style;
|
29
|
+
font-weight: $weight;
|
30
|
+
src: font-sources($filename, $formats);
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,168 @@
|
|
1
|
+
@use "sass:math";
|
2
|
+
|
3
|
+
// ---- Defaults --------------------------------------------------------------
|
4
|
+
|
5
|
+
$base-font-size: 16px !default;
|
6
|
+
|
7
|
+
$grids : (default: (column-count: 12,
|
8
|
+
column: 94px,
|
9
|
+
gutter: 24px,
|
10
|
+
padding: 24px),
|
11
|
+
mobile: (column-count: 4,
|
12
|
+
column: 60px,
|
13
|
+
gutter: 16px,
|
14
|
+
padding: 16px)) !default;
|
15
|
+
|
16
|
+
$spacings: (1: 12px,
|
17
|
+
2: 24px,
|
18
|
+
4: 40px,
|
19
|
+
8: 80px) !default;
|
20
|
+
|
21
|
+
// Uncomment to limit full width
|
22
|
+
// $limit-width: 1600px !default;
|
23
|
+
|
24
|
+
|
25
|
+
// ---- Grid and sizing -------------------------------------------------------
|
26
|
+
|
27
|
+
@function grid-value($grid, $name) {
|
28
|
+
@return map-get(map-get($grids, $grid), $name);
|
29
|
+
}
|
30
|
+
|
31
|
+
// Inner width: Size of $grid in px, excluding outer padding
|
32
|
+
@function inner-width($grid: default) {
|
33
|
+
@return (grid-value($grid, column-count) * grid-value($grid, column)) +
|
34
|
+
((grid-value($grid, column-count) - 1) * grid-value($grid, gutter));
|
35
|
+
}
|
36
|
+
|
37
|
+
// Full width in px including padding
|
38
|
+
@function full-width($grid: default) {
|
39
|
+
@return inner-width($grid) + (grid-value($grid, padding) * 2);
|
40
|
+
}
|
41
|
+
|
42
|
+
@function px-to-percent($size, $grid: default) {
|
43
|
+
@return percentage(math.div($size, full-width($grid)));
|
44
|
+
}
|
45
|
+
|
46
|
+
@function px-to-vw($size, $grid: default) {
|
47
|
+
@return (math.div($size, full-width($grid)) * 100) * 1vw;
|
48
|
+
}
|
49
|
+
|
50
|
+
@function relative-size($size-px, $container: 100%, $grid: default) {
|
51
|
+
@if unit($container) == '%' {
|
52
|
+
$container: (inner-width($grid) * math.div($container, 100%));
|
53
|
+
}
|
54
|
+
@if (unit($container) != "px") {
|
55
|
+
$container: columns-px($container, $grid: $grid);
|
56
|
+
}
|
57
|
+
@return percentage(math.div($size-px, $container));
|
58
|
+
}
|
59
|
+
|
60
|
+
@function rem-calc($value, $grid: default) {
|
61
|
+
@if unit($value) == "rem" {
|
62
|
+
@return $value;
|
63
|
+
}
|
64
|
+
|
65
|
+
// Assume px for values without units
|
66
|
+
@if unit($value) == "" {
|
67
|
+
$value: $value * 1px;
|
68
|
+
}
|
69
|
+
|
70
|
+
// Convert percentage to px
|
71
|
+
@if unit($value) == "%" {
|
72
|
+
$value: full-width($grid) * math.div($value, 100%);
|
73
|
+
}
|
74
|
+
|
75
|
+
@return math.div($value, $base-font-size) * 1rem;
|
76
|
+
}
|
77
|
+
|
78
|
+
@function spacing($key) {
|
79
|
+
@return rem-calc(map-get($spacings, $key));
|
80
|
+
}
|
81
|
+
|
82
|
+
// Width of gutter in px
|
83
|
+
@function gutter-px($grid: default) {
|
84
|
+
@return grid-value($grid, gutter);
|
85
|
+
}
|
86
|
+
|
87
|
+
// Width of $n columns in px
|
88
|
+
@function columns-px($n: 1, $grid: default) {
|
89
|
+
@return grid-value($grid, column) * $n + ((ceil($n) - 1) * gutter-px($grid));
|
90
|
+
}
|
91
|
+
|
92
|
+
// Gutter width, optionally relative to size of $container
|
93
|
+
@function gutter($container: 100%, $grid: default) {
|
94
|
+
@return relative-size(gutter-px($grid: $grid), $container, $grid: $grid);
|
95
|
+
}
|
96
|
+
|
97
|
+
// Width of $n columns as a percentage of $container.
|
98
|
+
@function columns($n: 1, $container: 100%, $grid: default) {
|
99
|
+
@return relative-size(columns-px($n, $grid: $grid), $container, $grid: $grid);
|
100
|
+
}
|
101
|
+
|
102
|
+
// Equal to columns($n) + gutter()
|
103
|
+
@function columns-and-gutter($n: 1, $container: 100%, $grid: default) {
|
104
|
+
@return columns($n, $container, $grid) + gutter($container, $grid);
|
105
|
+
}
|
106
|
+
|
107
|
+
@function grid-adjust($size, $columns: $total-columns, $grid: default) {
|
108
|
+
@return math.div($sizem math.div(columns($columns, $grid: $grid), 100%));
|
109
|
+
}
|
110
|
+
|
111
|
+
@function outer-padding($grid: default) {
|
112
|
+
@return px-to-percent(grid-value($grid, padding), $grid: $grid);
|
113
|
+
}
|
114
|
+
|
115
|
+
@function limit-width-scale($value) {
|
116
|
+
@return $value * math.div($limit-width, full-width());
|
117
|
+
}
|
118
|
+
|
119
|
+
|
120
|
+
// ---- Styles ----------------------------------------------------------------
|
121
|
+
|
122
|
+
@mixin mobile-full {
|
123
|
+
@include mobile {
|
124
|
+
width: 100%;
|
125
|
+
margin-left: 0px;
|
126
|
+
margin-right: 0px;
|
127
|
+
float: none;
|
128
|
+
@content;
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
@mixin mobile-offset {
|
133
|
+
@include mobile {
|
134
|
+
$offset: px-to-percent(grid-value(mobile, padding), $grid: mobile);
|
135
|
+
|
136
|
+
width: 100% + $offset;
|
137
|
+
margin-left: 0 - math.div($offset, 2);
|
138
|
+
margin-right: 0 - math.div($offset, 2);
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
@mixin grid-container-inner {
|
143
|
+
margin: 0px auto;
|
144
|
+
@if variable-exists(limit-width) {
|
145
|
+
@include breakpoint($min: rem-calc($limit-width)) {
|
146
|
+
max-width: rem-calc(limit-width-scale(inner-width()));
|
147
|
+
}
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
@mixin grid-container {
|
152
|
+
padding-left: outer-padding();
|
153
|
+
padding-right: outer-padding();
|
154
|
+
|
155
|
+
@include mobile {
|
156
|
+
padding-left: outer-padding(mobile);
|
157
|
+
padding-right: outer-padding(mobile);
|
158
|
+
}
|
159
|
+
|
160
|
+
@media print {
|
161
|
+
padding-left: 0px;
|
162
|
+
padding-right: 0px;
|
163
|
+
}
|
164
|
+
|
165
|
+
.inner {
|
166
|
+
@include grid-container-inner;
|
167
|
+
}
|
168
|
+
}
|
data/lib/rails/generators/pages_core/frontend/templates/stylesheets/framework/grid_overlay.scss
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
$grid-overlay-color: rgba(255, 0, 255, 0.05) !default;
|
2
|
+
|
3
|
+
@function grid-background($grid: default) {
|
4
|
+
$gradient: ();
|
5
|
+
@for $i from 1 to grid-value($grid, column-count) {
|
6
|
+
$gradient: join($gradient,
|
7
|
+
($grid-overlay-color columns($i, $grid: $grid),
|
8
|
+
transparent columns($i, $grid: $grid),
|
9
|
+
transparent columns-and-gutter($i, $grid: $grid),
|
10
|
+
$grid-overlay-color (columns-and-gutter($i, $grid: $grid))),
|
11
|
+
comma);
|
12
|
+
}
|
13
|
+
@return linear-gradient(to right, #{$gradient});
|
14
|
+
}
|
15
|
+
|
16
|
+
.grid-overlay {
|
17
|
+
position: fixed;
|
18
|
+
z-index: 9000;
|
19
|
+
top: 0px;
|
20
|
+
left: 0px;
|
21
|
+
width: 100%;
|
22
|
+
height: 100%;
|
23
|
+
background-image: grid-background(default);
|
24
|
+
background-size: px-to-percent(inner-width(default)) 100%;
|
25
|
+
background-repeat: no-repeat;
|
26
|
+
background-position: 50% 50%;
|
27
|
+
pointer-events: none;
|
28
|
+
display: none;
|
29
|
+
|
30
|
+
@if variable-exists(limit-width) {
|
31
|
+
@include breakpoint($min: rem-calc($limit-width)) {
|
32
|
+
background-size: rem-calc(limit-width-scale(inner-width())) 100%;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
@include mobile {
|
37
|
+
background-image: grid-background(mobile);
|
38
|
+
background-size: px-to-percent(inner-width(mobile), $grid: mobile) 100%;
|
39
|
+
}
|
40
|
+
|
41
|
+
&--active {
|
42
|
+
display: block;
|
43
|
+
}
|
44
|
+
}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
$font-sans: 'Helvetica', sans-serif;
|
2
|
+
|
3
|
+
// ---- Mixins ----------------------------------------------------------------
|
4
|
+
|
5
|
+
@mixin child-margins {
|
6
|
+
&:first-child {
|
7
|
+
margin-top: 0px;
|
8
|
+
}
|
9
|
+
&:last-child {
|
10
|
+
margin-bottom: 0px;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
|
15
|
+
// ---- Definitions -----------------------------------------------------------
|
16
|
+
|
17
|
+
%text-larger { font: normal 72px/1.00 $font-sans; }
|
18
|
+
%text-large { font: normal 54px/1.04 $font-sans; }
|
19
|
+
%text-medium { font: normal 24px/1.25 $font-sans; }
|
20
|
+
%text-normal { font: normal 16px/1.50 $font-sans; }
|
21
|
+
%text-small { font: normal 14px/1.5 $font-sans; }
|
22
|
+
|
23
|
+
@include mobile {
|
24
|
+
%text-large { font: normal 32px/1.13 $font-sans; }
|
25
|
+
%text-medium { font: normal 22px/1.27 $font-sans; }
|
26
|
+
%text-normal { font: normal 16px/1.31 $font-sans; }
|
27
|
+
%text-small-mobile,
|
28
|
+
%text-small { font: normal 13px/1.31 $font-sans; }
|
29
|
+
}
|
30
|
+
|
31
|
+
|
32
|
+
// ---- Rules -----------------------------------------------------------------
|
33
|
+
|
34
|
+
body {
|
35
|
+
@extend %text-normal;
|
36
|
+
}
|
37
|
+
|
38
|
+
h1, h2, h3, h4, h5, h6, ul, ol, p {
|
39
|
+
margin: 0px 0px spacing(2) 0px;
|
40
|
+
&:last-child {
|
41
|
+
margin-bottom: 0px;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
h1 {
|
46
|
+
@extend %text-larger;
|
47
|
+
}
|
48
|
+
|
49
|
+
h2 {
|
50
|
+
@extend %text-large;
|
51
|
+
margin-top: spacing(10);
|
52
|
+
margin-bottom: spacing(10);
|
53
|
+
@include mobile {
|
54
|
+
margin-top: spacing(5);
|
55
|
+
margin-bottom: spacing(5);
|
56
|
+
}
|
57
|
+
@include child-margins;
|
58
|
+
}
|
59
|
+
|
60
|
+
h3 {
|
61
|
+
@extend %text-medium;
|
62
|
+
margin-top: spacing(5);
|
63
|
+
margin-bottom: spacing(5);
|
64
|
+
@include child-margins;
|
65
|
+
}
|
66
|
+
|
67
|
+
h4 {
|
68
|
+
font: inherit;
|
69
|
+
margin-top: spacing(5);
|
70
|
+
margin-bottom: 0px;
|
71
|
+
@include child-margins;
|
72
|
+
}
|
73
|
+
|
74
|
+
a, a:visited {
|
75
|
+
text-decoration: underline;
|
76
|
+
}
|
77
|
+
|
78
|
+
h1, h2, h3 {
|
79
|
+
a, a:visited {
|
80
|
+
text-decoration: none;
|
81
|
+
}
|
82
|
+
a:hover, a:focus {
|
83
|
+
text-decoration: underline;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
figcaption {
|
88
|
+
@extend %text-small;
|
89
|
+
margin-top: spacing(2);
|
90
|
+
}
|