├── .gitignore ├── README.md ├── assets ├── css │ ├── style.css │ └── style.min.css ├── img │ ├── favicon.ico │ ├── menu.svg │ └── sassline-logo.svg ├── js │ ├── responsive-nav.js │ └── responsive-nav.min.js └── sass │ ├── _sassline-base.scss │ ├── modules │ ├── _footer.scss │ ├── _globals.scss │ ├── _header.scss │ ├── _nav.scss │ └── _show-grid.scss │ ├── sassline-base │ ├── _layouts.scss │ ├── _mixins.scss │ ├── _modular-scale.scss │ ├── _reset.scss │ ├── _typography.scss │ └── _variables.scss │ └── style.scss ├── bower.json ├── gulpfile.js ├── index.html ├── package.json └── sache.json /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache 2 | .bundle 3 | /node_modules 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Sassline](https://sassline.com) 2 | 3 | Set text on the web to a baseline grid with Sass & rems using a responsive modular-scale. 4 | 5 | `Please note this code is p old now and is no longer actively maintained.` 6 | 7 | `Hey, you can do this all in pure CSS now — fun how things evolve in 10 years. I’ll see if I can work up a new version, stay tuned.` 8 | 9 | ## Do one thing well 10 | 11 | Sassline has one aim and one aim only – to spread better typography across the responsive environment of the web. 12 | 13 | The idea is to have easy to use and maintain SCSS partials utilising the power of Sass to make the complex calculations to set type on a baseline grid on the web, with a production ready CSS output. Using rems for the font-sizing and the spacing measurements gives a simple way to use the proportions of the baseline grid throughout the design. Sass mixins do all the heavy lifting so your job is easy. 14 | 15 | OpenType features are enabled with `font-feature-settings` to give the most appropriate formatting of text and some flourishes in the headings if available in the web font and supported in the browser. 16 | 17 | Sassline includes some basic layouts, and includes mixins to create a main column with optimal measure and a sidebar that doesn’t get too narrow. 18 | 19 | ## Root font-size = ½ line-height 20 | 21 | Sassline works by setting the root font-size as half the line-height of the standard paragraph text. The height of the baseline grid is then effectively set at 2rem, with increments at each 1rem. This makes it nice and easy to work proportionally from the baseline with integer rem values to create harmony in your layout and typography. This is based off a technique for setting text in print documents. 22 | 23 | ## Documentation 24 | 25 | Sassline is fully commented with details in the SCSS. Set the font sizes with the `fontsize` mixin, set the spacing using the `baseline` mixin or set both at once with the `sassline` mixin. Use rems for everything else. Full documentation is in the works. 26 | 27 | ### Running / compiling 28 | 29 | You can also use your preferred methods for compiling Sass as long as you have Sass 3.3.7+. To just include the necessary partials in your existing sass project, you only need to import [sassline-base.scss](assets/sass/_sassline-base.scss). 30 | 31 | If you want to run Sassline as a standalone project use the gulp setup included (or modify it to your needs). 32 | 33 | 1. Clone the repo or grab the zip file 34 | 2. Open a terminal window and `cd` into this directory 35 | 3. Run `npm install -g gulp` (this may need sudo in front) 36 | 4. Run `npm install` 37 | 38 | Once that is done you can start the server with `gulp` and stop it with `ctrl` + `c`. 39 | 40 | The pages will run at http://localhost:1234/ 41 | 42 | ### Sass file structure 43 | 44 | My preferred method is to work along the lines of the SMACSS & BEM method. In the sass folder there there are two folders — sassline-base and modules. The base folder has the Sassline base SCSS partials. The modules folder contains some demo SCSS partials with styles you can keep or remove. All new partials should be added to the modules folder and referenced in `style.scss` to be compiled into your CSS. 45 | 46 | ### More on information on using Sassline 47 | 48 | Please see [this blog post](https://jakegiltsoff.co.uk/posts/sassline-v2-0). 49 | 50 | ## Responsive Nav 51 | 52 | Ariel Salminen’s [responsive-nav.js](https://github.com/arielsalminen/responsive-nav.js) plugin is included to provide a mobile-ready navigation to work from. 53 | 54 | ## Browsers 55 | 56 | Sassline will set text to the baseline in recent versions of Chrome and Firefox, IE 11+ and Safari 8+. 57 | 58 | ## Roadmap 59 | 60 | - Full documentation 61 | 62 | ======== 63 | 64 | ## License 65 | 66 | Sassline is licensed under the MIT license. ([http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT)) 67 | -------------------------------------------------------------------------------- /assets/css/style.css: -------------------------------------------------------------------------------- 1 | /* CSS compiled from SCSS. */ 2 | /* --------------------------------------- */ 3 | * { 4 | box-sizing: border-box; } 5 | 6 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { 7 | margin: 0; 8 | padding: 0; 9 | border: 0; 10 | font-size: 100%; 11 | font: inherit; 12 | vertical-align: baseline; } 13 | 14 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { 15 | display: block; } 16 | 17 | html, body { 18 | height: 100%; } 19 | 20 | a img { 21 | border: none; } 22 | 23 | blockquote { 24 | quotes: none; } 25 | 26 | blockquote:before, blockquote:after { 27 | content: ''; 28 | content: none; } 29 | 30 | table { 31 | border-collapse: collapse; 32 | border-spacing: 0; } 33 | 34 | caption, th, td { 35 | text-align: left; 36 | font-weight: normal; 37 | vertical-align: middle; } 38 | 39 | html { 40 | -webkit-text-size-adjust: 100%; 41 | -ms-text-size-adjust: 100%; 42 | font-size: 75%; } 43 | @media screen and (min-width: 40em) { 44 | html { 45 | font-size: 87.5%; } } 46 | @media screen and (min-width: 50em) { 47 | html { 48 | font-size: 93.75%; } } 49 | @media screen and (min-width: 64em) { 50 | html { 51 | font-size: 106.25%; } } 52 | @media screen and (min-width: 100em) { 53 | html { 54 | font-size: 118.75%; } } 55 | 56 | body { 57 | font-family: Georgia, serif; 58 | font-style: normal; 59 | font-weight: 400; 60 | line-height: 2rem; 61 | font-size: 1.33333rem; } 62 | @media screen and (min-width: 40em) { 63 | body { 64 | font-size: 1.21429rem; } } 65 | @media screen and (min-width: 50em) { 66 | body { 67 | font-size: 1.2rem; } } 68 | @media screen and (min-width: 64em) { 69 | body { 70 | font-size: 1.17647rem; } } 71 | @media screen and (min-width: 100em) { 72 | body { 73 | font-size: 1.15789rem; } } 74 | 75 | a { 76 | color: #0E58F5; 77 | text-decoration: none; 78 | transition: color .1s, background-color .1s; } 79 | a:hover, a:active, a:focus { 80 | color: #0B348B; 81 | text-decoration: none; } 82 | 83 | .typeset p a, .typeset li a { 84 | background-image: linear-gradient(to bottom, transparent 50%, #709cf9 50%); 85 | background-position: 0 93%; 86 | background-repeat: repeat-x; 87 | background-size: 100% 0.15rem; 88 | text-shadow: 0.1rem 0 #FCFCFC, 0.15rem 0 #FCFCFC, -0.1rem 0 #FCFCFC, -0.15rem 0 #FCFCFC; } 89 | .typeset p a:hover, .typeset p a:active, .typeset p a:focus, .typeset li a:hover, .typeset li a:active, .typeset li a:focus { 90 | background-image: linear-gradient(to bottom, transparent 50%, #1257ea 50%); } 91 | 92 | .typeset p { 93 | -webkit-font-feature-settings: 'kern', 'onum', 'liga'; 94 | font-feature-settings: 'kern', 'onum', 'liga'; 95 | line-height: 2rem; 96 | margin-bottom: 1.43999rem; 97 | padding-top: 0.56001rem; } 98 | @media screen and (min-width: 40em) { 99 | .typeset p { 100 | margin-bottom: 1.4007rem; 101 | padding-top: 0.5993rem; } } 102 | @media screen and (min-width: 50em) { 103 | .typeset p { 104 | margin-bottom: 1.39599rem; 105 | padding-top: 0.60401rem; } } 106 | @media screen and (min-width: 64em) { 107 | .typeset p { 108 | margin-bottom: 1.38823rem; 109 | padding-top: 0.61177rem; } } 110 | @media screen and (min-width: 100em) { 111 | .typeset p { 112 | margin-bottom: 1.3821rem; 113 | padding-top: 0.6179rem; } } 114 | 115 | .typeset h1, .typeset h2, .typeset h3, .typeset h4, .typeset h5, .typeset h6 { 116 | color: #2E2E2E; 117 | font-family: Helvetica, sans-serif; 118 | -webkit-font-feature-settings: 'dlig', 'liga', 'lnum', 'kern'; 119 | font-feature-settings: 'dlig', 'liga', 'lnum', 'kern'; 120 | font-style: normal; 121 | font-weight: 700; } 122 | 123 | .typeset h1, .typeset .alpha { 124 | line-height: 3rem; 125 | font-size: 2.33333rem; 126 | margin-bottom: 0.26999rem; 127 | padding-top: 0.73001rem; } 128 | @media screen and (min-width: 40em) { 129 | .typeset h1, .typeset .alpha { 130 | font-size: 2.14286rem; 131 | margin-bottom: 0.20713rem; 132 | padding-top: 0.79287rem; } } 133 | @media screen and (min-width: 50em) { 134 | .typeset h1, .typeset .alpha { 135 | font-size: 2.13333rem; 136 | margin-bottom: 0.20399rem; 137 | padding-top: 0.79601rem; } } 138 | @media screen and (min-width: 64em) { 139 | .typeset h1, .typeset .alpha { 140 | font-size: 2.35294rem; 141 | margin-bottom: 0.27646rem; 142 | padding-top: 0.72354rem; } } 143 | @media screen and (min-width: 100em) { 144 | .typeset h1, .typeset .alpha { 145 | font-size: 2.63158rem; 146 | margin-bottom: 0.36841rem; 147 | padding-top: 0.63159rem; } } 148 | 149 | .typeset h2, .typeset .beta { 150 | line-height: 3rem; 151 | font-size: 2.08333rem; 152 | margin-bottom: 0.18749rem; 153 | padding-top: 0.81251rem; } 154 | @media screen and (min-width: 40em) { 155 | .typeset h2, .typeset .beta { 156 | font-size: 1.9rem; 157 | margin-bottom: 0.12699rem; 158 | padding-top: 0.87301rem; } } 159 | @media screen and (min-width: 50em) { 160 | .typeset h2, .typeset .beta { 161 | font-size: 1.87333rem; 162 | margin-bottom: 0.11819rem; 163 | padding-top: 0.88181rem; } } 164 | @media screen and (min-width: 64em) { 165 | .typeset h2, .typeset .beta { 166 | font-size: 2.08824rem; 167 | margin-bottom: 0.18911rem; 168 | padding-top: 0.81089rem; } } 169 | @media screen and (min-width: 100em) { 170 | .typeset h2, .typeset .beta { 171 | font-size: 2.31053rem; 172 | margin-bottom: 0.26246rem; 173 | padding-top: 0.73754rem; } } 174 | 175 | .typeset h3, .typeset .gamma { 176 | line-height: 3rem; 177 | font-size: 1.86667rem; 178 | margin-bottom: 0.11599rem; 179 | padding-top: 0.88401rem; } 180 | @media screen and (min-width: 40em) { 181 | .typeset h3, .typeset .gamma { 182 | font-size: 1.71429rem; 183 | margin-bottom: 0.0657rem; 184 | padding-top: 0.9343rem; } } 185 | @media screen and (min-width: 50em) { 186 | .typeset h3, .typeset .gamma { 187 | font-size: 1.70667rem; 188 | margin-bottom: 0.06319rem; 189 | padding-top: 0.93681rem; } } 190 | @media screen and (min-width: 64em) { 191 | .typeset h3, .typeset .gamma { 192 | font-size: 1.76471rem; 193 | margin-bottom: 0.08234rem; 194 | padding-top: 0.91766rem; } } 195 | @media screen and (min-width: 100em) { 196 | .typeset h3, .typeset .gamma { 197 | font-size: 1.85789rem; 198 | margin-bottom: 0.1131rem; 199 | padding-top: 0.8869rem; } } 200 | 201 | .typeset h4, .typeset .delta { 202 | line-height: 2rem; 203 | font-size: 1.66667rem; 204 | margin-bottom: -0.45001rem; 205 | padding-top: 0.45001rem; } 206 | @media screen and (min-width: 40em) { 207 | .typeset h4, .typeset .delta { 208 | font-size: 1.52143rem; 209 | margin-bottom: -0.49794rem; 210 | padding-top: 0.49794rem; } } 211 | @media screen and (min-width: 50em) { 212 | .typeset h4, .typeset .delta { 213 | font-size: 1.5rem; 214 | margin-bottom: -0.50501rem; 215 | padding-top: 0.50501rem; } } 216 | @media screen and (min-width: 64em) { 217 | .typeset h4, .typeset .delta { 218 | font-size: 1.57059rem; 219 | margin-bottom: -0.48172rem; 220 | padding-top: 0.48172rem; } } 221 | @media screen and (min-width: 100em) { 222 | .typeset h4, .typeset .delta { 223 | font-size: 1.63684rem; 224 | margin-bottom: -0.45985rem; 225 | padding-top: 0.45985rem; } } 226 | 227 | .typeset h5, .typeset .epsilon { 228 | line-height: 2rem; 229 | font-size: 1.49167rem; 230 | margin-bottom: -0.50776rem; 231 | padding-top: 0.50776rem; } 232 | @media screen and (min-width: 40em) { 233 | .typeset h5, .typeset .epsilon { 234 | font-size: 1.37143rem; 235 | margin-bottom: -0.54744rem; 236 | padding-top: 0.54744rem; } } 237 | @media screen and (min-width: 50em) { 238 | .typeset h5, .typeset .epsilon { 239 | font-size: 1.36667rem; 240 | margin-bottom: -0.54901rem; 241 | padding-top: 0.54901rem; } } 242 | @media screen and (min-width: 64em) { 243 | .typeset h5, .typeset .epsilon { 244 | font-size: 1.32353rem; 245 | margin-bottom: -0.56325rem; 246 | padding-top: 0.56325rem; } } 247 | @media screen and (min-width: 100em) { 248 | .typeset h5, .typeset .epsilon { 249 | font-size: 1.31579rem; 250 | margin-bottom: -0.5658rem; 251 | padding-top: 0.5658rem; } } 252 | 253 | .typeset h6, .typeset .zeta { 254 | line-height: 2rem; 255 | font-size: 1.33333rem; 256 | margin-bottom: -0.56001rem; 257 | padding-top: 0.56001rem; } 258 | @media screen and (min-width: 40em) { 259 | .typeset h6, .typeset .zeta { 260 | font-size: 1.21429rem; 261 | margin-bottom: -0.5993rem; 262 | padding-top: 0.5993rem; } } 263 | @media screen and (min-width: 50em) { 264 | .typeset h6, .typeset .zeta { 265 | font-size: 1.2rem; 266 | margin-bottom: -0.60401rem; 267 | padding-top: 0.60401rem; } } 268 | @media screen and (min-width: 64em) { 269 | .typeset h6, .typeset .zeta { 270 | font-size: 1.17647rem; 271 | margin-bottom: -0.61177rem; 272 | padding-top: 0.61177rem; } } 273 | @media screen and (min-width: 100em) { 274 | .typeset h6, .typeset .zeta { 275 | font-size: 1.15789rem; 276 | margin-bottom: -0.6179rem; 277 | padding-top: 0.6179rem; } } 278 | 279 | .typeset ul, .typeset ol { 280 | line-height: 2rem; 281 | margin-bottom: 1.43999rem; 282 | padding-top: 0.56001rem; } 283 | @media screen and (min-width: 40em) { 284 | .typeset ul, .typeset ol { 285 | margin-bottom: 1.4007rem; 286 | padding-top: 0.5993rem; } } 287 | @media screen and (min-width: 50em) { 288 | .typeset ul, .typeset ol { 289 | margin-bottom: 1.39599rem; 290 | padding-top: 0.60401rem; } } 291 | @media screen and (min-width: 64em) { 292 | .typeset ul, .typeset ol { 293 | margin-bottom: 1.38823rem; 294 | padding-top: 0.61177rem; } } 295 | @media screen and (min-width: 100em) { 296 | .typeset ul, .typeset ol { 297 | margin-bottom: 1.3821rem; 298 | padding-top: 0.6179rem; } } 299 | .typeset ul li, .typeset ol li { 300 | -webkit-font-feature-settings: 'kern', 'onum', 'liga'; 301 | font-feature-settings: 'kern', 'onum', 'liga'; 302 | margin-left: 2rem; } 303 | @media screen and (min-width: 40em) { 304 | .typeset ul li, .typeset ol li { 305 | margin-left: 0; } } 306 | .typeset ul li ol, .typeset ul li ul, .typeset ol li ol, .typeset ol li ul { 307 | padding-top: 1rem; 308 | margin-bottom: 1rem; 309 | margin-left: 2rem; } 310 | 311 | .typeset ol { 312 | list-style-type: none; } 313 | .typeset ol li { 314 | counter-increment: top-level; } 315 | .typeset ol li:before { 316 | content: counter(top-level) "."; 317 | -webkit-font-feature-settings: 'lnum', 'tnum'; 318 | font-feature-settings: 'lnum', 'tnum'; 319 | margin-left: -3rem; 320 | position: absolute; 321 | text-align: right; 322 | width: 2em; } 323 | .typeset ol li ul li:before { 324 | content: ''; } 325 | .typeset ol li ul li ol li { 326 | counter-increment: alt-level; } 327 | .typeset ol li ul li ol li:before { 328 | content: counter(alt-level) "."; } 329 | .typeset ol li ol li { 330 | counter-increment: sub-level; } 331 | .typeset ol li ol li:before { 332 | content: counter(top-level) "." counter(sub-level); } 333 | .typeset ol li ol li ul li:before { 334 | content: ''; } 335 | .typeset ol li ol li ol li { 336 | counter-increment: sub-sub-level; } 337 | .typeset ol li ol li ol li:before { 338 | content: counter(top-level) "." counter(sub-level) "." counter(sub-sub-level); } 339 | 340 | .typeset dl { 341 | line-height: 2rem; 342 | margin-bottom: 1.43999rem; 343 | padding-top: 0.56001rem; } 344 | @media screen and (min-width: 40em) { 345 | .typeset dl { 346 | margin-bottom: 1.4007rem; 347 | padding-top: 0.5993rem; } } 348 | @media screen and (min-width: 50em) { 349 | .typeset dl { 350 | margin-bottom: 1.39599rem; 351 | padding-top: 0.60401rem; } } 352 | @media screen and (min-width: 64em) { 353 | .typeset dl { 354 | margin-bottom: 1.38823rem; 355 | padding-top: 0.61177rem; } } 356 | @media screen and (min-width: 100em) { 357 | .typeset dl { 358 | margin-bottom: 1.3821rem; 359 | padding-top: 0.6179rem; } } 360 | .typeset dl dt, .typeset dl dd { 361 | -webkit-font-feature-settings: 'kern', 'onum', 'liga'; 362 | font-feature-settings: 'kern', 'onum', 'liga'; 363 | margin-left: 2rem; } 364 | @media screen and (min-width: 40em) { 365 | .typeset dl dt, .typeset dl dd { 366 | margin-left: 0; } } 367 | .typeset dl dt { 368 | font-weight: 700; } 369 | .typeset dl dd + dt { 370 | padding-top: 1rem; } 371 | 372 | .typeset table { 373 | font-family: Helvetica, sans-serif; 374 | -webkit-font-feature-settings: 'liga', 'lnum', 'tnum', 'kern'; 375 | font-feature-settings: 'liga', 'lnum', 'tnum', 'kern'; 376 | font-style: normal; 377 | font-weight: 400; 378 | width: 100%; 379 | line-height: 2rem; 380 | font-size: 1.19167rem; 381 | margin-bottom: -0.60676rem; 382 | padding-top: 0.60676rem; } 383 | @media screen and (min-width: 40em) { 384 | .typeset table { 385 | font-size: 1.09286rem; 386 | margin-bottom: -0.63937rem; 387 | padding-top: 0.63937rem; } } 388 | @media screen and (min-width: 50em) { 389 | .typeset table { 390 | font-size: 1.08667rem; 391 | margin-bottom: -0.64141rem; 392 | padding-top: 0.64141rem; } } 393 | @media screen and (min-width: 64em) { 394 | .typeset table { 395 | font-size: 0.99412rem; 396 | margin-bottom: -0.67195rem; 397 | padding-top: 0.67195rem; } } 398 | @media screen and (min-width: 100em) { 399 | .typeset table { 400 | font-size: 0.92632rem; 401 | margin-bottom: -0.69433rem; 402 | padding-top: 0.69433rem; } } 403 | .typeset table thead th { 404 | line-height: 2rem; 405 | font-size: 1.33333rem; 406 | margin-bottom: -0.56001rem; 407 | padding-top: 0.56001rem; 408 | padding-bottom: 1px; } 409 | @media screen and (min-width: 40em) { 410 | .typeset table thead th { 411 | font-size: 1.21429rem; 412 | margin-bottom: -0.5993rem; 413 | padding-top: 0.5993rem; } } 414 | @media screen and (min-width: 50em) { 415 | .typeset table thead th { 416 | font-size: 1.2rem; 417 | margin-bottom: -0.60401rem; 418 | padding-top: 0.60401rem; } } 419 | @media screen and (min-width: 64em) { 420 | .typeset table thead th { 421 | font-size: 1.17647rem; 422 | margin-bottom: -0.61177rem; 423 | padding-top: 0.61177rem; } } 424 | @media screen and (min-width: 100em) { 425 | .typeset table thead th { 426 | font-size: 1.15789rem; 427 | margin-bottom: -0.6179rem; 428 | padding-top: 0.6179rem; } } 429 | 430 | .typeset b, .typeset strong, .typeset .bold { 431 | font-weight: 700; } 432 | 433 | .typeset em, .typeset i, .typeset .italic { 434 | font-style: italic; } 435 | 436 | .typeset small, .typeset .caption { 437 | font-family: Helvetica, sans-serif; 438 | font-style: normal; 439 | font-weight: 400; 440 | font-size: 1.06667rem; } 441 | @media screen and (min-width: 40em) { 442 | .typeset small, .typeset .caption { 443 | font-size: 0.97143rem; } } 444 | @media screen and (min-width: 50em) { 445 | .typeset small, .typeset .caption { 446 | font-size: 0.96rem; } } 447 | @media screen and (min-width: 64em) { 448 | .typeset small, .typeset .caption { 449 | font-size: 0.88235rem; } } 450 | @media screen and (min-width: 100em) { 451 | .typeset small, .typeset .caption { 452 | font-size: 0.82105rem; } } 453 | 454 | .typeset small { 455 | line-height: 1rem; } 456 | 457 | .typeset .caption { 458 | color: #BDC8CC; 459 | line-height: 2rem; 460 | margin-bottom: 1.35199rem; 461 | padding-top: 0.64801rem; } 462 | @media screen and (min-width: 40em) { 463 | .typeset .caption { 464 | margin-bottom: 1.32056rem; 465 | padding-top: 0.67944rem; } } 466 | @media screen and (min-width: 50em) { 467 | .typeset .caption { 468 | margin-bottom: 1.31679rem; 469 | padding-top: 0.68321rem; } } 470 | @media screen and (min-width: 64em) { 471 | .typeset .caption { 472 | margin-bottom: 1.29117rem; 473 | padding-top: 0.70883rem; } } 474 | @media screen and (min-width: 100em) { 475 | .typeset .caption { 476 | margin-bottom: 1.27094rem; 477 | padding-top: 0.72906rem; } } 478 | 479 | .typeset h1 + .caption, .typeset .alpha + .caption, .typeset h2 + .caption, .typeset .beta + .caption, .typeset h3 + .caption, .typeset .gamma + .caption { 480 | margin-top: -1rem; } 481 | 482 | .typeset .delta + .caption, .typeset .epsilon + .caption, .typeset .zeta + .caption { 483 | margin-top: 0rem; } 484 | 485 | .typeset blockquote p { 486 | border-left: 0.15rem solid #0E58F5; 487 | font-style: italic; 488 | padding-left: 1rem; 489 | margin-bottom: 1.87999rem; 490 | padding-bottom: 0.56001rem; } 491 | @media screen and (min-width: 40em) { 492 | .typeset blockquote p { 493 | margin-bottom: 1.80142rem; 494 | padding-bottom: 0.5993rem; } } 495 | @media screen and (min-width: 50em) { 496 | .typeset blockquote p { 497 | margin-bottom: 1.79199rem; 498 | padding-bottom: 0.60401rem; } } 499 | @media screen and (min-width: 64em) { 500 | .typeset blockquote p { 501 | margin-bottom: 1.77646rem; 502 | padding-bottom: 0.61177rem; } } 503 | @media screen and (min-width: 100em) { 504 | .typeset blockquote p { 505 | margin-bottom: 1.7642rem; 506 | padding-bottom: 0.6179rem; } } 507 | 508 | @media screen and (min-width: 40em) { 509 | .typeset blockquote { 510 | margin-left: -1rem; } } 511 | 512 | .typeset hr { 513 | background-image: linear-gradient(to bottom, transparent 50%, #BDC8CC 50%); 514 | background-position: 0 50%; 515 | background-repeat: repeat-x; 516 | background-size: 100% 0.15rem; 517 | border: 0; 518 | margin: 0; 519 | padding-bottom: 3rem; 520 | padding-top: 3rem; } 521 | 522 | .typeset code, .typeset pre { 523 | background-color: #F5F4F2; 524 | font-family: Menlo, monospace; } 525 | 526 | .typeset pre { 527 | display: block; 528 | margin-bottom: 2rem; 529 | padding: 1rem; 530 | white-space: pre; 531 | white-space: pre-wrap; 532 | word-break: break-all; 533 | word-wrap: break-word; } 534 | 535 | .typeset code { 536 | line-height: 1rem; 537 | font-size: 1.06667rem; } 538 | @media screen and (min-width: 40em) { 539 | .typeset code { 540 | font-size: 0.97143rem; } } 541 | @media screen and (min-width: 50em) { 542 | .typeset code { 543 | font-size: 0.96rem; } } 544 | @media screen and (min-width: 64em) { 545 | .typeset code { 546 | font-size: 0.88235rem; } } 547 | @media screen and (min-width: 100em) { 548 | .typeset code { 549 | font-size: 0.82105rem; } } 550 | 551 | .typeset .upper { 552 | -webkit-font-kerning: normal; 553 | font-kerning: normal; 554 | letter-spacing: 0.1rem; 555 | text-transform: uppercase; } 556 | 557 | .typeset .small-caps { 558 | -webkit-font-feature-settings: 'smcp', 'kern'; 559 | font-feature-settings: 'smcp', 'kern'; 560 | -webkit-font-kerning: normal; 561 | font-kerning: normal; 562 | letter-spacing: 0.1rem; } 563 | 564 | .typeset .lining-numerals { 565 | -webkit-font-feature-settings: 'lnum', 'kern'; 566 | font-feature-settings: 'lnum', 'kern'; } 567 | 568 | .typeset .oldstyle-numerals { 569 | -webkit-font-feature-settings: 'onum', 'kern'; 570 | font-feature-settings: 'onum', 'kern'; } 571 | 572 | .section { 573 | margin: 0 auto; 574 | position: relative; 575 | width: 94%; } 576 | .section:before, .section:after { 577 | display: table; 578 | content: ""; } 579 | .section:after { 580 | clear: both; } 581 | @media screen and (min-width: 64em) { 582 | .section { 583 | max-width: 64.70588rem; } } 584 | @media screen and (min-width: 100em) { 585 | .section { 586 | max-width: 68.42105rem; } } 587 | 588 | .single-measure { 589 | margin: 0 auto; 590 | max-width: 41.66667rem; } 591 | @media screen and (min-width: 40em) { 592 | .single-measure { 593 | max-width: 39.28571rem; } } 594 | @media screen and (min-width: 50em) { 595 | .single-measure { 596 | max-width: 40rem; } } 597 | @media screen and (min-width: 64em) { 598 | .single-measure { 599 | max-width: 40rem; } } 600 | @media screen and (min-width: 100em) { 601 | .single-measure { 602 | max-width: 39.47368rem; } } 603 | 604 | .column { 605 | margin: 0 auto; 606 | width: 100%; 607 | max-width: 41.66667rem; } 608 | @media screen and (min-width: 40em) { 609 | .column { 610 | float: left; 611 | margin: inherit; 612 | max-width: auto; 613 | padding-left: 1rem; 614 | padding-right: 1rem; } } 615 | @media screen and (min-width: 64em) { 616 | .column { 617 | padding-left: 2rem; 618 | padding-right: 2rem; } } 619 | 620 | @media screen and (min-width: 40em) { 621 | .column--duo { 622 | width: 50%; } 623 | .column--duo:nth-child(3n) { 624 | clear: left; } 625 | .column--duo:nth-child(n+3) { 626 | margin-top: 2rem; } } 627 | 628 | @media screen and (min-width: 40em) { 629 | .column--trio { 630 | width: 33.333%; } 631 | .column--trio:nth-child(4n) { 632 | clear: left; } 633 | .column--trio:nth-child(n+4) { 634 | margin-top: 2rem; } } 635 | 636 | @media screen and (min-width: 40em) { 637 | .column--quad { 638 | width: 50%; } } 639 | 640 | @media screen and (min-width: 50em) { 641 | .column--quad { 642 | width: 25%; } } 643 | 644 | @media screen and (min-width: 40em) { 645 | .column--main { 646 | max-width: 65%; } } 647 | 648 | @media screen and (min-width: 50em) { 649 | .column--main { 650 | max-width: 65%; } } 651 | 652 | @media screen and (min-width: 64em) { 653 | .column--main { 654 | max-width: 65%; } } 655 | 656 | @media screen and (min-width: 100em) { 657 | .column--main { 658 | max-width: 63.53846%; } } 659 | 660 | @media screen and (min-width: 40em) { 661 | .column--sidebar { 662 | padding-right: 2rem; 663 | max-width: 35%; } } 664 | 665 | @media screen and (min-width: 50em) { 666 | .column--sidebar { 667 | max-width: 35%; } } 668 | 669 | @media screen and (min-width: 64em) { 670 | .column--sidebar { 671 | padding-right: 4rem; 672 | max-width: 35%; } } 673 | 674 | @media screen and (min-width: 100em) { 675 | .column--sidebar { 676 | max-width: 36.46154%; } } 677 | 678 | @media screen and (min-width: 40em) { 679 | .column--main + .column--sidebar { 680 | padding-left: 2rem; 681 | padding-right: 1rem; } } 682 | 683 | @media screen and (min-width: 64em) { 684 | .column--main + .column--sidebar { 685 | padding-left: 4rem; 686 | padding-right: 2rem; } } 687 | 688 | @media screen and (min-width: 64em) { 689 | .column--trio p, 690 | .column--quad p, 691 | .column--sidebar p { 692 | line-height: 2rem; 693 | font-size: 0.99412rem; 694 | margin-bottom: 1.32805rem; 695 | padding-top: 0.67195rem; } 696 | .column--trio li, 697 | .column--quad li, 698 | .column--sidebar li { 699 | font-size: 0.99412rem; } } 700 | 701 | @media screen and (min-width: 100em) { 702 | .column--trio p, 703 | .column--quad p, 704 | .column--sidebar p { 705 | line-height: 2rem; 706 | font-size: 0.92632rem; 707 | margin-bottom: 1.30567rem; 708 | padding-top: 0.69433rem; } 709 | .column--trio li, 710 | .column--quad li, 711 | .column--sidebar li { 712 | font-size: 0.92632rem; } } 713 | 714 | @media screen and (min-width: 40em) { 715 | .column--right { 716 | max-width: 65%; 717 | margin-left: 35%; } } 718 | 719 | @media screen and (min-width: 50em) { 720 | .column--right { 721 | max-width: 65%; 722 | margin-left: 35%; } } 723 | 724 | @media screen and (min-width: 64em) { 725 | .column--right { 726 | max-width: 65%; 727 | margin-left: 35%; } } 728 | 729 | @media screen and (min-width: 100em) { 730 | .column--right { 731 | max-width: 63.53846%; 732 | margin-left: 36.46154%; } } 733 | 734 | @media screen and (min-width: 40em) { 735 | .column--right .sidenote { 736 | left: 0; 737 | padding-left: 1rem; 738 | padding-right: 2rem; 739 | position: absolute; 740 | max-width: 35%; } } 741 | 742 | @media screen and (min-width: 50em) { 743 | .column--right .sidenote { 744 | max-width: 35%; } } 745 | 746 | @media screen and (min-width: 64em) { 747 | .column--right .sidenote { 748 | padding-right: 4rem; 749 | max-width: 35%; } } 750 | 751 | @media screen and (min-width: 100em) { 752 | .column--right .sidenote { 753 | padding-left: 2rem; 754 | max-width: 36.46154%; } } 755 | 756 | @media screen and (min-width: 40em) { 757 | .column--left { 758 | max-width: 65%; } } 759 | 760 | @media screen and (min-width: 50em) { 761 | .column--left { 762 | max-width: 65%; } } 763 | 764 | @media screen and (min-width: 64em) { 765 | .column--left { 766 | max-width: 65%; } } 767 | 768 | @media screen and (min-width: 100em) { 769 | .column--left { 770 | max-width: 63.53846%; } } 771 | 772 | @media screen and (min-width: 40em) { 773 | .column--left .sidenote { 774 | padding-left: 2rem; 775 | padding-right: 1rem; 776 | position: absolute; 777 | max-width: 35%; 778 | left: 65%; } } 779 | 780 | @media screen and (min-width: 50em) { 781 | .column--left .sidenote { 782 | max-width: 35%; 783 | left: 65%; } } 784 | 785 | @media screen and (min-width: 64em) { 786 | .column--left .sidenote { 787 | padding-left: 4rem; 788 | max-width: 35%; 789 | left: 65%; } } 790 | 791 | @media screen and (min-width: 100em) { 792 | .column--left .sidenote { 793 | padding-right: 2rem; 794 | max-width: 36.46154%; 795 | left: 63.53846%; } } 796 | 797 | body { 798 | background-color: #FCFCFC; 799 | color: #494949; 800 | overflow-x: hidden; } 801 | 802 | .section { 803 | padding: 2rem 0; } 804 | @media screen and (min-width: 40em) { 805 | .section { 806 | padding: 3rem 0; } } 807 | @media screen and (min-width: 50em) { 808 | .section { 809 | padding: 4rem 0; } } 810 | 811 | img { 812 | -ms-interpolation-mode: bicubic; 813 | height: auto; 814 | vertical-align: middle; 815 | width: 100%; } 816 | @media screen and (min-width: 40em) { 817 | img { 818 | margin: 0 auto; 819 | max-width: 100%; 820 | width: auto; } } 821 | 822 | .button-align { 823 | line-height: 2rem; 824 | margin-bottom: 1.43999rem; 825 | padding-top: 0.56001rem; } 826 | @media screen and (min-width: 40em) { 827 | .button-align { 828 | margin-bottom: 1.4007rem; 829 | padding-top: 0.5993rem; } } 830 | @media screen and (min-width: 50em) { 831 | .button-align { 832 | margin-bottom: 1.39599rem; 833 | padding-top: 0.60401rem; } } 834 | @media screen and (min-width: 64em) { 835 | .button-align { 836 | margin-bottom: 1.38823rem; 837 | padding-top: 0.61177rem; } } 838 | @media screen and (min-width: 100em) { 839 | .button-align { 840 | margin-bottom: 1.3821rem; 841 | padding-top: 0.6179rem; } } 842 | 843 | .nav-collapse ul { 844 | display: block; 845 | list-style: none; 846 | margin: 0; 847 | padding: 0; 848 | width: 100%; } 849 | 850 | .nav-collapse li { 851 | display: block; 852 | width: 100%; } 853 | 854 | .nav-collapse.opened { 855 | max-height: 9999px; } 856 | 857 | .js .nav-collapse { 858 | clip: rect(0 0 0 0); 859 | display: block; 860 | max-height: 0; 861 | overflow: hidden; 862 | position: absolute; 863 | zoom: 1; } 864 | @media screen and (min-width: 40em) { 865 | .js .nav-collapse { 866 | max-height: none; 867 | position: relative; } } 868 | 869 | .disable-pointer-events { 870 | pointer-events: none; } 871 | 872 | .nav-toggle { 873 | -webkit-tap-highlight-color: transparent; 874 | -webkit-touch-callout: none; 875 | -webkit-user-select: none; 876 | -moz-user-select: none; 877 | -ms-user-select: none; 878 | -o-user-select: none; 879 | user-select: none; } 880 | @media screen and (min-width: 40em) { 881 | .nav-toggle { 882 | display: none; } } 883 | 884 | @media screen and (min-width: 40em) { 885 | .main-nav { 886 | display: inline-block; 887 | width: calc(100% - 132px - 2rem); 888 | vertical-align: middle; } } 889 | 890 | .main-nav .main-nav__list { 891 | border-top: 0.1rem solid #d9d9d9; } 892 | @media screen and (min-width: 40em) { 893 | .main-nav .main-nav__list { 894 | border: 0; 895 | background-color: transparent; 896 | margin-left: 0; 897 | text-align: right; 898 | width: 100%; } } 899 | 900 | .main-nav li { 901 | font-family: Helvetica, sans-serif; 902 | font-style: normal; 903 | font-weight: 400; 904 | font-size: 1.33333rem; } 905 | .main-nav li a, .main-nav li span { 906 | -webkit-user-select: none; 907 | -moz-user-select: none; 908 | -ms-user-select: none; 909 | user-select: none; 910 | border-bottom: 0.1rem solid #d9d9d9; 911 | color: #0E58F5; 912 | cursor: pointer; 913 | display: block; 914 | padding: 10px 3%; } 915 | .main-nav li a:hover, .main-nav li a:active, .main-nav li a:focus, .main-nav li span:hover, .main-nav li span:active, .main-nav li span:focus { 916 | background-color: #0E58F5; 917 | color: #FFFFFF; } 918 | @media screen and (min-width: 40em) { 919 | .main-nav li { 920 | display: inline-block; 921 | letter-spacing: 0.1rem; 922 | margin-right: 2rem; 923 | padding: 1rem 0; 924 | text-transform: uppercase; 925 | width: auto; 926 | font-size: 0.85714rem; } 927 | .main-nav li a, .main-nav li span { 928 | border: 0; 929 | color: #BDC8CC; 930 | display: inline; 931 | padding: 0; } 932 | .main-nav li a:hover, .main-nav li a:active, .main-nav li a:focus, .main-nav li span:hover, .main-nav li span:active, .main-nav li span:focus { 933 | background-color: transparent; 934 | color: #0E58F5; } } 935 | @media screen and (min-width: 50em) { 936 | .main-nav li { 937 | font-size: 0.8rem; } } 938 | @media screen and (min-width: 64em) { 939 | .main-nav li { 940 | font-size: 0.70588rem; } } 941 | @media screen and (min-width: 100em) { 942 | .main-nav li { 943 | font-size: 0.63158rem; } } 944 | 945 | @media screen and (min-width: 40em) { 946 | .js .nav-collapse { 947 | display: inline-block; 948 | max-height: none; 949 | position: relative; } } 950 | 951 | .js .nav-toggle { 952 | display: block; 953 | line-height: 0; 954 | position: absolute; 955 | right: 3%; 956 | top: 1.3rem; } 957 | .js .nav-toggle:after { 958 | background-image: url(../img/menu.svg); 959 | background-position: 0 0; 960 | background-size: 30px 60px; 961 | content: ''; 962 | display: block; 963 | height: 30px; 964 | width: 30px; } 965 | .js .nav-toggle.active:after { 966 | background-position: 0 30px; } 967 | @media screen and (min-width: 40em) { 968 | .js .nav-toggle { 969 | display: none; } } 970 | 971 | .global-header { 972 | background-color: #FCFCFC; 973 | font-size: 0; } 974 | .global-header .global-header__logo { 975 | background-image: url(../img/sassline-logo.svg); 976 | background-size: 132px 19px; 977 | color: transparent; 978 | display: inline-block; 979 | font: 0/0 a; 980 | height: 19px; 981 | margin: 2rem 0 2rem 3%; 982 | position: relative; 983 | vertical-align: middle; 984 | width: 132px; } 985 | @media screen and (min-width: 40em) { 986 | .global-header .global-header__logo { 987 | margin-left: 2rem; } } 988 | .global-header .global-header__logo a { 989 | bottom: 0; 990 | left: 0; 991 | position: absolute; 992 | right: 0; 993 | top: 0; } 994 | 995 | .global-footer p { 996 | color: #BDC8CC; 997 | font-family: Helvetica, sans-serif; 998 | font-style: normal; 999 | font-weight: 400; 1000 | padding: 1rem 0; 1001 | margin: 0; 1002 | text-align: center; 1003 | font-size: 1.19167rem; } 1004 | @media screen and (min-width: 40em) { 1005 | .global-footer p { 1006 | font-size: 1.09286rem; } } 1007 | @media screen and (min-width: 50em) { 1008 | .global-footer p { 1009 | font-size: 1.08667rem; } } 1010 | @media screen and (min-width: 64em) { 1011 | .global-footer p { 1012 | font-size: 0.99412rem; } } 1013 | @media screen and (min-width: 100em) { 1014 | .global-footer p { 1015 | font-size: 0.92632rem; } } 1016 | 1017 | #baseline.show-grid { 1018 | background-image: linear-gradient(to bottom, cyan 0, rgba(255, 255, 255, 0) 1px); 1019 | background-repeat: repeat-y; 1020 | background-size: 100% 1rem; } 1021 | -------------------------------------------------------------------------------- /assets/css/style.min.css: -------------------------------------------------------------------------------- 1 | .typeset pre,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}*{box-sizing:border-box}a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}.typeset p,body{line-height:2rem}caption,img,td,th{vertical-align:middle}body,html{height:100%}a img{border:none}blockquote{quotes:none}blockquote:after,blockquote:before{content:'';content:none}table{border-collapse:collapse;border-spacing:0}caption,td,th{text-align:left;font-weight:400}html{-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;font-size:75%}@media screen and (min-width:40em){html{font-size:87.5%}}@media screen and (min-width:50em){html{font-size:93.75%}}@media screen and (min-width:64em){html{font-size:106.25%}}@media screen and (min-width:100em){html{font-size:118.75%}}body{font-family:Georgia,serif;font-style:normal;font-weight:400;font-size:1.33333rem}a{color:#0E58F5;text-decoration:none;transition:color .1s,background-color .1s}a:active,a:focus,a:hover{color:#0B348B;text-decoration:none}.typeset li a,.typeset p a{background-image:linear-gradient(to bottom,transparent 50%,#709cf9 50%);background-position:0 93%;background-repeat:repeat-x;background-size:100% .15rem;text-shadow:.1rem 0 #FCFCFC,.15rem 0 #FCFCFC,-.1rem 0 #FCFCFC,-.15rem 0 #FCFCFC}.typeset li a:active,.typeset li a:focus,.typeset li a:hover,.typeset p a:active,.typeset p a:focus,.typeset p a:hover{background-image:linear-gradient(to bottom,transparent 50%,#1257ea 50%)}.typeset p{-webkit-font-feature-settings:'kern','onum','liga';font-feature-settings:'kern','onum','liga';margin-bottom:1.43999rem;padding-top:.56001rem}@media screen and (min-width:40em){body{font-size:1.21429rem}.typeset p{margin-bottom:1.4007rem;padding-top:.5993rem}}@media screen and (min-width:50em){body{font-size:1.2rem}.typeset p{margin-bottom:1.39599rem;padding-top:.60401rem}}@media screen and (min-width:64em){body{font-size:1.17647rem}.typeset p{margin-bottom:1.38823rem;padding-top:.61177rem}}@media screen and (min-width:100em){body{font-size:1.15789rem}.typeset p{margin-bottom:1.3821rem;padding-top:.6179rem}}.typeset h1,.typeset h2,.typeset h3,.typeset h4,.typeset h5,.typeset h6{color:#2E2E2E;font-family:Helvetica,sans-serif;-webkit-font-feature-settings:'dlig','liga','lnum','kern';font-feature-settings:'dlig','liga','lnum','kern';font-style:normal;font-weight:700}.typeset .alpha,.typeset h1{line-height:3rem;font-size:2.33333rem;margin-bottom:.26999rem;padding-top:.73001rem}@media screen and (min-width:40em){.typeset .alpha,.typeset h1{font-size:2.14286rem;margin-bottom:.20713rem;padding-top:.79287rem}}@media screen and (min-width:50em){.typeset .alpha,.typeset h1{font-size:2.13333rem;margin-bottom:.20399rem;padding-top:.79601rem}}@media screen and (min-width:64em){.typeset .alpha,.typeset h1{font-size:2.35294rem;margin-bottom:.27646rem;padding-top:.72354rem}}@media screen and (min-width:100em){.typeset .alpha,.typeset h1{font-size:2.63158rem;margin-bottom:.36841rem;padding-top:.63159rem}}.typeset .beta,.typeset h2{line-height:3rem;font-size:2.08333rem;margin-bottom:.18749rem;padding-top:.81251rem}@media screen and (min-width:40em){.typeset .beta,.typeset h2{font-size:1.9rem;margin-bottom:.12699rem;padding-top:.87301rem}}@media screen and (min-width:50em){.typeset .beta,.typeset h2{font-size:1.87333rem;margin-bottom:.11819rem;padding-top:.88181rem}}@media screen and (min-width:64em){.typeset .beta,.typeset h2{font-size:2.08824rem;margin-bottom:.18911rem;padding-top:.81089rem}}@media screen and (min-width:100em){.typeset .beta,.typeset h2{font-size:2.31053rem;margin-bottom:.26246rem;padding-top:.73754rem}}.typeset .gamma,.typeset h3{line-height:3rem;font-size:1.86667rem;margin-bottom:.11599rem;padding-top:.88401rem}@media screen and (min-width:40em){.typeset .gamma,.typeset h3{font-size:1.71429rem;margin-bottom:.0657rem;padding-top:.9343rem}}@media screen and (min-width:50em){.typeset .gamma,.typeset h3{font-size:1.70667rem;margin-bottom:.06319rem;padding-top:.93681rem}}@media screen and (min-width:64em){.typeset .gamma,.typeset h3{font-size:1.76471rem;margin-bottom:.08234rem;padding-top:.91766rem}}@media screen and (min-width:100em){.typeset .gamma,.typeset h3{font-size:1.85789rem;margin-bottom:.1131rem;padding-top:.8869rem}}.typeset .delta,.typeset h4{line-height:2rem;font-size:1.66667rem;margin-bottom:-.45001rem;padding-top:.45001rem}@media screen and (min-width:40em){.typeset .delta,.typeset h4{font-size:1.52143rem;margin-bottom:-.49794rem;padding-top:.49794rem}}@media screen and (min-width:50em){.typeset .delta,.typeset h4{font-size:1.5rem;margin-bottom:-.50501rem;padding-top:.50501rem}}@media screen and (min-width:64em){.typeset .delta,.typeset h4{font-size:1.57059rem;margin-bottom:-.48172rem;padding-top:.48172rem}}@media screen and (min-width:100em){.typeset .delta,.typeset h4{font-size:1.63684rem;margin-bottom:-.45985rem;padding-top:.45985rem}}.typeset .epsilon,.typeset h5{line-height:2rem;font-size:1.49167rem;margin-bottom:-.50776rem;padding-top:.50776rem}@media screen and (min-width:40em){.typeset .epsilon,.typeset h5{font-size:1.37143rem;margin-bottom:-.54744rem;padding-top:.54744rem}}@media screen and (min-width:50em){.typeset .epsilon,.typeset h5{font-size:1.36667rem;margin-bottom:-.54901rem;padding-top:.54901rem}}@media screen and (min-width:64em){.typeset .epsilon,.typeset h5{font-size:1.32353rem;margin-bottom:-.56325rem;padding-top:.56325rem}}@media screen and (min-width:100em){.typeset .epsilon,.typeset h5{font-size:1.31579rem;margin-bottom:-.5658rem;padding-top:.5658rem}}.typeset .zeta,.typeset h6{line-height:2rem;font-size:1.33333rem;margin-bottom:-.56001rem;padding-top:.56001rem}@media screen and (min-width:40em){.typeset .zeta,.typeset h6{font-size:1.21429rem;margin-bottom:-.5993rem;padding-top:.5993rem}}@media screen and (min-width:50em){.typeset .zeta,.typeset h6{font-size:1.2rem;margin-bottom:-.60401rem;padding-top:.60401rem}}@media screen and (min-width:64em){.typeset .zeta,.typeset h6{font-size:1.17647rem;margin-bottom:-.61177rem;padding-top:.61177rem}}@media screen and (min-width:100em){.typeset .zeta,.typeset h6{font-size:1.15789rem;margin-bottom:-.6179rem;padding-top:.6179rem}}.typeset ol,.typeset ul{line-height:2rem;margin-bottom:1.43999rem;padding-top:.56001rem}@media screen and (min-width:40em){.typeset ol,.typeset ul{margin-bottom:1.4007rem;padding-top:.5993rem}}@media screen and (min-width:50em){.typeset ol,.typeset ul{margin-bottom:1.39599rem;padding-top:.60401rem}}@media screen and (min-width:64em){.typeset ol,.typeset ul{margin-bottom:1.38823rem;padding-top:.61177rem}}@media screen and (min-width:100em){.typeset ol,.typeset ul{margin-bottom:1.3821rem;padding-top:.6179rem}}.typeset ol li,.typeset ul li{-webkit-font-feature-settings:'kern','onum','liga';font-feature-settings:'kern','onum','liga';margin-left:2rem}@media screen and (min-width:40em){.typeset ol li,.typeset ul li{margin-left:0}}.typeset ol li ol,.typeset ol li ul,.typeset ul li ol,.typeset ul li ul{padding-top:1rem;margin-bottom:1rem;margin-left:2rem}.typeset ol{list-style-type:none}.typeset ol li{counter-increment:top-level}.typeset ol li:before{content:counter(top-level) ".";-webkit-font-feature-settings:'lnum','tnum';font-feature-settings:'lnum','tnum';margin-left:-3rem;position:absolute;text-align:right;width:2em}.typeset ol li ul li:before{content:''}.typeset ol li ul li ol li{counter-increment:alt-level}.typeset ol li ul li ol li:before{content:counter(alt-level) "."}.typeset ol li ol li{counter-increment:sub-level}.typeset ol li ol li:before{content:counter(top-level) "." counter(sub-level)}.typeset ol li ol li ul li:before{content:''}.typeset ol li ol li ol li{counter-increment:sub-sub-level}.typeset ol li ol li ol li:before{content:counter(top-level) "." counter(sub-level) "." counter(sub-sub-level)}.typeset dl{line-height:2rem;margin-bottom:1.43999rem;padding-top:.56001rem}@media screen and (min-width:40em){.typeset dl{margin-bottom:1.4007rem;padding-top:.5993rem}}@media screen and (min-width:50em){.typeset dl{margin-bottom:1.39599rem;padding-top:.60401rem}}@media screen and (min-width:64em){.typeset dl{margin-bottom:1.38823rem;padding-top:.61177rem}}@media screen and (min-width:100em){.typeset dl{margin-bottom:1.3821rem;padding-top:.6179rem}}.typeset dl dd,.typeset dl dt{-webkit-font-feature-settings:'kern','onum','liga';font-feature-settings:'kern','onum','liga';margin-left:2rem}.typeset dl dt{font-weight:700}.typeset dl dd+dt{padding-top:1rem}.typeset table{font-family:Helvetica,sans-serif;-webkit-font-feature-settings:'liga','lnum','tnum','kern';font-feature-settings:'liga','lnum','tnum','kern';font-style:normal;font-weight:400;width:100%;line-height:2rem;font-size:1.19167rem;margin-bottom:-.60676rem;padding-top:.60676rem}@media screen and (min-width:40em){.typeset dl dd,.typeset dl dt{margin-left:0}.typeset table{font-size:1.09286rem;margin-bottom:-.63937rem;padding-top:.63937rem}}@media screen and (min-width:50em){.typeset table{font-size:1.08667rem;margin-bottom:-.64141rem;padding-top:.64141rem}}@media screen and (min-width:64em){.typeset table{font-size:.99412rem;margin-bottom:-.67195rem;padding-top:.67195rem}}@media screen and (min-width:100em){.typeset table{font-size:.92632rem;margin-bottom:-.69433rem;padding-top:.69433rem}}.typeset table thead th{line-height:2rem;font-size:1.33333rem;margin-bottom:-.56001rem;padding-top:.56001rem;padding-bottom:1px}@media screen and (min-width:40em){.typeset table thead th{font-size:1.21429rem;margin-bottom:-.5993rem;padding-top:.5993rem}}@media screen and (min-width:50em){.typeset table thead th{font-size:1.2rem;margin-bottom:-.60401rem;padding-top:.60401rem}}@media screen and (min-width:64em){.typeset table thead th{font-size:1.17647rem;margin-bottom:-.61177rem;padding-top:.61177rem}}@media screen and (min-width:100em){.typeset table thead th{font-size:1.15789rem;margin-bottom:-.6179rem;padding-top:.6179rem}}.typeset .bold,.typeset b,.typeset strong{font-weight:700}.typeset .italic,.typeset em,.typeset i{font-style:italic}.typeset .caption,.typeset small{font-family:Helvetica,sans-serif;font-style:normal;font-weight:400;font-size:1.06667rem}.typeset small{line-height:1rem}.typeset .caption{color:#BDC8CC;line-height:2rem;margin-bottom:1.35199rem;padding-top:.64801rem}@media screen and (min-width:40em){.typeset .caption,.typeset small{font-size:.97143rem}.typeset .caption{margin-bottom:1.32056rem;padding-top:.67944rem}}@media screen and (min-width:50em){.typeset .caption,.typeset small{font-size:.96rem}.typeset .caption{margin-bottom:1.31679rem;padding-top:.68321rem}}@media screen and (min-width:64em){.typeset .caption,.typeset small{font-size:.88235rem}.typeset .caption{margin-bottom:1.29117rem;padding-top:.70883rem}}@media screen and (min-width:100em){.typeset .caption,.typeset small{font-size:.82105rem}.typeset .caption{margin-bottom:1.27094rem;padding-top:.72906rem}}.typeset .alpha+.caption,.typeset .beta+.caption,.typeset .gamma+.caption,.typeset h1+.caption,.typeset h2+.caption,.typeset h3+.caption{margin-top:-1rem}.typeset .delta+.caption,.typeset .epsilon+.caption,.typeset .zeta+.caption{margin-top:0}.typeset blockquote p{border-left:.15rem solid #0E58F5;font-style:italic;padding-left:1rem;margin-bottom:1.87999rem;padding-bottom:.56001rem}@media screen and (min-width:40em){.typeset blockquote p{margin-bottom:1.80142rem;padding-bottom:.5993rem}.typeset blockquote{margin-left:-1rem}}@media screen and (min-width:50em){.typeset blockquote p{margin-bottom:1.79199rem;padding-bottom:.60401rem}}@media screen and (min-width:64em){.typeset blockquote p{margin-bottom:1.77646rem;padding-bottom:.61177rem}}@media screen and (min-width:100em){.typeset blockquote p{margin-bottom:1.7642rem;padding-bottom:.6179rem}}.typeset hr{background-image:linear-gradient(to bottom,transparent 50%,#BDC8CC 50%);background-position:0 50%;background-repeat:repeat-x;background-size:100% .15rem;border:0;margin:0;padding-bottom:3rem;padding-top:3rem}.typeset code,.typeset pre{background-color:#F5F4F2;font-family:Menlo,monospace}.typeset pre{margin-bottom:2rem;padding:1rem;white-space:pre;white-space:pre-wrap;word-break:break-all;word-wrap:break-word}.typeset code{line-height:1rem;font-size:1.06667rem}@media screen and (min-width:40em){.typeset code{font-size:.97143rem}}@media screen and (min-width:50em){.typeset code{font-size:.96rem}}.typeset .upper{-webkit-font-kerning:normal;font-kerning:normal;letter-spacing:.1rem;text-transform:uppercase}.typeset .small-caps{-webkit-font-feature-settings:'smcp','kern';font-feature-settings:'smcp','kern';-webkit-font-kerning:normal;font-kerning:normal;letter-spacing:.1rem}.typeset .lining-numerals{-webkit-font-feature-settings:'lnum','kern';font-feature-settings:'lnum','kern'}.typeset .oldstyle-numerals{-webkit-font-feature-settings:'onum','kern';font-feature-settings:'onum','kern'}.section{margin:0;position:relative;width:94%}.section:after,.section:before{display:table;content:""}.section:after{clear:both}@media screen and (min-width:64em){.typeset code{font-size:.88235rem}.section{max-width:64.70588rem}}@media screen and (min-width:100em){.typeset code{font-size:.82105rem}.section{max-width:68.42105rem}}.single-measure{margin:0 auto;max-width:41.66667rem}@media screen and (min-width:40em){.single-measure{max-width:39.28571rem}}@media screen and (min-width:50em){.single-measure{max-width:40rem}}@media screen and (min-width:64em){.single-measure{max-width:40rem}}@media screen and (min-width:100em){.single-measure{max-width:39.47368rem}}.column{margin:0 auto;width:100%;max-width:41.66667rem}@media screen and (min-width:40em){.column{float:left;margin:inherit;max-width:auto;padding-left:1rem;padding-right:1rem}.column--duo{width:50%}.column--duo:nth-child(3n){clear:left}.column--duo:nth-child(n+3){margin-top:2rem}.column--trio{width:33.333%}.column--trio:nth-child(4n){clear:left}.column--trio:nth-child(n+4){margin-top:2rem}.column--quad{width:50%}.column--main{max-width:65%}}@media screen and (min-width:50em){.column--quad{width:25%}.column--main{max-width:65%}}@media screen and (min-width:64em){.column{padding-left:2rem;padding-right:2rem}.column--main{max-width:65%}}@media screen and (min-width:100em){.column--main{max-width:63.53846%}}@media screen and (min-width:40em){.column--sidebar{padding-right:2rem;max-width:35%}}@media screen and (min-width:50em){.column--sidebar{max-width:35%}}@media screen and (min-width:64em){.column--sidebar{padding-right:4rem;max-width:35%}}@media screen and (min-width:40em){.column--main+.column--sidebar{padding-left:2rem;padding-right:1rem}}@media screen and (min-width:64em){.column--main+.column--sidebar{padding-left:4rem;padding-right:2rem}.column--quad p,.column--sidebar p,.column--trio p{line-height:2rem;font-size:.99412rem;margin-bottom:1.32805rem;padding-top:.67195rem}.column--quad li,.column--sidebar li,.column--trio li{font-size:.99412rem}}@media screen and (min-width:100em){.column--sidebar{max-width:36.46154%}.column--quad p,.column--sidebar p,.column--trio p{line-height:2rem;font-size:.92632rem;margin-bottom:1.30567rem;padding-top:.69433rem}.column--quad li,.column--sidebar li,.column--trio li{font-size:.92632rem}}@media screen and (min-width:40em){.column--right{max-width:65%;margin-left:35%}}@media screen and (min-width:50em){.column--right{max-width:65%;margin-left:35%}}@media screen and (min-width:64em){.column--right{max-width:65%;margin-left:35%}}@media screen and (min-width:100em){.column--right{max-width:63.53846%;margin-left:36.46154%}}@media screen and (min-width:40em){.column--right .sidenote{left:0;padding-left:1rem;padding-right:2rem;position:absolute;max-width:35%}}@media screen and (min-width:50em){.column--right .sidenote{max-width:35%}}@media screen and (min-width:64em){.column--right .sidenote{padding-right:4rem;max-width:35%}}@media screen and (min-width:100em){.column--right .sidenote{padding-left:2rem;max-width:36.46154%}}@media screen and (min-width:40em){.column--left{max-width:65%}}@media screen and (min-width:50em){.column--left{max-width:65%}}@media screen and (min-width:64em){.column--left{max-width:65%}}@media screen and (min-width:100em){.column--left{max-width:63.53846%}}@media screen and (min-width:40em){.column--left .sidenote{padding-left:2rem;padding-right:1rem;position:absolute;max-width:35%;left:65%}}@media screen and (min-width:50em){.column--left .sidenote{max-width:35%;left:65%}}@media screen and (min-width:64em){.column--left .sidenote{padding-left:4rem;max-width:35%;left:65%}}@media screen and (min-width:100em){.column--left .sidenote{padding-right:2rem;max-width:36.46154%;left:63.53846%}}body{background-color:#FCFCFC;color:#494949;overflow-x:hidden}.section{padding:2rem 0}@media screen and (min-width:40em){.section{padding:3rem 0}}@media screen and (min-width:50em){.section{padding:4rem 0}}img{-ms-interpolation-mode:bicubic;height:auto;width:100%}@media screen and (min-width:40em){img{margin:0 auto;max-width:100%;width:auto}}.nav-collapse li,.nav-collapse ul{width:100%;display:block}.button-align{line-height:2rem;margin-bottom:1.43999rem;padding-top:.56001rem}@media screen and (min-width:40em){.button-align{margin-bottom:1.4007rem;padding-top:.5993rem}}@media screen and (min-width:50em){.button-align{margin-bottom:1.39599rem;padding-top:.60401rem}}@media screen and (min-width:64em){.button-align{margin-bottom:1.38823rem;padding-top:.61177rem}}@media screen and (min-width:100em){.button-align{margin-bottom:1.3821rem;padding-top:.6179rem}}.nav-collapse ul{list-style:none;margin:0;padding:0}.nav-collapse.opened{max-height:9999px}.js .nav-collapse{clip:rect(0 0 0 0);display:block;max-height:0;overflow:hidden;position:absolute;zoom:1}.disable-pointer-events{pointer-events:none}.nav-toggle{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.main-nav .main-nav__list{border-top:.1rem solid #d9d9d9}@media screen and (min-width:40em){.js .nav-collapse{max-height:none;position:relative}.nav-toggle{display:none}.main-nav{display:inline-block;width:calc(100% - 132px - 2rem);vertical-align:middle}.main-nav .main-nav__list{border:0;background-color:transparent;margin-left:0;text-align:right;width:100%}}.main-nav li{font-family:Helvetica,sans-serif;font-style:normal;font-weight:400;font-size:1.33333rem}.main-nav li a,.main-nav li span{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-bottom:.1rem solid #d9d9d9;color:#0E58F5;cursor:pointer;display:block;padding:10px 3%}.main-nav li a:active,.main-nav li a:focus,.main-nav li a:hover,.main-nav li span:active,.main-nav li span:focus,.main-nav li span:hover{background-color:#0E58F5;color:#FFF}@media screen and (min-width:40em){.main-nav li{display:inline-block;letter-spacing:.1rem;margin-right:2rem;padding:1rem 0;text-transform:uppercase;width:auto;font-size:.85714rem}.main-nav li a,.main-nav li span{border:0;color:#BDC8CC;display:inline;padding:0}.main-nav li a:active,.main-nav li a:focus,.main-nav li a:hover,.main-nav li span:active,.main-nav li span:focus,.main-nav li span:hover{background-color:transparent;color:#0E58F5}.js .nav-collapse{display:inline-block;max-height:none;position:relative}}@media screen and (min-width:50em){.main-nav li{font-size:.8rem}}@media screen and (min-width:64em){.main-nav li{font-size:.70588rem}}@media screen and (min-width:100em){.main-nav li{font-size:.63158rem}}.js .nav-toggle{display:block;line-height:0;position:absolute;right:3%;top:1.3rem}.js .nav-toggle:after{background-image:url(../img/menu.svg);background-position:0 0;background-size:30px 60px;content:'';display:block;height:30px;width:30px}.js .nav-toggle.active:after{background-position:0 30px}@media screen and (min-width:40em){.js .nav-toggle{display:none}}.global-header{background-color:#FCFCFC;font-size:0}.global-header .global-header__logo{background-image:url(../img/sassline-logo.svg);background-size:132px 19px;color:transparent;display:inline-block;font:0/0 a;height:19px;margin:2rem 0 2rem 3%;position:relative;vertical-align:middle;width:132px}@media screen and (min-width:40em){.global-header .global-header__logo{margin-left:2rem}}.global-header .global-header__logo a{bottom:0;left:0;position:absolute;right:0;top:0}.global-footer p{color:#BDC8CC;font-family:Helvetica,sans-serif;font-style:normal;font-weight:400;padding:1rem 0;margin:0;text-align:center;font-size:1.19167rem}@media screen and (min-width:40em){.global-footer p{font-size:1.09286rem}}@media screen and (min-width:50em){.global-footer p{font-size:1.08667rem}}@media screen and (min-width:64em){.global-footer p{font-size:.99412rem}}@media screen and (min-width:100em){.global-footer p{font-size:.92632rem}}#baseline.show-grid{background-image:linear-gradient(to bottom,#0ff 0,rgba(255,255,255,0) 1px);background-repeat:repeat-y;background-size:100% 1rem} -------------------------------------------------------------------------------- /assets/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakegiltsoff/sassline/ca2a15deccf2b75ad31fde2e3f3a4cdf9c7ac55a/assets/img/favicon.ico -------------------------------------------------------------------------------- /assets/img/menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/img/sassline-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/js/responsive-nav.js: -------------------------------------------------------------------------------- 1 | /*! responsive-nav.js 1.0.39 2 | * https://github.com/viljamis/responsive-nav.js 3 | * http://responsive-nav.com 4 | * 5 | * Copyright (c) 2015 @viljamis 6 | * Available under the MIT license 7 | */ 8 | 9 | /* global Event */ 10 | (function (document, window, index) { 11 | // Index is used to keep multiple navs on the same page namespaced 12 | 13 | "use strict"; 14 | 15 | var responsiveNav = function (el, options) { 16 | 17 | var computed = !!window.getComputedStyle; 18 | 19 | /** 20 | * getComputedStyle polyfill for old browsers 21 | */ 22 | if (!computed) { 23 | window.getComputedStyle = function(el) { 24 | this.el = el; 25 | this.getPropertyValue = function(prop) { 26 | var re = /(\-([a-z]){1})/g; 27 | if (prop === "float") { 28 | prop = "styleFloat"; 29 | } 30 | if (re.test(prop)) { 31 | prop = prop.replace(re, function () { 32 | return arguments[2].toUpperCase(); 33 | }); 34 | } 35 | return el.currentStyle[prop] ? el.currentStyle[prop] : null; 36 | }; 37 | return this; 38 | }; 39 | } 40 | /* exported addEvent, removeEvent, getChildren, setAttributes, addClass, removeClass, forEach */ 41 | 42 | /** 43 | * Add Event 44 | * fn arg can be an object or a function, thanks to handleEvent 45 | * read more at: http://www.thecssninja.com/javascript/handleevent 46 | * 47 | * @param {element} element 48 | * @param {event} event 49 | * @param {Function} fn 50 | * @param {boolean} bubbling 51 | */ 52 | var addEvent = function (el, evt, fn, bubble) { 53 | if ("addEventListener" in el) { 54 | // BBOS6 doesn't support handleEvent, catch and polyfill 55 | try { 56 | el.addEventListener(evt, fn, bubble); 57 | } catch (e) { 58 | if (typeof fn === "object" && fn.handleEvent) { 59 | el.addEventListener(evt, function (e) { 60 | // Bind fn as this and set first arg as event object 61 | fn.handleEvent.call(fn, e); 62 | }, bubble); 63 | } else { 64 | throw e; 65 | } 66 | } 67 | } else if ("attachEvent" in el) { 68 | // check if the callback is an object and contains handleEvent 69 | if (typeof fn === "object" && fn.handleEvent) { 70 | el.attachEvent("on" + evt, function () { 71 | // Bind fn as this 72 | fn.handleEvent.call(fn); 73 | }); 74 | } else { 75 | el.attachEvent("on" + evt, fn); 76 | } 77 | } 78 | }, 79 | 80 | /** 81 | * Remove Event 82 | * 83 | * @param {element} element 84 | * @param {event} event 85 | * @param {Function} fn 86 | * @param {boolean} bubbling 87 | */ 88 | removeEvent = function (el, evt, fn, bubble) { 89 | if ("removeEventListener" in el) { 90 | try { 91 | el.removeEventListener(evt, fn, bubble); 92 | } catch (e) { 93 | if (typeof fn === "object" && fn.handleEvent) { 94 | el.removeEventListener(evt, function (e) { 95 | fn.handleEvent.call(fn, e); 96 | }, bubble); 97 | } else { 98 | throw e; 99 | } 100 | } 101 | } else if ("detachEvent" in el) { 102 | if (typeof fn === "object" && fn.handleEvent) { 103 | el.detachEvent("on" + evt, function () { 104 | fn.handleEvent.call(fn); 105 | }); 106 | } else { 107 | el.detachEvent("on" + evt, fn); 108 | } 109 | } 110 | }, 111 | 112 | /** 113 | * Get the children of any element 114 | * 115 | * @param {element} 116 | * @return {array} Returns matching elements in an array 117 | */ 118 | getChildren = function (e) { 119 | if (e.children.length < 1) { 120 | throw new Error("The Nav container has no containing elements"); 121 | } 122 | // Store all children in array 123 | var children = []; 124 | // Loop through children and store in array if child != TextNode 125 | for (var i = 0; i < e.children.length; i++) { 126 | if (e.children[i].nodeType === 1) { 127 | children.push(e.children[i]); 128 | } 129 | } 130 | return children; 131 | }, 132 | 133 | /** 134 | * Sets multiple attributes at once 135 | * 136 | * @param {element} element 137 | * @param {attrs} attrs 138 | */ 139 | setAttributes = function (el, attrs) { 140 | for (var key in attrs) { 141 | el.setAttribute(key, attrs[key]); 142 | } 143 | }, 144 | 145 | /** 146 | * Adds a class to any element 147 | * 148 | * @param {element} element 149 | * @param {string} class 150 | */ 151 | addClass = function (el, cls) { 152 | if (el.className.indexOf(cls) !== 0) { 153 | el.className += " " + cls; 154 | el.className = el.className.replace(/(^\s*)|(\s*$)/g,""); 155 | } 156 | }, 157 | 158 | /** 159 | * Remove a class from any element 160 | * 161 | * @param {element} element 162 | * @param {string} class 163 | */ 164 | removeClass = function (el, cls) { 165 | var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)"); 166 | el.className = el.className.replace(reg, " ").replace(/(^\s*)|(\s*$)/g,""); 167 | }, 168 | 169 | /** 170 | * forEach method that passes back the stuff we need 171 | * 172 | * @param {array} array 173 | * @param {Function} callback 174 | * @param {scope} scope 175 | */ 176 | forEach = function (array, callback, scope) { 177 | for (var i = 0; i < array.length; i++) { 178 | callback.call(scope, i, array[i]); 179 | } 180 | }; 181 | 182 | var nav, 183 | opts, 184 | navToggle, 185 | styleElement = document.createElement("style"), 186 | htmlEl = document.documentElement, 187 | hasAnimFinished, 188 | isMobile, 189 | navOpen; 190 | 191 | var ResponsiveNav = function (el, options) { 192 | var i; 193 | 194 | /** 195 | * Default options 196 | * @type {Object} 197 | */ 198 | this.options = { 199 | animate: true, // Boolean: Use CSS3 transitions, true or false 200 | transition: 284, // Integer: Speed of the transition, in milliseconds 201 | label: "Menu", // String: Label for the navigation toggle 202 | insert: "before", // String: Insert the toggle before or after the navigation 203 | customToggle: "", // Selector: Specify the ID of a custom toggle 204 | closeOnNavClick: false, // Boolean: Close the navigation when one of the links are clicked 205 | openPos: "relative", // String: Position of the opened nav, relative or static 206 | navClass: "nav-collapse", // String: Default CSS class. If changed, you need to edit the CSS too! 207 | navActiveClass: "js-nav-active", // String: Class that is added to element when nav is active 208 | jsClass: "js", // String: 'JS enabled' class which is added to element 209 | init: function(){}, // Function: Init callback 210 | open: function(){}, // Function: Open callback 211 | close: function(){} // Function: Close callback 212 | }; 213 | 214 | // User defined options 215 | for (i in options) { 216 | this.options[i] = options[i]; 217 | } 218 | 219 | // Adds "js" class for 220 | addClass(htmlEl, this.options.jsClass); 221 | 222 | // Wrapper 223 | this.wrapperEl = el.replace("#", ""); 224 | 225 | // Try selecting ID first 226 | if (document.getElementById(this.wrapperEl)) { 227 | this.wrapper = document.getElementById(this.wrapperEl); 228 | 229 | // If element with an ID doesn't exist, use querySelector 230 | } else if (document.querySelector(this.wrapperEl)) { 231 | this.wrapper = document.querySelector(this.wrapperEl); 232 | 233 | // If element doesn't exists, stop here. 234 | } else { 235 | throw new Error("The nav element you are trying to select doesn't exist"); 236 | } 237 | 238 | // Inner wrapper 239 | this.wrapper.inner = getChildren(this.wrapper); 240 | 241 | // For minification 242 | opts = this.options; 243 | nav = this.wrapper; 244 | 245 | // Init 246 | this._init(this); 247 | }; 248 | 249 | ResponsiveNav.prototype = { 250 | 251 | /** 252 | * Unattaches events and removes any classes that were added 253 | */ 254 | destroy: function () { 255 | this._removeStyles(); 256 | removeClass(nav, "closed"); 257 | removeClass(nav, "opened"); 258 | removeClass(nav, opts.navClass); 259 | removeClass(nav, opts.navClass + "-" + this.index); 260 | removeClass(htmlEl, opts.navActiveClass); 261 | nav.removeAttribute("style"); 262 | nav.removeAttribute("aria-hidden"); 263 | 264 | removeEvent(window, "resize", this, false); 265 | removeEvent(window, "focus", this, false); 266 | removeEvent(document.body, "touchmove", this, false); 267 | removeEvent(navToggle, "touchstart", this, false); 268 | removeEvent(navToggle, "touchend", this, false); 269 | removeEvent(navToggle, "mouseup", this, false); 270 | removeEvent(navToggle, "keyup", this, false); 271 | removeEvent(navToggle, "click", this, false); 272 | 273 | if (!opts.customToggle) { 274 | navToggle.parentNode.removeChild(navToggle); 275 | } else { 276 | navToggle.removeAttribute("aria-hidden"); 277 | } 278 | }, 279 | 280 | /** 281 | * Toggles the navigation open/close 282 | */ 283 | toggle: function () { 284 | if (hasAnimFinished === true) { 285 | if (!navOpen) { 286 | this.open(); 287 | } else { 288 | this.close(); 289 | } 290 | } 291 | }, 292 | 293 | /** 294 | * Opens the navigation 295 | */ 296 | open: function () { 297 | if (!navOpen) { 298 | removeClass(nav, "closed"); 299 | addClass(nav, "opened"); 300 | addClass(htmlEl, opts.navActiveClass); 301 | addClass(navToggle, "active"); 302 | nav.style.position = opts.openPos; 303 | setAttributes(nav, {"aria-hidden": "false"}); 304 | navOpen = true; 305 | opts.open(); 306 | } 307 | }, 308 | 309 | /** 310 | * Closes the navigation 311 | */ 312 | close: function () { 313 | if (navOpen) { 314 | addClass(nav, "closed"); 315 | removeClass(nav, "opened"); 316 | removeClass(htmlEl, opts.navActiveClass); 317 | removeClass(navToggle, "active"); 318 | setAttributes(nav, {"aria-hidden": "true"}); 319 | 320 | // If animations are enabled, wait until they finish 321 | if (opts.animate) { 322 | hasAnimFinished = false; 323 | setTimeout(function () { 324 | nav.style.position = "absolute"; 325 | hasAnimFinished = true; 326 | }, opts.transition + 10); 327 | 328 | // Animations aren't enabled, we can do these immediately 329 | } else { 330 | nav.style.position = "absolute"; 331 | } 332 | 333 | navOpen = false; 334 | opts.close(); 335 | } 336 | }, 337 | 338 | /** 339 | * Resize is called on window resize and orientation change. 340 | * It initializes the CSS styles and height calculations. 341 | */ 342 | resize: function () { 343 | 344 | // Resize watches navigation toggle's display state 345 | if (window.getComputedStyle(navToggle, null).getPropertyValue("display") !== "none") { 346 | 347 | isMobile = true; 348 | setAttributes(navToggle, {"aria-hidden": "false"}); 349 | 350 | // If the navigation is hidden 351 | if (nav.className.match(/(^|\s)closed(\s|$)/)) { 352 | setAttributes(nav, {"aria-hidden": "true"}); 353 | nav.style.position = "absolute"; 354 | } 355 | 356 | this._createStyles(); 357 | this._calcHeight(); 358 | } else { 359 | 360 | isMobile = false; 361 | setAttributes(navToggle, {"aria-hidden": "true"}); 362 | setAttributes(nav, {"aria-hidden": "false"}); 363 | nav.style.position = opts.openPos; 364 | this._removeStyles(); 365 | } 366 | }, 367 | 368 | /** 369 | * Takes care of all even handling 370 | * 371 | * @param {event} event 372 | * @return {type} returns the type of event that should be used 373 | */ 374 | handleEvent: function (e) { 375 | var evt = e || window.event; 376 | 377 | switch (evt.type) { 378 | case "touchstart": 379 | this._onTouchStart(evt); 380 | break; 381 | case "touchmove": 382 | this._onTouchMove(evt); 383 | break; 384 | case "touchend": 385 | case "mouseup": 386 | this._onTouchEnd(evt); 387 | break; 388 | case "click": 389 | this._preventDefault(evt); 390 | break; 391 | case "keyup": 392 | this._onKeyUp(evt); 393 | break; 394 | case "focus": 395 | case "resize": 396 | this.resize(evt); 397 | break; 398 | } 399 | }, 400 | 401 | /** 402 | * Initializes the widget 403 | */ 404 | _init: function () { 405 | this.index = index++; 406 | 407 | addClass(nav, opts.navClass); 408 | addClass(nav, opts.navClass + "-" + this.index); 409 | addClass(nav, "closed"); 410 | hasAnimFinished = true; 411 | navOpen = false; 412 | 413 | this._closeOnNavClick(); 414 | this._createToggle(); 415 | this._transitions(); 416 | this.resize(); 417 | 418 | /** 419 | * On IE8 the resize event triggers too early for some reason 420 | * so it's called here again on init to make sure all the 421 | * calculated styles are correct. 422 | */ 423 | var self = this; 424 | setTimeout(function () { 425 | self.resize(); 426 | }, 20); 427 | 428 | addEvent(window, "resize", this, false); 429 | addEvent(window, "focus", this, false); 430 | addEvent(document.body, "touchmove", this, false); 431 | addEvent(navToggle, "touchstart", this, false); 432 | addEvent(navToggle, "touchend", this, false); 433 | addEvent(navToggle, "mouseup", this, false); 434 | addEvent(navToggle, "keyup", this, false); 435 | addEvent(navToggle, "click", this, false); 436 | 437 | /** 438 | * Init callback here 439 | */ 440 | opts.init(); 441 | }, 442 | 443 | /** 444 | * Creates Styles to the 445 | */ 446 | _createStyles: function () { 447 | if (!styleElement.parentNode) { 448 | styleElement.type = "text/css"; 449 | document.getElementsByTagName("head")[0].appendChild(styleElement); 450 | } 451 | }, 452 | 453 | /** 454 | * Removes styles from the 455 | */ 456 | _removeStyles: function () { 457 | if (styleElement.parentNode) { 458 | styleElement.parentNode.removeChild(styleElement); 459 | } 460 | }, 461 | 462 | /** 463 | * Creates Navigation Toggle 464 | */ 465 | _createToggle: function () { 466 | 467 | // If there's no toggle, let's create one 468 | if (!opts.customToggle) { 469 | var toggle = document.createElement("a"); 470 | toggle.innerHTML = opts.label; 471 | setAttributes(toggle, { 472 | "href": "#", 473 | "class": "nav-toggle" 474 | }); 475 | 476 | // Determine where to insert the toggle 477 | if (opts.insert === "after") { 478 | nav.parentNode.insertBefore(toggle, nav.nextSibling); 479 | } else { 480 | nav.parentNode.insertBefore(toggle, nav); 481 | } 482 | 483 | navToggle = toggle; 484 | 485 | // There is a toggle already, let's use that one 486 | } else { 487 | var toggleEl = opts.customToggle.replace("#", ""); 488 | 489 | if (document.getElementById(toggleEl)) { 490 | navToggle = document.getElementById(toggleEl); 491 | } else if (document.querySelector(toggleEl)) { 492 | navToggle = document.querySelector(toggleEl); 493 | } else { 494 | throw new Error("The custom nav toggle you are trying to select doesn't exist"); 495 | } 496 | } 497 | }, 498 | 499 | /** 500 | * Closes the navigation when a link inside is clicked. 501 | */ 502 | _closeOnNavClick: function () { 503 | if (opts.closeOnNavClick) { 504 | var links = nav.getElementsByTagName("a"), 505 | self = this; 506 | forEach(links, function (i, el) { 507 | addEvent(links[i], "click", function () { 508 | if (isMobile) { 509 | self.toggle(); 510 | } 511 | }, false); 512 | }); 513 | } 514 | }, 515 | 516 | /** 517 | * Prevents the default functionality. 518 | * 519 | * @param {event} event 520 | */ 521 | _preventDefault: function(e) { 522 | if (e.preventDefault) { 523 | if (e.stopImmediatePropagation) { 524 | e.stopImmediatePropagation(); 525 | } 526 | e.preventDefault(); 527 | e.stopPropagation(); 528 | return false; 529 | 530 | // This is strictly for old IE 531 | } else { 532 | e.returnValue = false; 533 | } 534 | }, 535 | 536 | /** 537 | * On touch start we get the location of the touch. 538 | * 539 | * @param {event} event 540 | */ 541 | _onTouchStart: function (e) { 542 | if (!Event.prototype.stopImmediatePropagation) { 543 | this._preventDefault(e); 544 | } 545 | this.startX = e.touches[0].clientX; 546 | this.startY = e.touches[0].clientY; 547 | this.touchHasMoved = false; 548 | 549 | /** 550 | * Remove mouseup event completely here to avoid 551 | * double triggering the event. 552 | */ 553 | removeEvent(navToggle, "mouseup", this, false); 554 | }, 555 | 556 | /** 557 | * Check if the user is scrolling instead of tapping. 558 | * 559 | * @param {event} event 560 | */ 561 | _onTouchMove: function (e) { 562 | if (Math.abs(e.touches[0].clientX - this.startX) > 10 || 563 | Math.abs(e.touches[0].clientY - this.startY) > 10) { 564 | this.touchHasMoved = true; 565 | } 566 | }, 567 | 568 | /** 569 | * On touch end toggle the navigation. 570 | * 571 | * @param {event} event 572 | */ 573 | _onTouchEnd: function (e) { 574 | this._preventDefault(e); 575 | if (!isMobile) { 576 | return; 577 | } 578 | 579 | // If the user isn't scrolling 580 | if (!this.touchHasMoved) { 581 | 582 | // If the event type is touch 583 | if (e.type === "touchend") { 584 | this.toggle(); 585 | return; 586 | 587 | // Event type was click, not touch 588 | } else { 589 | var evt = e || window.event; 590 | 591 | // If it isn't a right click, do toggling 592 | if (!(evt.which === 3 || evt.button === 2)) { 593 | this.toggle(); 594 | } 595 | } 596 | } 597 | }, 598 | 599 | /** 600 | * For keyboard accessibility, toggle the navigation on Enter 601 | * keypress too. 602 | * 603 | * @param {event} event 604 | */ 605 | _onKeyUp: function (e) { 606 | var evt = e || window.event; 607 | if (evt.keyCode === 13) { 608 | this.toggle(); 609 | } 610 | }, 611 | 612 | /** 613 | * Adds the needed CSS transitions if animations are enabled 614 | */ 615 | _transitions: function () { 616 | if (opts.animate) { 617 | var objStyle = nav.style, 618 | transition = "max-height " + opts.transition + "ms"; 619 | 620 | objStyle.WebkitTransition = 621 | objStyle.MozTransition = 622 | objStyle.OTransition = 623 | objStyle.transition = transition; 624 | } 625 | }, 626 | 627 | /** 628 | * Calculates the height of the navigation and then creates 629 | * styles which are later added to the page 630 | */ 631 | _calcHeight: function () { 632 | var savedHeight = 0; 633 | for (var i = 0; i < nav.inner.length; i++) { 634 | savedHeight += nav.inner[i].offsetHeight; 635 | } 636 | 637 | var innerStyles = "." + opts.jsClass + " ." + opts.navClass + "-" + this.index + ".opened{max-height:" + savedHeight + "px !important} ." + opts.jsClass + " ." + opts.navClass + "-" + this.index + ".opened.dropdown-active {max-height:9999px !important}"; 638 | 639 | if (styleElement.styleSheet) { 640 | styleElement.styleSheet.cssText = innerStyles; 641 | } else { 642 | styleElement.innerHTML = innerStyles; 643 | } 644 | 645 | innerStyles = ""; 646 | } 647 | 648 | }; 649 | 650 | /** 651 | * Return new Responsive Nav 652 | */ 653 | return new ResponsiveNav(el, options); 654 | 655 | }; 656 | 657 | if (typeof module !== "undefined" && module.exports) { 658 | module.exports = responsiveNav; 659 | } else { 660 | window.responsiveNav = responsiveNav; 661 | } 662 | 663 | }(document, window, 0)); 664 | -------------------------------------------------------------------------------- /assets/js/responsive-nav.min.js: -------------------------------------------------------------------------------- 1 | /*! responsive-nav.js 1.0.39 2 | * https://github.com/viljamis/responsive-nav.js 3 | * http://responsive-nav.com 4 | * 5 | * Copyright (c) 2015 @viljamis 6 | * Available under the MIT license 7 | */ 8 | !function(e,t,n){"use strict";var i=function(i,s){var o=!!t.getComputedStyle;o||(t.getComputedStyle=function(e){return this.el=e,this.getPropertyValue=function(t){var n=/(\-([a-z]){1})/g;return"float"===t&&(t="styleFloat"),n.test(t)&&(t=t.replace(n,function(){return arguments[2].toUpperCase()})),e.currentStyle[t]?e.currentStyle[t]:null},this});var a,r,c,l,h,u,p=function(e,t,n,i){if("addEventListener"in e)try{e.addEventListener(t,n,i)}catch(s){if("object"!=typeof n||!n.handleEvent)throw s;e.addEventListener(t,function(e){n.handleEvent.call(n,e)},i)}else"attachEvent"in e&&("object"==typeof n&&n.handleEvent?e.attachEvent("on"+t,function(){n.handleEvent.call(n)}):e.attachEvent("on"+t,n))},d=function(e,t,n,i){if("removeEventListener"in e)try{e.removeEventListener(t,n,i)}catch(s){if("object"!=typeof n||!n.handleEvent)throw s;e.removeEventListener(t,function(e){n.handleEvent.call(n,e)},i)}else"detachEvent"in e&&("object"==typeof n&&n.handleEvent?e.detachEvent("on"+t,function(){n.handleEvent.call(n)}):e.detachEvent("on"+t,n))},v=function(e){if(e.children.length<1)throw new Error("The Nav container has no containing elements");// Loop through children and store in array if child != TextNode 9 | for(var t=[],n=0;n10||Math.abs(e.touches[0].clientY-this.startY)>10)&&(this.touchHasMoved=!0)},_onTouchEnd:function(e){if(this._preventDefault(e),h&&!this.touchHasMoved){if("touchend"===e.type)return this.toggle(),void 0;var n=e||t.event;3!==n.which&&2!==n.button&&this.toggle()}},_onKeyUp:function(e){var n=e||t.event;13===n.keyCode&&this.toggle()},_transitions:function(){if(r.animate){var e=a.style,t="max-height "+r.transition+"ms";e.WebkitTransition=e.MozTransition=e.OTransition=e.transition=t}},_calcHeight:function(){for(var e=0,t=0;tmax and max-width are available too. 18 | // Parts based on https://gist.github.com/timknight/03e6335b8816aa534cf7 19 | @mixin breakpoint($break: 0, $max: 0) { 20 | // Type of break variable 21 | $value: type-of($break); 22 | 23 | // If it is a string (i.e. a breakpoint variable). 24 | @if $value == string { 25 | // If using 'break-1', 'break-2' etc output the correct breakpoints from map. 26 | @if map-has-key($breakpoints, $break) { 27 | @media screen and (min-width: #{map-get($breakpoints, $break) / 16 * 1em} ) { @content; } 28 | } @else { 29 | @warn "#{$break} is not a set breakpoint variable"; 30 | } 31 | 32 | // If it is a number, use this for the breakpoint. 33 | } @else if $value == number { 34 | // If using other numbers output value in ems either for min, min & max or max width breakpoints. 35 | $query: "all" !default; 36 | @if $break != 0 and $max != 0 { $query: "(min-width: #{$break / 16 * 1em}) and (max-width: #{$max / 16 * 1em})"; } 37 | @else if $break != 0 and $max == 0 { $query: "(min-width: #{$break / 16 * 1em})"; } 38 | @else if $break == 0 and $max != 0 { $query: "(max-width: #{$max / 16 * 1em})"; } 39 | @media #{$query} { @content; } 40 | 41 | } @else { 42 | @warn "#{$break} is not valid to use as a breakpoint"; 43 | } 44 | } 45 | 46 | // Root font-size in %, outputted in correct breakpoints. 47 | @mixin rootsize { 48 | font-size: nth($sizes, 1) / 16 * 100%; 49 | 50 | // Loop through breakpoints. 51 | @for $i from 2 through $breakpoints-limit { 52 | @media screen and (min-width: nth($points, $i) / 16 * 1em ) { 53 | font-size: nth($sizes, $i) / 16 * 100%; 54 | } 55 | } 56 | } 57 | 58 | // Max-widths for typeset containers, outputted in correct breakpoints. 59 | @mixin maxwidth($breakpoint: 0) { 60 | // Type of chosen variables. 61 | $break-value: type-of($breakpoint); 62 | 63 | // If specifying a breakpoint to use (and breakpoint exists). 64 | @if $break-value == number and $breakpoint <= ($breakpoints-limit - 1) and $breakpoint >= 0 { 65 | 66 | max-width: #{nth($max-widths, ($breakpoint + 1)) / nth($sizes, ($breakpoint + 1))}rem; 67 | 68 | } @else if $breakpoint == all { 69 | max-width: #{nth($max-widths, 1) / nth($sizes, 1)}rem; 70 | 71 | // Loop through breakpoints. 72 | @for $i from 2 through $breakpoints-limit { 73 | @media screen and (min-width: nth($points, $i) / 16 * 1em ) { 74 | max-width: #{nth($max-widths, $i) / nth($sizes, $i)}rem; 75 | } 76 | } 77 | } 78 | } 79 | 80 | // Set the measure for single columns, outputted in correct breakpoints. 81 | @mixin measure($breakpoint: 0) { 82 | // Type of chosen variables. 83 | $break-value: type-of($breakpoint); 84 | 85 | // If specifying a breakpoint to use (and breakpoint exists). 86 | @if $break-value == number and $breakpoint <= ($breakpoints-limit - 1) and $breakpoint >= 0 { 87 | 88 | max-width: #{nth($line-widths, ($breakpoint + 1)) / nth($sizes, ($breakpoint + 1))}rem; 89 | 90 | } @else if $breakpoint == all { 91 | max-width: #{nth($line-widths, 1) / nth($sizes, 1)}rem; 92 | 93 | // Loop through breakpoints. 94 | @for $i from 2 through $breakpoints-limit { 95 | @media screen and (min-width: nth($points, $i) / 16 * 1em ) { 96 | max-width: #{nth($line-widths, $i) / nth($sizes, $i)}rem; 97 | } 98 | } 99 | } 100 | } 101 | 102 | // Calculate percentage width of container to get optimal measure for main text columns. 103 | // Defaults to all breakpoints. 104 | // Note: will not output for base breakpoint as this comes from the 'measure' mixin. 105 | @mixin ideal-measure($breakpoint: 0, $gutter: 0, $main: true, $output: max-width) { 106 | // Type of chosen variables. 107 | $break-value: type-of($breakpoint); 108 | 109 | // If specifying a breakpoint to use (and breakpoint exists and is larger than 0). 110 | @if $break-value == number and $breakpoint <= ($breakpoints-limit - 1) and $breakpoint > 0 { 111 | 112 | @if $gutter == small { 113 | $gutter: map-get($gutterwidths, small) * 2 / 1rem; 114 | } @else if $gutter == medium { 115 | $gutter: map-get($gutterwidths, medium) * 2 / 1rem; 116 | } @else if $gutter == large { 117 | $gutter: map-get($gutterwidths, large) * 2 / 1rem; 118 | } @else { 119 | $gutter: 0; 120 | } 121 | 122 | $rootsize: map-get($rootsizes, rootsize-#{$breakpoint}); 123 | $ideal-measure: map-get($measures, measure-#{$breakpoint}); 124 | $gutter-size: ($gutter * $rootsize); 125 | $container-width: map-get($maxwidths, width-#{$breakpoint}); 126 | 127 | $percentage: percentage(($ideal-measure + $gutter-size) / $container-width); 128 | 129 | @if $percentage < 55 { 130 | $percentage: 55%; 131 | } @else if $percentage > 65 { 132 | $percentage: 65%; 133 | } 134 | 135 | @if $main == false { 136 | $percentage: 100 - $percentage; 137 | } 138 | 139 | #{$output}: $percentage; 140 | } 141 | } 142 | 143 | // Value in scale in $modular-scale? 144 | // Used in following fontsize mixin. 145 | @function in-modular-scale($scale, $key) { 146 | $map: map-get($modular-scale, $scale); 147 | $output: map-has-key($map, $key); 148 | @return $output; 149 | } 150 | 151 | // Font-size in rems. Either set per breakpoint or for all. 152 | // Use values as you would for pixels i.e. 16 or use values from the modular scale. 153 | @mixin fontsize($fontsize, $breakpoint: 0) { 154 | // Type of chosen variables. 155 | $font-value: type-of($fontsize); 156 | $break-value: type-of($breakpoint); 157 | 158 | // Check if value exists in scale. 159 | $in-scale: in-modular-scale(scale-0, $fontsize); 160 | 161 | // If specifying a breakpoint to use (and breakpoint exists). 162 | @if $break-value == number and $breakpoint <= ($breakpoints-limit - 1) and $breakpoint >= 0 { 163 | 164 | // If using a number for fontsize. 165 | @if $font-value == number { 166 | font-size: #{$fontsize / nth($sizes, ($breakpoint + 1))}rem; 167 | 168 | // If using a variable from the scale for fontsize. 169 | } @else if $in-scale == true { 170 | $get-scale: map-get($modular-scale, scale-#{$breakpoint}); 171 | $get-size: map-get($get-scale, $fontsize); 172 | 173 | font-size: #{$get-size / nth($sizes, ($breakpoint + 1))}rem; 174 | 175 | } @else { 176 | @warn "#{$fontsize} is not a valid scale variable"; 177 | } 178 | 179 | // If want to use value for all breakpoints. 180 | } @else if $breakpoint == all { 181 | 182 | // If using a number for fontsize. 183 | @if $font-value == number { 184 | font-size: #{$fontsize / nth($sizes, 1)}rem; 185 | 186 | // Loop through breakpoints. 187 | @for $i from 2 through $breakpoints-limit { 188 | @media screen and (min-width: nth($points, $i) / 16 * 1em ) { 189 | font-size: #{$fontsize / nth($sizes, $i)}rem; 190 | } 191 | } 192 | 193 | // If using a variable from the scale for fontsize. 194 | } @else if $in-scale == true { 195 | $get-scale: map-get($modular-scale, scale-0); 196 | $get-size: map-get($get-scale, $fontsize); 197 | font-size: #{$get-size / nth($sizes, 1)}rem; 198 | 199 | // Loop through breakpoints. 200 | @for $i from 2 through $breakpoints-limit { 201 | $get-scale: map-get($modular-scale, scale-#{$i - 1}); 202 | $get-size: map-get($get-scale, $fontsize); 203 | 204 | @media screen and (min-width: nth($points, $i) / 16 * 1em ) { 205 | font-size: #{$get-size / nth($sizes, $i)}rem; 206 | } 207 | } 208 | 209 | } @else { 210 | @warn "#{$fontsize} is not a valid scale variable"; 211 | } 212 | 213 | } @else { 214 | @warn "#{$breakpoint} is not valid to use as a breakpoint"; 215 | } 216 | } 217 | 218 | // Advanced baseline magic. 219 | // ! Read the README to help understand what is going on here. 220 | // Parts based on https://gist.github.com/razwan/10662500 221 | @mixin baseline($fontsize, $font, $lineheight: 2, $below: 2, $breakpoint: 0) { 222 | // Type of chosen variables. 223 | $font-value: type-of($fontsize); 224 | $break-value: type-of($breakpoint); 225 | 226 | // Cap height 227 | $cap-height: map-get($font, cap-height); 228 | 229 | // Check if value exists in scale. 230 | $in-scale: in-modular-scale(scale-0, $fontsize); 231 | 232 | // Set the line-height (if it isn’t set at 0). 233 | @if $lineheight != 0 { 234 | line-height: #{$lineheight}rem; 235 | } 236 | 237 | // If specifying a breakpoint to use (and breakpoint exists). 238 | @if $break-value == number and $breakpoint <= ($breakpoints-limit - 1) and $breakpoint >= 0 { 239 | 240 | // If using a number for fontsize. 241 | @if $font-value == number { 242 | $rootsize: nth($sizes, ($breakpoint + 1)); 243 | $baseline-shift: #{($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001}; 244 | $baseline-push: #{$below - (($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001)}; 245 | 246 | margin-bottom: #{$baseline-push}rem; 247 | padding-top: #{$baseline-shift}rem; 248 | 249 | // If using a variable from the scale for fontsize. 250 | } @else if $in-scale == true { 251 | $get-scale: map-get($modular-scale, scale-#{$breakpoint}); 252 | $get-size: map-get($get-scale, $fontsize); 253 | $rootsize: nth($sizes, ($breakpoint + 1)); 254 | 255 | $baseline-shift: #{($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001}; 256 | $baseline-push: #{$below - (($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001)}; 257 | 258 | margin-bottom: #{$baseline-push}rem; 259 | padding-top: #{$baseline-shift}rem; 260 | 261 | } @else { 262 | @warn "#{$fontsize} is not a valid scale variable"; 263 | } 264 | 265 | // If want to use value for all breakpoints. 266 | } @else if $breakpoint == all { 267 | 268 | // If using a number for fontsize. 269 | @if $font-value == number { 270 | $rootsize: nth($sizes, 1); 271 | $baseline-shift: #{($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001}; 272 | $baseline-push: #{$below - (($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001)}; 273 | 274 | margin-bottom: #{$baseline-push}rem; 275 | padding-top: #{$baseline-shift}rem; 276 | 277 | // Loop through breakpoints. 278 | @for $i from 2 through $breakpoints-limit { 279 | $rootsize: nth($sizes, $i); 280 | $baseline-shift: #{($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001}; 281 | $baseline-push: #{$below - (($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001)}; 282 | 283 | @media screen and (min-width: nth($points, $i) / 16 * 1em ) { 284 | margin-bottom: #{$baseline-push}rem; 285 | padding-top: #{$baseline-shift}rem; 286 | } 287 | } 288 | 289 | // If using a variable from the scale for fontsize. 290 | } @else if $in-scale == true { 291 | $get-scale: map-get($modular-scale, scale-0); 292 | $get-size: map-get($get-scale, $fontsize); 293 | $rootsize: nth($sizes, 1); 294 | 295 | $baseline-shift: #{($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001}; 296 | $baseline-push: #{$below - (($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001)}; 297 | 298 | margin-bottom: #{$baseline-push}rem; 299 | padding-top: #{$baseline-shift}rem; 300 | 301 | // Loop through breakpoints. 302 | @for $i from 2 through $breakpoints-limit { 303 | $get-scale: map-get($modular-scale, scale-#{$i - 1}); 304 | $get-size: map-get($get-scale, $fontsize); 305 | $rootsize: nth($sizes, $i); 306 | 307 | $baseline-shift: #{($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001}; 308 | $baseline-push: #{$below - (($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001)}; 309 | 310 | @media screen and (min-width: nth($points, $i) / 16 * 1em ) { 311 | margin-bottom: #{$baseline-push}rem; 312 | padding-top: #{$baseline-shift}rem; 313 | } 314 | } 315 | 316 | } @else { 317 | @warn "#{$fontsize} is not a valid scale variable"; 318 | } 319 | 320 | } @else { 321 | @warn "#{$breakpoint} is not valid to use as a breakpoint"; 322 | } 323 | } 324 | 325 | // Set fontsize and baseline at once. Mix of fontsize and baseline mixin. 326 | @mixin sassline($fontsize, $font, $lineheight: 2, $below: 2, $breakpoint: 0) { 327 | $font-value: type-of($fontsize); 328 | $break-value: type-of($breakpoint); 329 | $cap-height: map-get($font, cap-height); 330 | $in-scale: in-modular-scale(scale-0, $fontsize); 331 | 332 | line-height: #{$lineheight}rem; 333 | 334 | @if $break-value == number and $breakpoint <= ($breakpoints-limit - 1) and $breakpoint >= 0 { 335 | 336 | @if $font-value == number { 337 | $rootsize: nth($sizes, ($breakpoint + 1)); 338 | $baseline-shift: #{($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001}; 339 | $baseline-push: #{$below - (($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001)}; 340 | font-size: #{$fontsize / nth($sizes, ($breakpoint + 1))}rem; 341 | margin-bottom: #{$baseline-push}rem; 342 | padding-top: #{$baseline-shift}rem; 343 | 344 | } @else if $in-scale == true { 345 | $get-scale: map-get($modular-scale, scale-#{$breakpoint}); 346 | $get-size: map-get($get-scale, $fontsize); 347 | $rootsize: nth($sizes, ($breakpoint + 1)); 348 | $baseline-shift: #{($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001}; 349 | $baseline-push: #{$below - (($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001)}; 350 | font-size: #{$get-size / nth($sizes, ($breakpoint + 1))}rem; 351 | margin-bottom: #{$baseline-push}rem; 352 | padding-top: #{$baseline-shift}rem; 353 | 354 | } @else { 355 | @warn "#{$fontsize} is not a valid scale variable"; 356 | } 357 | 358 | } @else if $breakpoint == all { 359 | 360 | @if $font-value == number { 361 | $rootsize: nth($sizes, 1); 362 | $baseline-shift: #{($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001}; 363 | $baseline-push: #{$below - (($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001)}; 364 | font-size: #{$fontsize / nth($sizes, 1)}rem; 365 | margin-bottom: #{$baseline-push}rem; 366 | padding-top: #{$baseline-shift}rem; 367 | 368 | @for $i from 2 through $breakpoints-limit { 369 | $rootsize: nth($sizes, $i); 370 | $baseline-shift: #{($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001}; 371 | $baseline-push: #{$below - (($fontsize / 2 * (($lineheight * $rootsize / $fontsize) - $cap-height)) / $rootsize + 0.00001)}; 372 | @media screen and (min-width: nth($points, $i) / 16 * 1em ) { 373 | font-size: #{$fontsize / nth($sizes, $i)}rem; 374 | margin-bottom: #{$baseline-push}rem; 375 | padding-top: #{$baseline-shift}rem; 376 | } 377 | } 378 | 379 | } @else if $in-scale == true { 380 | $get-scale: map-get($modular-scale, scale-0); 381 | $get-size: map-get($get-scale, $fontsize); 382 | $rootsize: nth($sizes, 1); 383 | $baseline-shift: #{($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001}; 384 | $baseline-push: #{$below - (($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001)}; 385 | font-size: #{$get-size / nth($sizes, 1)}rem; 386 | margin-bottom: #{$baseline-push}rem; 387 | padding-top: #{$baseline-shift}rem; 388 | 389 | @for $i from 2 through $breakpoints-limit { 390 | $get-scale: map-get($modular-scale, scale-#{$i - 1}); 391 | $get-size: map-get($get-scale, $fontsize); 392 | $rootsize: nth($sizes, $i); 393 | $baseline-shift: #{($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001}; 394 | $baseline-push: #{$below - (($get-size / 2 * (($lineheight * $rootsize / $get-size) - $cap-height)) / $rootsize + 0.00001)}; 395 | @media screen and (min-width: nth($points, $i) / 16 * 1em ) { 396 | font-size: #{$get-size / nth($sizes, $i)}rem; 397 | margin-bottom: #{$baseline-push}rem; 398 | padding-top: #{$baseline-shift}rem; 399 | } 400 | } 401 | 402 | } @else { 403 | @warn "#{$fontsize} is not a valid scale variable"; 404 | } 405 | 406 | } @else { 407 | @warn "#{$breakpoint} is not valid to use as a breakpoint"; 408 | } 409 | } 410 | 411 | // Clearfix. 412 | @mixin clearfix { 413 | &:before, &:after{ 414 | display: table; 415 | content: ""; 416 | } 417 | &:after{ 418 | clear: both; 419 | } 420 | } 421 | -------------------------------------------------------------------------------- /assets/sass/sassline-base/_modular-scale.scss: -------------------------------------------------------------------------------- 1 | // Modular scale 2 | // --------------------------------------- 3 | 4 | // Setting responsive modular-scales. Use appropriate scales for viewport sizes. 5 | $modular-scale: ( 6 | // Major Third http://www.modularscale.com/?16,28&px&1.25&web&text 7 | scale-0: ( 8 | alpha: 28.0, 9 | beta: 25.0, 10 | gamma: 22.4, 11 | delta: 20.0, 12 | epsilon: 17.9, 13 | zeta: 16.0, 14 | eta: 14.3, 15 | theta: 12.8, 16 | iota: 11.5 17 | ), 18 | // Major Third http://www.modularscale.com/?17,30&px&1.25&web&text 19 | scale-1: ( 20 | alpha: 30.0, 21 | beta: 26.6, 22 | gamma: 24.0, 23 | delta: 21.3, 24 | epsilon: 19.2, 25 | zeta: 17.0, 26 | eta: 15.3, 27 | theta: 13.6, 28 | iota: 12.8 29 | ), 30 | // Major Third http://www.modularscale.com/?18,32&px&1.25&web&text 31 | scale-2: ( 32 | alpha: 32.0, 33 | beta: 28.1, 34 | gamma: 25.6, 35 | delta: 22.5, 36 | epsilon: 20.5, 37 | zeta: 18.0, 38 | eta: 16.3, 39 | theta: 14.4, 40 | iota: 13.1 41 | ), 42 | // Perfect Fourth http://www.modularscale.com/?20,40&px&1.333&web&text 43 | scale-3: ( 44 | alpha: 40.0, 45 | beta: 35.5, 46 | gamma: 30.0, 47 | delta: 26.7, 48 | epsilon: 22.5, 49 | zeta: 20.0, 50 | eta: 16.9, 51 | theta: 15.0, 52 | iota: 12.7 53 | ), 54 | // Aug. Fourth http://www.modularscale.com/?22,50&px&1.414&web&text 55 | scale-4: ( 56 | alpha: 50.0, 57 | beta: 43.9, 58 | gamma: 35.3, 59 | delta: 31.1, 60 | epsilon: 25.0, 61 | zeta: 22.0, 62 | eta: 17.6, 63 | theta: 15.6, 64 | iota: 12.5 65 | ) 66 | ); 67 | -------------------------------------------------------------------------------- /assets/sass/sassline-base/_reset.scss: -------------------------------------------------------------------------------- 1 | // Reset 2 | // --------------------------------------- 3 | 4 | // Reset all the things 5 | * { box-sizing: border-box; } 6 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } 7 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } 8 | html, body { height: 100%; } 9 | a img { border: none; } 10 | blockquote { quotes: none; } 11 | blockquote:before, blockquote:after { content: ''; content: none; } 12 | table { border-collapse: collapse; border-spacing: 0; } 13 | caption, th, td { text-align: left; font-weight: normal; vertical-align: middle; } 14 | -------------------------------------------------------------------------------- /assets/sass/sassline-base/_typography.scss: -------------------------------------------------------------------------------- 1 | // Typography 2 | // --------------------------------------- 3 | 4 | // Setting root sizes and base styles. 5 | html { 6 | @include rootsize; 7 | 8 | -webkit-text-size-adjust: 100%; 9 | -ms-text-size-adjust: 100%; 10 | } 11 | 12 | // Site-wide base styles. 13 | body { 14 | @include fontsize(zeta, all); 15 | 16 | font-family: unquote(map-get($bodytype, font-family)); 17 | font-style: normal; 18 | font-weight: map-get($bodytype, regular); 19 | line-height: 2rem; 20 | } 21 | 22 | // Links. 23 | a { 24 | color: $linkColour; 25 | text-decoration: none; 26 | transition: color .1s, background-color .1s; 27 | 28 | &:hover, &:active, &:focus { 29 | color: $hoverColour; 30 | text-decoration: none; 31 | } 32 | } 33 | 34 | // Styles for typeset text. 35 | .typeset { 36 | 37 | // Nice underlines for text links. 38 | p a, li a { 39 | background-image: linear-gradient(to bottom,rgba(0, 0, 0, 0) 50%,lighten($linkColour,20%) 50%); 40 | background-position: 0 93%; 41 | background-repeat: repeat-x; 42 | background-size: 100% 0.15rem; 43 | text-shadow: 0.1rem 0 $backgroundColour, 44 | 0.15rem 0 $backgroundColour, 45 | -0.1rem 0 $backgroundColour, 46 | -0.15rem 0 $backgroundColour; 47 | 48 | &:hover, &:active, &:focus { 49 | background-image: linear-gradient(to bottom,rgba(0, 0, 0, 0) 50%,lighten($hoverColour,20%) 50%); 50 | } 51 | } 52 | 53 | // Paragraphs. OpenType ligatures and oldstyle figures enabled if available. 54 | p { 55 | @include baseline($fontsize: zeta, $font: $bodytype, $lineheight: 2, $below: 2, $breakpoint: all); 56 | 57 | font-feature-settings: 'kern', 'onum', 'liga'; 58 | } 59 | 60 | // Headings. OpenType ligatures and lining figures enabled if available. 61 | h1, h2, h3, h4, h5, h6 { 62 | color: $headingColour; 63 | font-family: unquote(map-get($headingtype, font-family)); 64 | font-feature-settings: 'liga', 'lnum', 'kern'; 65 | font-style: normal; 66 | font-weight: map-get($headingtype, bold); 67 | } 68 | 69 | // Heading level 1. 70 | h1, .alpha { 71 | @include sassline($fontsize: alpha, $font: $headingtype, $lineheight: 3, $below: 1, $breakpoint: all); 72 | } 73 | 74 | // Heading level 2. 75 | h2, .beta { 76 | @include sassline(beta, $headingtype, 3, 1, all); 77 | } 78 | 79 | // Heading level 3. 80 | h3, .gamma { 81 | @include sassline(gamma, $headingtype, 3, 1, all); 82 | } 83 | 84 | // Heading level 4. 85 | h4, .delta { 86 | @include sassline(delta, $headingtype, 2, 0, all); 87 | } 88 | 89 | // Heading level 5. 90 | h5, .epsilon { 91 | @include sassline(epsilon, $headingtype, 2, 0, all); 92 | } 93 | 94 | // Heading level 6. 95 | h6, .zeta { 96 | @include sassline(zeta, $headingtype, 2, 0, all); 97 | } 98 | 99 | // Lists. 100 | ul, ol { 101 | @include baseline(zeta, $bodytype, 2, 2, all); 102 | 103 | li { 104 | font-feature-settings: 'kern', 'onum', 'liga'; 105 | margin-left: 2rem; 106 | 107 | @include breakpoint(break-1) { 108 | margin-left: 0; 109 | } 110 | 111 | ol, ul { 112 | padding-top: 1rem; 113 | margin-bottom: 1rem; 114 | margin-left: 2rem; 115 | } 116 | } 117 | } 118 | 119 | // Ordered lists. 120 | ol { 121 | list-style-type: none; 122 | 123 | li { 124 | counter-increment: top-level; 125 | 126 | &:before { 127 | content: counter(top-level) '.'; 128 | font-feature-settings: 'lnum', 'tnum'; 129 | margin-left: -3rem; 130 | position: absolute; 131 | text-align: right; 132 | width: 2em; 133 | } 134 | 135 | ul { 136 | 137 | li { 138 | counter-increment: none; 139 | 140 | &:before { 141 | content: ''; 142 | } 143 | 144 | ol { 145 | 146 | li { 147 | counter-increment: alt-level; 148 | 149 | &:before { 150 | content: counter(alt-level) '.'; 151 | } 152 | } 153 | } 154 | } 155 | } 156 | 157 | ol { 158 | 159 | li { 160 | counter-increment: sub-level; 161 | 162 | &:before { 163 | content: counter(top-level) '.' counter(sub-level); 164 | } 165 | 166 | ul { 167 | 168 | li { 169 | counter-increment: none; 170 | 171 | &:before { 172 | content: ''; 173 | } 174 | } 175 | } 176 | 177 | ol { 178 | 179 | li { 180 | counter-increment: sub-sub-level; 181 | 182 | &:before { 183 | content: counter(top-level) '.' counter(sub-level) '.' counter(sub-sub-level); 184 | } 185 | } 186 | } 187 | } 188 | } 189 | } 190 | } 191 | 192 | // Definition lists. 193 | dl { 194 | @include baseline(zeta, $bodytype, 2, 2, all); 195 | 196 | dt, dd { 197 | font-feature-settings: 'kern', 'onum', 'liga'; 198 | margin-left: 2rem; 199 | 200 | @include breakpoint(break-1) { 201 | margin-left: 0; 202 | } 203 | } 204 | 205 | dt { 206 | font-weight: map-get($bodytype, bold); 207 | } 208 | 209 | dd + dt { 210 | padding-top: 1rem; 211 | } 212 | } 213 | 214 | // Tables. 215 | table { 216 | @include sassline(eta, $headingtype, 2, 0, all); 217 | 218 | font-family: unquote(map-get($headingtype, font-family)); 219 | font-feature-settings: 'liga', 'lnum', 'tnum', 'kern'; 220 | font-style: normal; 221 | font-weight: map-get($headingtype, regular); 222 | width: 100%; 223 | 224 | thead { 225 | 226 | th { 227 | @include sassline(zeta, $headingtype, 2, 0, all); 228 | padding-bottom: 1px; 229 | } 230 | } 231 | } 232 | 233 | // Bold. 234 | b, strong, .bold { 235 | font-weight: map-get($bodytype, bold); 236 | } 237 | 238 | // Italic. 239 | em, i, .italic { 240 | font-style: map-get($bodytype, italic); 241 | } 242 | 243 | // Caption and inline small text. 244 | small, .caption { 245 | @include fontsize(theta, all); 246 | 247 | font-family: unquote(map-get($headingtype, font-family)); 248 | font-style: normal; 249 | font-weight: map-get($headingtype, regular); 250 | } 251 | 252 | small { 253 | line-height: 1rem; 254 | } 255 | 256 | .caption { 257 | @include baseline(theta, $headingtype, 2, 2, all); 258 | 259 | color: $captionColour; 260 | } 261 | 262 | // Nice spacing for captions. 263 | h1 + .caption, .alpha + .caption, h2 + .caption, .beta + .caption, h3 + .caption, .gamma + .caption { 264 | margin-top: -1rem; 265 | } 266 | 267 | .delta + .caption, .epsilon + .caption, .zeta + .caption { 268 | margin-top: 0rem; 269 | } 270 | 271 | // Quotes. 272 | blockquote { 273 | 274 | p { 275 | border-left: 0.15rem solid $linkColour; 276 | font-style: map-get($bodytype, italic); 277 | padding-left: 1rem; 278 | 279 | // Add spacing below blockquote paragraphs to align to baseline grid. 280 | $get-scale: map-get($modular-scale, scale-0); 281 | $get-size: map-get($get-scale, zeta); 282 | $rootsize: nth($sizes, 1); 283 | $baseline-shift: #{($get-size / 2 * ((2 * $rootsize / $get-size) - map-get($bodytype, cap-height))) / $rootsize + 0.00001}; 284 | $baseline-push: #{3 - (($get-size * ((2 * $rootsize / $get-size) - map-get($bodytype, cap-height))) / $rootsize + 0.00001)}; 285 | 286 | margin-bottom: #{$baseline-push}rem; 287 | padding-bottom: #{$baseline-shift}rem; 288 | 289 | @for $i from 2 through $breakpoints-limit { 290 | $get-scale: map-get($modular-scale, scale-#{$i - 1}); 291 | $get-size: map-get($get-scale, zeta); 292 | $rootsize: nth($sizes, $i); 293 | $baseline-shift: #{($get-size / 2 * ((2 * $rootsize / $get-size) - map-get($bodytype, cap-height))) / $rootsize + 0.00001}; 294 | $baseline-push: #{3 - (($get-size * ((2 * $rootsize / $get-size) - map-get($bodytype, cap-height))) / $rootsize + 0.00001)}; 295 | 296 | @media screen and (min-width: nth($points, $i) / 16 * 1em ) { 297 | margin-bottom: #{$baseline-push}rem; 298 | padding-bottom: #{$baseline-shift}rem; 299 | } 300 | } 301 | } 302 | 303 | @include breakpoint(break-1) { 304 | margin-left: -1rem; 305 | } 306 | } 307 | 308 | // Horizontal rule. 309 | hr { 310 | background-image: linear-gradient(to bottom,rgba(0, 0, 0, 0) 50%,$captionColour 50%); 311 | background-position: 0 50%; 312 | background-repeat: repeat-x; 313 | background-size: 100% 0.15rem; 314 | border: 0; 315 | margin: 0; 316 | padding-bottom: 3rem; 317 | padding-top: 3rem; 318 | } 319 | 320 | // Code block. 321 | code, pre { 322 | background-color: $codeBackgroundColour; 323 | font-family: unquote(map-get($monospacetype, font-family)); 324 | } 325 | 326 | pre { 327 | display: block; 328 | margin-bottom: 2rem; 329 | padding: 1rem; 330 | white-space: pre; 331 | white-space: pre-wrap; 332 | word-break: break-all; 333 | word-wrap: break-word; 334 | } 335 | 336 | code { 337 | @include fontsize(theta, all); 338 | 339 | line-height: 1rem; 340 | } 341 | 342 | // Letter space those capitals people, Jan Tschichold would be proud. 343 | .upper { 344 | font-kerning: normal; 345 | letter-spacing: 0.1rem; 346 | text-transform: uppercase; 347 | } 348 | 349 | // Real small caps. 350 | .small-caps { 351 | font-feature-settings: 'smcp', 'kern'; 352 | font-kerning: normal; 353 | letter-spacing: 0.1rem; 354 | } 355 | 356 | // Consistent height numbers with OpenType. 357 | .lining-numerals { 358 | font-feature-settings: 'lnum', 'kern'; 359 | } 360 | 361 | // Ascending and descending numbers with OpenType. 362 | .oldstyle-numerals { 363 | font-feature-settings: 'onum', 'kern'; 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /assets/sass/sassline-base/_variables.scss: -------------------------------------------------------------------------------- 1 | // SCSS variables 2 | // --------------------------------------- 3 | 4 | // Note: For the following Sass maps enter values as if they would be px units. 5 | 6 | // Breakpoint sizes from px to ems. Add more values here to add more breakpoints. 7 | // Change names if you prefer, it wont break the mixin as long as they are strings not just numbers. 8 | $breakpoints: ( 9 | break-0: 0, // 0px Mobile first 10 | break-1: 640, // 640px ~ Small tablet up 11 | break-2: 800, // 800px ~ Large tablet up 12 | break-3: 1024, // 1024px ~ Desktop up 13 | break-4: 1600 // 1600px ~ Large desktop up 14 | ) !default; 15 | 16 | // Root font-sizes for each breakpoint. Set to half desired line-height of body text. 17 | // ! Make sure to have as many sizes as breakpoints above. 18 | $rootsizes: ( 19 | rootsize-0: 12, // 24px line-height body text 20 | rootsize-1: 14, // 28px line-height body text 21 | rootsize-2: 15, // 30px line-height body text 22 | rootsize-3: 17, // 34px line-height body text 23 | rootsize-4: 19 // 38px line-height body text 24 | ) !default; 25 | 26 | // Set the optimum line-length for your text (based on typeface). 27 | // Aim for 75–100 characters a line when possible, at smaller sizes type size is more important. 28 | // ! Make sure to have as many widths as breakpoints above. 29 | // Note: this was 'maxwidths' in previous versions. 30 | $measures: ( 31 | measure-0: 500, // 500px wide 32 | measure-1: 550, // 550px wide 33 | measure-2: 600, // 600px wide 34 | measure-3: 680, // 680px wide 35 | measure-4: 750 // 750px wide 36 | ) !default; 37 | 38 | // Set the max-widths for containers (based on design). 39 | // ! Make sure to have as many widths as breakpoints above. 40 | $maxwidths: ( 41 | width-0: 500, // 500px wide 42 | width-1: 600, // 600px wide 43 | width-2: 800, // 800px wide 44 | width-3: 1100, // 110px wide 45 | width-4: 1300 // 1300px wide 46 | ) !default; 47 | 48 | // Gutter widths 49 | $gutterwidths: ( 50 | small: 1rem, 51 | medium: 2rem, 52 | large: 4rem 53 | ) !default; 54 | 55 | // Add typefaces here. 56 | // Add weight and style details too. 57 | // ! Set cap height to set to the baseline. 58 | $bodytype: ( 59 | font-family: 'Georgia, serif', 60 | regular: 400, 61 | bold: 700, 62 | italic: italic, 63 | cap-height: 0.66 64 | ) !default; 65 | 66 | $headingtype: ( 67 | font-family: 'Helvetica, sans-serif', 68 | regular: 400, 69 | bold: 700, 70 | cap-height: 0.66 71 | ) !default; 72 | 73 | $monospacetype: ( 74 | font-family: 'Menlo, monospace', 75 | regular: 400, 76 | cap-height: 0.68 77 | ) !default; 78 | 79 | // Here are some local fonts cap-height sizes to get you started: 80 | // Georgia: 0.66, Times / Times New Roman: 0.65, Palatino: 0.52 81 | // Lucida Grande: 0.72, Helvetica: 0.66, Verdana: 0.76, Tahoma: 0.76 82 | 83 | // Selection of Typekit fonts cap-height sizes: 84 | // Proxima Nova: 0.57, Museo Slab: 0.66, JAF Facit: 0.7, Brandon Grotesque: 0.65, Clavo: 0.7, Adelle: 0.66, FF Tisa Pro: 0.82, Jubilat: 0.66, Futura PT: 0.66, Chaparral Pro: 0.5, Minion Pro: 0.66, Myriad Pro: 0.66, Adobe Caslon Pro: 0.36 85 | 86 | // Text colours. British English. 87 | $headingColour: #2E2E2E !default; 88 | $bodyColour: #494949 !default; 89 | $linkColour: #0E58F5 !default; 90 | $hoverColour: #0B348B !default; 91 | $captionColour: #BDC8CC !default; 92 | $white: #FFFFFF !default; 93 | 94 | // Background colours. 95 | $backgroundColour: #FCFCFC !default; 96 | $codeBackgroundColour: #F5F4F2 !default; 97 | -------------------------------------------------------------------------------- /assets/sass/style.scss: -------------------------------------------------------------------------------- 1 | /* CSS compiled from SCSS. */ 2 | /* --------------------------------------- */ 3 | 4 | // Import Sassline base. 5 | @import "sassline-base"; 6 | 7 | // Import your project SCSS module partials. 8 | @import "modules/globals"; 9 | @import "modules/nav"; 10 | @import "modules/header"; 11 | @import "modules/footer"; 12 | @import "modules/show-grid"; 13 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sassline", 3 | "homepage": "https://github.com/jakegiltsoff/sassline", 4 | "authors": [ 5 | "Jake Giltsoff (http://jke.me)" 6 | ], 7 | "description": "Set text on the web to a baseline grid with Sass & rems using a responsive modular-scale.", 8 | "keywords": [ 9 | "sass", 10 | "baseline", 11 | "boilerplate", 12 | "modular-scale" 13 | ], 14 | "main": "assets/sass/sassline-base/*.scss", 15 | "ignore": [ 16 | "**/.*" 17 | ], 18 | "license": "MIT" 19 | } 20 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var sass = require('gulp-sass'); 3 | var autoprefixer = require('gulp-autoprefixer'); 4 | var cleanCSS = require('gulp-clean-css'); 5 | var rename = require('gulp-rename'); 6 | var webserver = require('gulp-webserver'); 7 | 8 | gulp.task('sass', function() { 9 | gulp.src('./assets/sass/style.scss') 10 | .pipe(sass()) 11 | .pipe(autoprefixer('last 2 versions')) 12 | .pipe(gulp.dest('./assets/css/')); 13 | }); 14 | 15 | gulp.task('css', ['sass'], function() { 16 | gulp.src('./assets/css/style.css') 17 | .pipe(cleanCSS()) 18 | .pipe(rename({ 19 | extname: '.min.css' 20 | })) 21 | .pipe(gulp.dest('./assets/css/')); 22 | }); 23 | 24 | gulp.task('serve', function() { 25 | gulp.src('.') 26 | .pipe(webserver({ 27 | port: 1234, 28 | livereload: true 29 | })); 30 | }); 31 | 32 | gulp.task('default', ['css', 'serve'], function() { 33 | gulp.watch(['./assets/sass/*.scss', './assets/sass/**/*.scss'], ['css']); 34 | }); 35 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sassline 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 25 | 26 |
27 |
28 |
29 |

Lorem ipsum dolor sit amet

30 | 31 |

Labore reprehenderit corporis ullam distinctio ex.

32 | 33 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

34 | 35 |

Quos atque officia quod. Suscipit delectus cupidatat, quia nulla numquam aute cillum proident. Maiores iusto culpa molestias quam id tenetur saepe impedit reiciendis itaque ducimus itaque nostrud. Tempor aliquip, culpa earum itaque sed consequatur minus aliquip reprehenderit nihil veniam tempora do maxime omnis reiciendis elit tempora.

36 | 37 |
    38 |
  1. Perferendis tempor
  2. 39 |
  3. Minim eiusmod
  4. 40 |
  5. Tempor
  6. 41 |
  7. Minus quia sint
  8. 42 |
43 | 44 |

Voluptates mollitia quod tempore laboris commodi

45 | 46 |

Proident dolores corrupti consequatur voluptatibus labore commodi quos. Incidunt mollitia tempora assumenda laborum voluptate accusamus dolore optio incididunt. Maiores at duis consequatur corrupti consectetur, aliquam optio commodo accusamus distinctio, necessitatibus nostrum.

47 | 48 |

Optio, nesciunt, quo, fugiat, blanditiis at quas excepturi quae maiores vel corrupti voluptate cupiditate nemo! In, eius quidem harum quibusdam ratione non. Iste, deleniti, fugit, voluptas aperiam qui adipisci provident ab accusantium possimus eveniet voluptate consectetur!

49 | 50 |

Repellat optio

51 | 52 |

Ad perferendis omnis

53 | 54 |

Pariatur animi quis. Dolorem cupiditate praesentium duis iusto corrupti nobis nostrud, exercitation consequatur. Nulla minim dignissimos reprehenderit voluptatem. Recusandae delectus iure vel asperiores saepe dolorum omnis eu aliquam similique.

55 | 56 |

Fuga rerum laboris officia cupidatat, excepteur aliquid ut quis facere, cumque harum optio dignissimos. Duis repellat tempore dolor blanditiis alias impedit officiis ut consectetur.

57 | 58 |
body {
 59 |     color: blue;
 60 | }
61 | 62 |

Quibusdam illum quo

63 | 64 |

Quos laboris eos, laborum animi. Ea blanditiis ducimus fugiat officia nostrud consectetur recusandae excepteur. Quis qui maiores distinctio facilis saepe eos.

65 | 66 |
Consectetur nobis consequat voluptates eiusmod
67 | 68 |

Iure vel nostrud repellendus. Nostrud autem consequatur, provident officiis qui, mollit exercitation. Veniam minus cillum suscipit aliqua, tenetur. Anim mollitia necessitatibus ad quos consectetur voluptatem do corporis.

69 | 70 |
    71 |
  • Perferendis tempor
  • 72 |
  • Minim eiusmod
  • 73 |
  • Tempor
  • 74 |
  • Minus quia sint
  • 75 |
76 | 77 |

Corporis eligendi minim, enim proident reprehenderit iusto. Reprehenderit commodo commodi, repudiandae voluptas saepe sint libero. Praesentium eius distinctio ullamco vero iusto praesentium eligendi animi. Consectetur dolore vero similique dolore, ut labore omnis.

78 | 79 |
Maxime alias anim similique
80 | 81 |

Omnis corporis assumenda nisi ullam dolores culpa repellat. Molestias praesentium necessitatibus minus, reiciendis officiis commodo incidunt. Consectetur nostrud odio numquam tenetur.

82 | 83 |
84 | 85 |

Heading level 1

86 | 87 |

Heading level 2

88 | 89 |

Heading level 3

90 | 91 |

Heading level 4

92 | 93 |
Heading level 5
94 | 95 |
Heading level 6
96 | 97 |

Paragraph with bold, italic, link and code styles.

98 | 99 |

Blockquote

100 | 101 |

Caption text

102 | 103 |
    104 |
  1. Ordered list element one
  2. 105 |
  3. Ordered list element two
  4. 106 |
  5. Ordered list element three
  6. 107 |
108 | 109 |
    110 |
  • Unordered list element one
  • 111 |
  • Unordered list element two
  • 112 |
  • Unordered list element three
  • 113 |
114 | 115 |
116 | 117 |
118 |
119 |
120 | 121 |
122 |
123 |

Super long title which goes over a couple of lines

124 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

125 |
126 | 127 |
128 |

A second column

129 |

Quos atque officia quod. Suscipit delectus cupidatat, quia nulla numquam aute cillum proident. Maiores iusto culpa molestias quam id tenetur saepe impedit reiciendis itaque ducimus itaque nostrud. Tempor aliquip, culpa earum itaque sed consequatur minus aliquip reprehenderit nihil veniam tempora do maxime omnis reiciendis elit tempora.

130 |
131 |
132 | 133 |
134 |
135 |
Column one
136 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

137 |
138 | 139 |
140 |
Column two
141 |

Quos atque officia quod. Suscipit delectus cupidatat, quia nulla numquam aute cillum proident. Maiores iusto culpa molestias quam id tenetur saepe impedit reiciendis itaque ducimus itaque nostrud. Tempor aliquip, culpa earum itaque sed consequatur minus aliquip reprehenderit nihil veniam tempora do maxime omnis reiciendis elit tempora.

142 |
143 | 144 |
145 |
Column three
146 |

Quos atque officia quod. Suscipit delectus cupidatat, quia nulla numquam aute cillum proident. Maiores iusto culpa molestias quam id tenetur saepe impedit reiciendis itaque ducimus itaque nostrud. Tempor aliquip, culpa earum itaque sed consequatur minus aliquip reprehenderit nihil veniam tempora do maxime omnis reiciendis elit tempora.

147 |
148 |
149 | 150 |
151 |
152 |
Column one
153 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

154 |
155 | 156 |
157 |
Column two
158 |

Quos atque officia quod. Suscipit delectus cupidatat, quia nulla numquam aute cillum proident. Maiores iusto culpa molestias quam id tenetur saepe impedit reiciendis itaque ducimus itaque nostrud. Tempor aliquip, culpa earum itaque sed consequatur minus aliquip reprehenderit nihil veniam tempora do maxime omnis reiciendis elit tempora.

159 |
160 | 161 |
162 |
Column three
163 |

Quos atque officia quod. Suscipit delectus cupidatat, quia nulla numquam aute cillum proident. Maiores iusto culpa molestias quam id tenetur saepe impedit reiciendis itaque ducimus itaque nostrud. Tempor aliquip, culpa earum itaque sed consequatur minus aliquip reprehenderit nihil veniam tempora do maxime omnis reiciendis elit tempora.

164 |
165 | 166 |
167 |
Column four
168 |

Quos atque officia quod. Suscipit delectus cupidatat, quia nulla numquam aute cillum proident. Maiores iusto culpa molestias quam id tenetur saepe impedit reiciendis itaque ducimus itaque nostrud. Tempor aliquip, culpa earum itaque sed consequatur minus aliquip reprehenderit nihil veniam tempora do maxime omnis reiciendis elit tempora.

169 |
170 |
171 | 172 |
173 |
174 |
Main column
175 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

176 | 177 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

178 |
179 | 180 |
181 |
Sidebar
182 |

Quos atque officia quod. Suscipit delectus cupidatat, quia nulla numquam aute cillum proident. Maiores iusto culpa molestias quam id tenetur saepe impedit reiciendis itaque ducimus itaque nostrud. Tempor aliquip, culpa earum itaque sed consequatur minus aliquip.

183 |
184 |
185 | 186 |
187 |
188 |
Sidebar
189 |

Quos atque officia quod. Suscipit delectus cupidatat, quia nulla numquam aute cillum proident. Maiores iusto culpa molestias quam id tenetur saepe impedit reiciendis itaque ducimus itaque nostrud. Tempor aliquip, culpa earum itaque sed consequatur minus aliquip.

190 |
191 | 192 |
193 |
Main column
194 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

195 | 196 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

197 |
198 |
199 | 200 |
201 |
202 |
Main column
203 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

204 | 205 |

This is an inline caption.

206 | 207 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

208 | 209 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

210 |
211 |
212 | 213 |
214 |
215 |
Main column
216 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

217 | 218 |

This is a long inline caption that will probably go across a couple of lines.

219 | 220 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

221 | 222 |

Consectetur adipisicing elit, alias at autem magna aliquid quam proident quis aliquam. temporibus minus eius veniam cupidatat ex, voluptas fuga, quos, mollitia incidunt do officia facilis. molestiae consequat excepturi laborum perferendis tempor minim eiusmod minim minus quia sint.

223 |
224 |
225 |
226 | 227 |
228 |

Hodor

229 |
230 | 231 | 242 | 243 | 244 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sassline", 3 | "version": "2.1.2", 4 | "description": "Set text on the web to a baseline grid with Sass & rems using a responsive modular-scale.", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/designbyjake/sassline.git" 8 | }, 9 | "devDependencies": { 10 | "gulp": "^3.9.0", 11 | "gulp-sass": "^2.1.1", 12 | "gulp-autoprefixer": "^3.1.0", 13 | "gulp-clean-css": "^2.0.2", 14 | "gulp-rename": "^1.2.2", 15 | "gulp-webserver": "^0.9.1" 16 | }, 17 | "scripts": { 18 | "start": "gulp" 19 | }, 20 | "keywords": [ "sass", "baseline", "boilerplate", "modular-scale" ], 21 | "author": "Jake Giltsoff (http://jke.me)", 22 | "license" : "MIT" 23 | } 24 | -------------------------------------------------------------------------------- /sache.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Sassline", 3 | "description": "Set text on the web to a baseline grid with Sass & rems using a responsive modular-scale.", 4 | "tags": ["starting-point", "type", "typography", "vertical-rhythm", "media-queries", "breakpoints", "responsive", "mixins"] 5 | } 6 | --------------------------------------------------------------------------------