├── .gitignore ├── README.md ├── assets └── wizard.png ├── bundle.css ├── bundle.js ├── index.html ├── package.json ├── scripts ├── config.js └── index.js └── styles ├── custom-reset.less ├── fonts.less ├── gh-link.less ├── index.less ├── layout.less ├── libs ├── normalize.css └── skeleton.css ├── utils.less └── variables.less /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | # Node 4 | 5 | *.log 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # Compiled binary addons (http://nodejs.org/api/addons.html) 22 | build/Release 23 | 24 | # Dependency directory 25 | # Commenting this out is preferred by some people, see 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 27 | node_modules 28 | 29 | # Users Environment Variables 30 | .lock-wscript 31 | 32 | # SASS 33 | .sass-cache 34 | *.css.map 35 | 36 | 37 | # OS X 38 | .DS_Store 39 | 40 | # IDEA editor 41 | .idea 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Don't Copy Paste This Frontend Template 2 | 3 | I use this project template in almost all of my static site projects, which 4 | need the basic set of frontend tools. 5 | 6 | Project documentation here: 7 | https://kimmobrunfeldt.github.io/dont-copy-paste-this-frontend-template/ 8 | -------------------------------------------------------------------------------- /assets/wizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimmobrunfeldt/dont-copy-paste-this-frontend-template/5cd2bde719654941bdfc0a42c6f1b8e69ae79980/assets/wizard.png -------------------------------------------------------------------------------- /bundle.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | font-size: 2em; 137 | margin: 0.67em 0; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | background: #ff0; 146 | color: #000; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | font-size: 75%; 164 | line-height: 0; 165 | position: relative; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | box-sizing: content-box; 213 | height: 0; 214 | } 215 | 216 | /** 217 | * Contain overflow in all browsers. 218 | */ 219 | 220 | pre { 221 | overflow: auto; 222 | } 223 | 224 | /** 225 | * Address odd `em`-unit font size rendering in all browsers. 226 | */ 227 | 228 | code, 229 | kbd, 230 | pre, 231 | samp { 232 | font-family: monospace, monospace; 233 | font-size: 1em; 234 | } 235 | 236 | /* Forms 237 | ========================================================================== */ 238 | 239 | /** 240 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 241 | * styling of `select`, unless a `border` property is set. 242 | */ 243 | 244 | /** 245 | * 1. Correct color not being inherited. 246 | * Known issue: affects color of disabled elements. 247 | * 2. Correct font properties not being inherited. 248 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 249 | */ 250 | 251 | button, 252 | input, 253 | optgroup, 254 | select, 255 | textarea { 256 | color: inherit; /* 1 */ 257 | font: inherit; /* 2 */ 258 | margin: 0; /* 3 */ 259 | } 260 | 261 | /** 262 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 263 | */ 264 | 265 | button { 266 | overflow: visible; 267 | } 268 | 269 | /** 270 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 271 | * All other form control elements do not inherit `text-transform` values. 272 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 273 | * Correct `select` style inheritance in Firefox. 274 | */ 275 | 276 | button, 277 | select { 278 | text-transform: none; 279 | } 280 | 281 | /** 282 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 283 | * and `video` controls. 284 | * 2. Correct inability to style clickable `input` types in iOS. 285 | * 3. Improve usability and consistency of cursor style between image-type 286 | * `input` and others. 287 | */ 288 | 289 | button, 290 | html input[type="button"], /* 1 */ 291 | input[type="reset"], 292 | input[type="submit"] { 293 | -webkit-appearance: button; /* 2 */ 294 | cursor: pointer; /* 3 */ 295 | } 296 | 297 | /** 298 | * Re-set default cursor for disabled elements. 299 | */ 300 | 301 | button[disabled], 302 | html input[disabled] { 303 | cursor: default; 304 | } 305 | 306 | /** 307 | * Remove inner padding and border in Firefox 4+. 308 | */ 309 | 310 | button::-moz-focus-inner, 311 | input::-moz-focus-inner { 312 | border: 0; 313 | padding: 0; 314 | } 315 | 316 | /** 317 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 318 | * the UA stylesheet. 319 | */ 320 | 321 | input { 322 | line-height: normal; 323 | } 324 | 325 | /** 326 | * It's recommended that you don't attempt to style these elements. 327 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 328 | * 329 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 330 | * 2. Remove excess padding in IE 8/9/10. 331 | */ 332 | 333 | input[type="checkbox"], 334 | input[type="radio"] { 335 | box-sizing: border-box; /* 1 */ 336 | padding: 0; /* 2 */ 337 | } 338 | 339 | /** 340 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 341 | * `font-size` values of the `input`, it causes the cursor style of the 342 | * decrement button to change from `default` to `text`. 343 | */ 344 | 345 | input[type="number"]::-webkit-inner-spin-button, 346 | input[type="number"]::-webkit-outer-spin-button { 347 | height: auto; 348 | } 349 | 350 | /** 351 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 352 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 353 | * (include `-moz` to future-proof). 354 | */ 355 | 356 | input[type="search"] { 357 | -webkit-appearance: textfield; /* 1 */ /* 2 */ 358 | box-sizing: content-box; 359 | } 360 | 361 | /** 362 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 363 | * Safari (but not Chrome) clips the cancel button when the search input has 364 | * padding (and `textfield` appearance). 365 | */ 366 | 367 | input[type="search"]::-webkit-search-cancel-button, 368 | input[type="search"]::-webkit-search-decoration { 369 | -webkit-appearance: none; 370 | } 371 | 372 | /** 373 | * Define consistent border, margin, and padding. 374 | */ 375 | 376 | fieldset { 377 | border: 1px solid #c0c0c0; 378 | margin: 0 2px; 379 | padding: 0.35em 0.625em 0.75em; 380 | } 381 | 382 | /** 383 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 384 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 385 | */ 386 | 387 | legend { 388 | border: 0; /* 1 */ 389 | padding: 0; /* 2 */ 390 | } 391 | 392 | /** 393 | * Remove default vertical scrollbar in IE 8/9/10/11. 394 | */ 395 | 396 | textarea { 397 | overflow: auto; 398 | } 399 | 400 | /** 401 | * Don't inherit the `font-weight` (applied by a rule above). 402 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 403 | */ 404 | 405 | optgroup { 406 | font-weight: bold; 407 | } 408 | 409 | /* Tables 410 | ========================================================================== */ 411 | 412 | /** 413 | * Remove most spacing between table cells. 414 | */ 415 | 416 | table { 417 | border-collapse: collapse; 418 | border-spacing: 0; 419 | } 420 | 421 | td, 422 | th { 423 | padding: 0; 424 | } 425 | /* 426 | * Skeleton V2.0.4 427 | * Copyright 2014, Dave Gamache 428 | * www.getskeleton.com 429 | * Free to use under the MIT license. 430 | * http://www.opensource.org/licenses/mit-license.php 431 | * 12/29/2014 432 | */ 433 | 434 | 435 | /* Table of contents 436 | –––––––––––––––––––––––––––––––––––––––––––––––––– 437 | - Grid 438 | - Base Styles 439 | - Typography 440 | - Links 441 | - Buttons 442 | - Forms 443 | - Lists 444 | - Code 445 | - Tables 446 | - Spacing 447 | - Utilities 448 | - Clearing 449 | - Media Queries 450 | */ 451 | 452 | 453 | /* Grid 454 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 455 | .container { 456 | position: relative; 457 | width: 100%; 458 | max-width: 960px; 459 | margin: 0 auto; 460 | padding: 0 20px; 461 | box-sizing: border-box; } 462 | .column, 463 | .columns { 464 | width: 100%; 465 | float: left; 466 | box-sizing: border-box; } 467 | 468 | /* For devices larger than 400px */ 469 | @media (min-width: 400px) { 470 | .container { 471 | width: 85%; 472 | padding: 0; } 473 | } 474 | 475 | /* For devices larger than 550px */ 476 | @media (min-width: 550px) { 477 | .container { 478 | width: 80%; } 479 | .column, 480 | .columns { 481 | margin-left: 4%; } 482 | .column:first-child, 483 | .columns:first-child { 484 | margin-left: 0; } 485 | 486 | .one.column, 487 | .one.columns { width: 4.66666666667%; } 488 | .two.columns { width: 13.3333333333%; } 489 | .three.columns { width: 22%; } 490 | .four.columns { width: 30.6666666667%; } 491 | .five.columns { width: 39.3333333333%; } 492 | .six.columns { width: 48%; } 493 | .seven.columns { width: 56.6666666667%; } 494 | .eight.columns { width: 65.3333333333%; } 495 | .nine.columns { width: 74.0%; } 496 | .ten.columns { width: 82.6666666667%; } 497 | .eleven.columns { width: 91.3333333333%; } 498 | .twelve.columns { width: 100%; margin-left: 0; } 499 | 500 | .one-third.column { width: 30.6666666667%; } 501 | .two-thirds.column { width: 65.3333333333%; } 502 | 503 | .one-half.column { width: 48%; } 504 | 505 | /* Offsets */ 506 | .offset-by-one.column, 507 | .offset-by-one.columns { margin-left: 8.66666666667%; } 508 | .offset-by-two.column, 509 | .offset-by-two.columns { margin-left: 17.3333333333%; } 510 | .offset-by-three.column, 511 | .offset-by-three.columns { margin-left: 26%; } 512 | .offset-by-four.column, 513 | .offset-by-four.columns { margin-left: 34.6666666667%; } 514 | .offset-by-five.column, 515 | .offset-by-five.columns { margin-left: 43.3333333333%; } 516 | .offset-by-six.column, 517 | .offset-by-six.columns { margin-left: 52%; } 518 | .offset-by-seven.column, 519 | .offset-by-seven.columns { margin-left: 60.6666666667%; } 520 | .offset-by-eight.column, 521 | .offset-by-eight.columns { margin-left: 69.3333333333%; } 522 | .offset-by-nine.column, 523 | .offset-by-nine.columns { margin-left: 78.0%; } 524 | .offset-by-ten.column, 525 | .offset-by-ten.columns { margin-left: 86.6666666667%; } 526 | .offset-by-eleven.column, 527 | .offset-by-eleven.columns { margin-left: 95.3333333333%; } 528 | 529 | .offset-by-one-third.column, 530 | .offset-by-one-third.columns { margin-left: 34.6666666667%; } 531 | .offset-by-two-thirds.column, 532 | .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } 533 | 534 | .offset-by-one-half.column, 535 | .offset-by-one-half.columns { margin-left: 52%; } 536 | 537 | } 538 | 539 | 540 | /* Base Styles 541 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 542 | /* NOTE 543 | html is set to 62.5% so that all the REM measurements throughout Skeleton 544 | are based on 10px sizing. So basically 1.5rem = 15px :) */ 545 | html { 546 | font-size: 62.5%; } 547 | body { 548 | font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */ 549 | line-height: 1.6; 550 | font-weight: 400; 551 | font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; 552 | color: #222; } 553 | 554 | 555 | /* Typography 556 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 557 | h1, h2, h3, h4, h5, h6 { 558 | margin-top: 0; 559 | margin-bottom: 2rem; 560 | font-weight: 300; } 561 | h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} 562 | h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } 563 | h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } 564 | h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } 565 | h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; } 566 | h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } 567 | 568 | /* Larger than phablet */ 569 | @media (min-width: 550px) { 570 | h1 { font-size: 5.0rem; } 571 | h2 { font-size: 4.2rem; } 572 | h3 { font-size: 3.6rem; } 573 | h4 { font-size: 3.0rem; } 574 | h5 { font-size: 2.4rem; } 575 | h6 { font-size: 1.5rem; } 576 | } 577 | 578 | p { 579 | margin-top: 0; } 580 | 581 | 582 | /* Links 583 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 584 | a { 585 | color: #1EAEDB; } 586 | a:hover { 587 | color: #0FA0CE; } 588 | 589 | 590 | /* Buttons 591 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 592 | .button, 593 | button, 594 | input[type="submit"], 595 | input[type="reset"], 596 | input[type="button"] { 597 | display: inline-block; 598 | height: 38px; 599 | padding: 0 30px; 600 | color: #555; 601 | text-align: center; 602 | font-size: 11px; 603 | font-weight: 600; 604 | line-height: 38px; 605 | letter-spacing: .1rem; 606 | text-transform: uppercase; 607 | text-decoration: none; 608 | white-space: nowrap; 609 | background-color: transparent; 610 | border-radius: 4px; 611 | border: 1px solid #bbb; 612 | cursor: pointer; 613 | box-sizing: border-box; } 614 | .button:hover, 615 | button:hover, 616 | input[type="submit"]:hover, 617 | input[type="reset"]:hover, 618 | input[type="button"]:hover, 619 | .button:focus, 620 | button:focus, 621 | input[type="submit"]:focus, 622 | input[type="reset"]:focus, 623 | input[type="button"]:focus { 624 | color: #333; 625 | border-color: #888; 626 | outline: 0; } 627 | .button.button-primary, 628 | button.button-primary, 629 | input[type="submit"].button-primary, 630 | input[type="reset"].button-primary, 631 | input[type="button"].button-primary { 632 | color: #FFF; 633 | background-color: #33C3F0; 634 | border-color: #33C3F0; } 635 | .button.button-primary:hover, 636 | button.button-primary:hover, 637 | input[type="submit"].button-primary:hover, 638 | input[type="reset"].button-primary:hover, 639 | input[type="button"].button-primary:hover, 640 | .button.button-primary:focus, 641 | button.button-primary:focus, 642 | input[type="submit"].button-primary:focus, 643 | input[type="reset"].button-primary:focus, 644 | input[type="button"].button-primary:focus { 645 | color: #FFF; 646 | background-color: #1EAEDB; 647 | border-color: #1EAEDB; } 648 | 649 | 650 | /* Forms 651 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 652 | input[type="email"], 653 | input[type="number"], 654 | input[type="search"], 655 | input[type="text"], 656 | input[type="tel"], 657 | input[type="url"], 658 | input[type="password"], 659 | textarea, 660 | select { 661 | height: 38px; 662 | padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ 663 | background-color: #fff; 664 | border: 1px solid #D1D1D1; 665 | border-radius: 4px; 666 | box-shadow: none; 667 | box-sizing: border-box; } 668 | /* Removes awkward default styles on some inputs for iOS */ 669 | input[type="email"], 670 | input[type="number"], 671 | input[type="search"], 672 | input[type="text"], 673 | input[type="tel"], 674 | input[type="url"], 675 | input[type="password"], 676 | textarea { 677 | -webkit-appearance: none; 678 | -moz-appearance: none; 679 | appearance: none; } 680 | textarea { 681 | min-height: 65px; 682 | padding-top: 6px; 683 | padding-bottom: 6px; } 684 | input[type="email"]:focus, 685 | input[type="number"]:focus, 686 | input[type="search"]:focus, 687 | input[type="text"]:focus, 688 | input[type="tel"]:focus, 689 | input[type="url"]:focus, 690 | input[type="password"]:focus, 691 | textarea:focus, 692 | select:focus { 693 | border: 1px solid #33C3F0; 694 | outline: 0; } 695 | label, 696 | legend { 697 | display: block; 698 | margin-bottom: .5rem; 699 | font-weight: 600; } 700 | fieldset { 701 | padding: 0; 702 | border-width: 0; } 703 | input[type="checkbox"], 704 | input[type="radio"] { 705 | display: inline; } 706 | label > .label-body { 707 | display: inline-block; 708 | margin-left: .5rem; 709 | font-weight: normal; } 710 | 711 | 712 | /* Lists 713 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 714 | ul { 715 | list-style: circle inside; } 716 | ol { 717 | list-style: decimal inside; } 718 | ol, ul { 719 | padding-left: 0; 720 | margin-top: 0; } 721 | ul ul, 722 | ul ol, 723 | ol ol, 724 | ol ul { 725 | margin: 1.5rem 0 1.5rem 3rem; 726 | font-size: 90%; } 727 | li { 728 | margin-bottom: 0.7rem; } 729 | 730 | 731 | /* Code 732 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 733 | code { 734 | padding: .2rem .5rem; 735 | margin: 0 .2rem; 736 | font-size: 90%; 737 | white-space: nowrap; 738 | background: #F1F1F1; 739 | border: 1px solid #E1E1E1; 740 | border-radius: 4px; } 741 | pre > code { 742 | display: block; 743 | padding: 1rem 1.5rem; 744 | white-space: pre; } 745 | 746 | 747 | /* Tables 748 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 749 | th, 750 | td { 751 | padding: 12px 15px; 752 | text-align: left; 753 | border-bottom: 1px solid #E1E1E1; } 754 | th:first-child, 755 | td:first-child { 756 | padding-left: 0; } 757 | th:last-child, 758 | td:last-child { 759 | padding-right: 0; } 760 | 761 | 762 | /* Spacing 763 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 764 | button, 765 | .button { 766 | margin-bottom: 1rem; } 767 | input, 768 | textarea, 769 | select, 770 | fieldset { 771 | margin-bottom: 1.5rem; } 772 | pre, 773 | blockquote, 774 | dl, 775 | figure, 776 | table, 777 | p, 778 | ul, 779 | ol, 780 | form { 781 | margin-bottom: 2.5rem; } 782 | 783 | 784 | /* Utilities 785 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 786 | .u-full-width { 787 | width: 100%; 788 | box-sizing: border-box; } 789 | .u-max-full-width { 790 | max-width: 100%; 791 | box-sizing: border-box; } 792 | .u-pull-right { 793 | float: right; } 794 | .u-pull-left { 795 | float: left; } 796 | 797 | 798 | /* Misc 799 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 800 | hr { 801 | margin-top: 3rem; 802 | margin-bottom: 3.5rem; 803 | border-width: 0; 804 | border-top: 1px solid #E1E1E1; } 805 | 806 | 807 | /* Clearing 808 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 809 | 810 | /* Self Clearing Goodness */ 811 | .container:after, 812 | .row:after, 813 | .u-cf { 814 | content: ""; 815 | display: table; 816 | clear: both; } 817 | 818 | 819 | /* Media Queries 820 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 821 | /* 822 | Note: The best way to structure the use of media queries is to create the queries 823 | near the relevant code. For example, if you wanted to change the styles for buttons 824 | on small devices, paste the mobile query code up in the buttons section and style it 825 | there. 826 | */ 827 | 828 | 829 | /* Larger than mobile */ 830 | @media (min-width: 400px) {} 831 | 832 | /* Larger than phablet (also point when grid becomes active) */ 833 | @media (min-width: 550px) {} 834 | 835 | /* Larger than tablet */ 836 | @media (min-width: 750px) {} 837 | 838 | /* Larger than desktop */ 839 | @media (min-width: 1000px) {} 840 | 841 | /* Larger than Desktop HD */ 842 | @media (min-width: 1200px) {} 843 | 844 | ul, 845 | ol { 846 | list-style-position: outside; 847 | margin-left: 1.9rem; 848 | } 849 | li > p { 850 | margin-top: 1rem; 851 | } 852 | h4 { 853 | font-size: 2.4rem; 854 | } 855 | h5 { 856 | font-size: 1.5rem; 857 | } 858 | h6 { 859 | font-size: 1.3rem; 860 | } 861 | body { 862 | font-size: 16px; 863 | font-family: "Source Sans Pro", Helvetica, sans-serif; 864 | color: #555; 865 | } 866 | header, 867 | h1, 868 | h2, 869 | h3, 870 | h4, 871 | h5, 872 | h6 { 873 | font-family: "Raleway", Helvetica, sans-serif; 874 | font-weight: bold; 875 | color: #4A4949; 876 | } 877 | header, 878 | h1, 879 | h2, 880 | .uppercase { 881 | letter-spacing: 0.25em; 882 | text-transform: uppercase; 883 | font-weight: 900; 884 | } 885 | .raleway { 886 | font-family: "Raleway", Helvetica, sans-serif; 887 | } 888 | .sub-header { 889 | font-size: 1.3rem; 890 | } 891 | p { 892 | max-width: 600px; 893 | } 894 | b { 895 | font-weight: 600; 896 | } 897 | .no-list-styling { 898 | list-style-type: none; 899 | margin-left: 0; 900 | } 901 | html, 902 | body { 903 | width: 100%; 904 | height: 100%; 905 | background: #eee; 906 | } 907 | .container { 908 | max-width: 700px; 909 | padding-top: 60px; 910 | padding-bottom: 40px; 911 | } 912 | .intro { 913 | padding-top: 30px; 914 | } 915 | h4 { 916 | padding-top: 20px; 917 | } 918 | h5 { 919 | padding-top: 15px; 920 | } 921 | .github-link { 922 | display: block; 923 | visibility: visible; 924 | position: absolute; 925 | z-index: 999999; 926 | top: 20px; 927 | right: 20px; 928 | } 929 | .github-link > a { 930 | color: #505d6b; 931 | } 932 | .github-link > a:hover { 933 | color: #1EAEDB; 934 | } 935 | .iconlink { 936 | border-bottom: none; 937 | position: relative; 938 | display: inline-block; 939 | vertical-align: middle; 940 | line-height: 1em; 941 | color: #505d6b; 942 | -webkit-transition: all 150ms linear; 943 | transition: all 150ms linear; 944 | padding: 10px; 945 | } 946 | .iconlink:hover { 947 | color: #505d6b; 948 | } 949 | .iconlink { 950 | white-space: nowrap; 951 | text-decoration: none; 952 | } 953 | .iconlink[data-title]:before { 954 | font-weight: 300; 955 | content: attr(data-title); 956 | display: inline-block; 957 | position: absolute; 958 | bottom: -34px; 959 | right: 10px; 960 | font-size: 13px; 961 | padding: 5px 10px; 962 | background: #404040; 963 | color: white; 964 | border: solid 1px #555; 965 | border-radius: 2px; 966 | text-decoration: none; 967 | width: auto; 968 | white-space: nowrap; 969 | pointer-events: none; 970 | opacity: 0; 971 | -webkit-transition: opacity 150ms linear, -webkit-transform 150ms linear; 972 | transition: opacity 150ms linear, -webkit-transform 150ms linear; 973 | transition: opacity 150ms linear, transform 150ms linear; 974 | transition: opacity 150ms linear, transform 150ms linear, -webkit-transform 150ms linear; 975 | -webkit-transform: translate3d(0, -8px, 0); 976 | transform: translate3d(0, -8px, 0); 977 | } 978 | .iconlink.iconlink-right[data-title]:before { 979 | left: 10px; 980 | right: auto; 981 | } 982 | .iconlink.iconlink-light[data-title]:before { 983 | background: #f4f4f4; 984 | color: #4A4949; 985 | } 986 | .iconlink[data-title]:hover:before { 987 | opacity: 1; 988 | -webkit-transform: translate3d(0, 0, 0); 989 | transform: translate3d(0, 0, 0); 990 | pointer-events: auto; 991 | } 992 | .iconlink i.fa { 993 | font-size: 2.827rem; 994 | } 995 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Don't Copy Paste This Frontend Template 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |

Don't Copy Paste This Frontend Template

21 | 22 |

23 | By git cloning this project template, you get quickly started in frontend development. 24 | I use this project template in almost all of my static site projects, which 25 | need the basic set of frontend tools. 26 |

27 | 28 |

29 | Before git clone, please go through 30 | the short explanation of how and why it works and see 31 | package.json devDependencies explained to get 32 | a quick introduction to all tools. See also 33 | frequently asked questions. 34 | 35 | After you understand the whole stack and tools, go ahead and just copy 36 | paste this setup. 37 |

38 | 39 |

Features

40 | 59 | 60 |

Get started

61 | 62 |

63 | You need to have Node.js environment installed before anything. 64 | Clone this repository, run npm install and you're ready to 65 | run the following commands. 66 |

67 | 68 | 77 | 78 |

79 | There are other commands too, but they are only used internally by these 80 | two main commands. These other commands are explained in 81 | package.json scripts reference. 82 | 83 |

84 | 85 |

How and why it works

86 | 87 |

88 | Everything happens via npm scripts. 89 | The project "configuration" is in package.json, which in practice means 90 | command line tools and their options. These tools all solve a specific problem, and 91 | they do it well. 92 | You can find all exact shell commands from 93 | package.json "scripts" 94 | section. 95 |

96 | 97 |

98 | If you spot a new tool, check what it is and 99 | why it is used from package.json devDependencies explained 100 | section. 101 |

102 | 103 |
Project structure
104 | 105 | 130 | 131 |

All your frontend code will be in three files: 132 | index.html, 133 | bundle.js, and 134 | bundle.css 135 | – simple. 136 |

137 | 138 |

package.json devDependencies explained

139 | 140 | 240 | 241 |

package.json scripts reference

242 | 243 |

244 | Each npm script is a fairly simple one-line command. This chapter contains 245 | very detailed explanation of these commands and written with beginners 246 | in mind. It is much more important 247 | to know and understand the tools 248 | instead of memorizing what each of these commands do. 249 |

250 | 251 |
JavaScript local development watch (npm run watch-js)
252 | 253 |

254 | Full command: 255 | 256 |

API_URL=http://localhost:9001 watchify ./scripts/index.js -t [ babelify --presets [ es2015 ] ] -t envify --debug --verbose -o ./bundle.js
257 |

258 | 259 | 287 | 288 |
JavaScript production build (npm run build-js)
289 | 290 |

291 | Full command: 292 | 293 |

NODE_ENV=production browserify ./scripts/index.js -t [ babelify --presets [ es2015 ] ] -t envify -o ./bundle.js && npm run minify-js
294 |

295 | 296 |

Note: you need to define API_URL environment variable 297 | before running this command. You can set it in e.g. in your deployment script. 298 |

299 | 300 | 316 | 317 |
CSS local development watch (npm run watch-styles)
318 | 319 |

320 | Full command: 321 | 322 |

npm run build-styles-dev && chokidar '**/*.less' './styles/**/*.css' -c 'npm run build-styles-dev'
323 |

324 | 325 | 338 | 339 |
CSS local development build (npm run build-styles-dev)
340 | 341 |

342 | Full command: 343 | 344 |

npm run build-less && npm run postcss && echo 'Styles built!'
345 |

346 | 347 | 355 | 356 |
CSS production build (npm run build-styles)
357 | 358 |

359 | Full command: 360 | 361 |

npm run build-less && npm run postcss && npm run minify-css
362 |

363 | 364 | 374 | 375 |

Downsides

376 | 377 |

378 | As much as I like npm scripts and browserify, here are some downsides in the 379 | setup. 380 |

381 | 382 | 429 |
430 | 431 | 436 | 437 | 438 | 439 | 440 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend-template", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "Example of Browserify and other frontend tools", 6 | "author": "Kimmo Brunfeldt", 7 | "license": "MIT", 8 | "scripts": { 9 | "start": "concurrently -p \"[{name}]\" -n \"HTTP,JS,LESS\" -c \"bgBlue.bold,bgMagenta.bold,bgGreen.bold\" \"npm run http-server\" \"npm run watch-js\" \"npm run watch-styles\"", 10 | "http-server": "http-server -c0 .", 11 | "watch-js": "API_URL=http://localhost:9001 watchify ./scripts/index.js -t [ babelify --presets [ es2015 ] ] -t envify --debug --verbose -o ./bundle.js", 12 | "watch-styles": "npm run build-styles-dev && chokidar \"**/*.less\" \"./styles/**/*.css\" -c \"npm run build-styles-dev\"", 13 | "build": "npm run build-js && npm run build-styles", 14 | "build-js": "NODE_ENV=production browserify ./scripts/index.js -t [ babelify --presets [ es2015 ] ] -t envify -o ./bundle.js && npm run minify-js", 15 | "build-styles": "npm run build-less && npm run postcss && npm run minify-css", 16 | "build-styles-dev": "npm run build-less && npm run postcss && echo \"Styles built!\"", 17 | "build-less": "lessc ./styles/index.less ./bundle.css", 18 | "postcss": "postcss --use autoprefixer ./bundle.css -o ./bundle.css", 19 | "minify-js": "uglifyjs ./bundle.js -o ./bundle.js", 20 | "minify-css": "cleancss --skip-aggressive-merging --skip-restructuring ./bundle.css -o ./bundle.css" 21 | }, 22 | "dependencies": { 23 | "bluebird": "^3.4.6", 24 | "fastclick": "^1.0.6", 25 | "lodash": "^4.15.0", 26 | "progressbar.js": "^1.0.1" 27 | }, 28 | "devDependencies": { 29 | "autoprefixer": "^6.4.1", 30 | "babel-preset-es2015": "^6.14.0", 31 | "babelify": "^7.3.0", 32 | "browserify": "^13.1.0", 33 | "chokidar-cli": "^1.2.0", 34 | "clean-css": "^3.4.19", 35 | "concurrently": "^2.2.0", 36 | "envify": "^3.4.1", 37 | "http-server": "^0.9.0", 38 | "less": "^2.7.1", 39 | "postcss-cli": "^2.6.0", 40 | "uglifyjs": "^2.4.10", 41 | "watchify": "^3.7.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /scripts/config.js: -------------------------------------------------------------------------------- 1 | const _ = require('lodash'); 2 | 3 | // Example of build time configuration 4 | // envify is a Browserify transform which replaces all process.env.X references 5 | // with build time environment variables. 6 | // You must e.g. do 7 | // API_URL=x npm run build 8 | // 9 | // to change this variable. 10 | if (_.isEmpty(process.env.API_URL)) { 11 | let message = 'API_URL is not defined. You must define API_URL environment' 12 | message += ' variable when building the frontend.' 13 | 14 | throw new Error(message); 15 | } 16 | 17 | module.exports = { 18 | API_URL: process.env.API_URL 19 | }; 20 | -------------------------------------------------------------------------------- /scripts/index.js: -------------------------------------------------------------------------------- 1 | // A few external library requires as an example 2 | const BPromise = require('bluebird'); 3 | const attachFastClick = require('fastclick'); 4 | 5 | const config = require('./config'); 6 | 7 | function main() { 8 | console.log('Executing main() ..'); 9 | console.log(`This bundle.js points to API_URL=${config.API_URL}`); 10 | 11 | // As an example 12 | attachFastClick(document.body); 13 | } 14 | 15 | window.onload = main; 16 | -------------------------------------------------------------------------------- /styles/custom-reset.less: -------------------------------------------------------------------------------- 1 | ul, ol { 2 | list-style-position: outside; 3 | margin-left: 1.9rem; 4 | } 5 | 6 | li > p { 7 | margin-top: 1rem; 8 | } 9 | 10 | h4 { 11 | font-size: 2.4rem; 12 | } 13 | 14 | h5 { 15 | font-size: 1.5rem; 16 | } 17 | 18 | h6 { 19 | font-size: 1.3rem; 20 | } 21 | -------------------------------------------------------------------------------- /styles/fonts.less: -------------------------------------------------------------------------------- 1 | @font-source-sans: "Source Sans Pro", Helvetica, sans-serif; 2 | @font-raleway: "Raleway", Helvetica, sans-serif; 3 | @font-base-color: #555; 4 | @font-size-xxx-large: 3.998rem; 5 | @font-size-xx-large: 2.827rem; 6 | @font-size-x-large: 1.999rem; 7 | @font-size-large: 1.414rem; 8 | @font-size-medium: 1rem; 9 | @font-size-small: 0.707rem; 10 | @font-size-x-small: 0.5rem; 11 | @font-size-xx-small: 0.345rem; 12 | 13 | body { 14 | font-size: 16px; 15 | font-family: @font-source-sans; 16 | color: @font-base-color; 17 | } 18 | 19 | header, h1, h2, h3, h4, h5, h6 { 20 | font-family: @font-raleway; 21 | font-weight: bold; 22 | color: #4A4949; 23 | } 24 | 25 | header, h1, h2, .uppercase { 26 | letter-spacing: 0.25em; 27 | text-transform: uppercase; 28 | font-weight: 900; 29 | } 30 | 31 | .raleway { 32 | font-family: @font-raleway; 33 | } 34 | 35 | .sub-header { 36 | font-size: 1.3rem; 37 | } 38 | 39 | p { 40 | max-width: 600px; 41 | } 42 | 43 | b { 44 | font-weight: 600; 45 | } 46 | -------------------------------------------------------------------------------- /styles/gh-link.less: -------------------------------------------------------------------------------- 1 | @iconlink-pad: 24px; 2 | 3 | .github-link { 4 | display: block; 5 | visibility: visible; 6 | position: absolute; 7 | z-index: 999999; 8 | top: 20px; 9 | right: 20px; 10 | 11 | > a { 12 | color: #505d6b; 13 | 14 | &:hover { 15 | color: #1EAEDB; 16 | } 17 | } 18 | } 19 | 20 | .iconlink { 21 | border-bottom: none; 22 | position: relative; 23 | display: inline-block; 24 | vertical-align: middle; 25 | line-height: 1em; 26 | color: #505d6b; 27 | transition: all 150ms linear; 28 | padding: 10px; 29 | } 30 | 31 | .iconlink:hover { 32 | color: #505d6b; 33 | } 34 | 35 | .iconlink { 36 | white-space: nowrap; 37 | text-decoration: none; 38 | } 39 | 40 | // Tooltip 41 | .iconlink[data-title]:before { 42 | font-weight: 300; 43 | content: attr(data-title); 44 | display: inline-block; 45 | position: absolute; 46 | bottom: -10px - @iconlink-pad; 47 | right: 10px; 48 | font-size: 13px; 49 | padding: 5px 10px; 50 | background: #404040; 51 | color: white; 52 | border: solid 1px #555; 53 | border-radius: 2px; 54 | text-decoration: none; 55 | width: auto; 56 | white-space: nowrap; 57 | pointer-events: none; 58 | opacity: 0; 59 | transition: opacity 150ms linear, transform 150ms linear; 60 | transform: translate3d(0, -8px, 0); 61 | } 62 | 63 | .iconlink.iconlink-right[data-title]:before { 64 | left: 10px; 65 | right: auto; 66 | } 67 | 68 | .iconlink.iconlink-light[data-title]:before { 69 | background: rgb(244, 244, 244); 70 | color: #4A4949; 71 | } 72 | 73 | .iconlink[data-title]:hover:before { 74 | opacity: 1; 75 | transform: translate3d(0, 0, 0); 76 | pointer-events: auto; 77 | } 78 | 79 | .iconlink i.fa { 80 | font-size: @font-size-xx-large; 81 | } 82 | -------------------------------------------------------------------------------- /styles/index.less: -------------------------------------------------------------------------------- 1 | @import (inline) 'libs/normalize.css'; 2 | @import (inline) 'libs/skeleton.css'; 3 | 4 | @import 'variables.less'; 5 | @import 'custom-reset.less'; 6 | @import 'fonts.less'; 7 | @import 'utils.less'; 8 | @import 'layout.less'; 9 | @import 'gh-link.less'; 10 | -------------------------------------------------------------------------------- /styles/layout.less: -------------------------------------------------------------------------------- 1 | html, body { 2 | width: 100%; 3 | height: 100%; 4 | background: @grey-900; 5 | } 6 | 7 | .container { 8 | max-width: 700px; 9 | padding-top: 60px; 10 | padding-bottom: 40px; 11 | } 12 | 13 | .intro { 14 | padding-top: 30px; 15 | } 16 | 17 | h4 { 18 | padding-top: 20px; 19 | } 20 | 21 | h5 { 22 | padding-top: 15px; 23 | } 24 | -------------------------------------------------------------------------------- /styles/libs/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | font-size: 2em; 137 | margin: 0.67em 0; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | background: #ff0; 146 | color: #000; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | font-size: 75%; 164 | line-height: 0; 165 | position: relative; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | -moz-box-sizing: content-box; 213 | box-sizing: content-box; 214 | height: 0; 215 | } 216 | 217 | /** 218 | * Contain overflow in all browsers. 219 | */ 220 | 221 | pre { 222 | overflow: auto; 223 | } 224 | 225 | /** 226 | * Address odd `em`-unit font size rendering in all browsers. 227 | */ 228 | 229 | code, 230 | kbd, 231 | pre, 232 | samp { 233 | font-family: monospace, monospace; 234 | font-size: 1em; 235 | } 236 | 237 | /* Forms 238 | ========================================================================== */ 239 | 240 | /** 241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 242 | * styling of `select`, unless a `border` property is set. 243 | */ 244 | 245 | /** 246 | * 1. Correct color not being inherited. 247 | * Known issue: affects color of disabled elements. 248 | * 2. Correct font properties not being inherited. 249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | color: inherit; /* 1 */ 258 | font: inherit; /* 2 */ 259 | margin: 0; /* 3 */ 260 | } 261 | 262 | /** 263 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 264 | */ 265 | 266 | button { 267 | overflow: visible; 268 | } 269 | 270 | /** 271 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 272 | * All other form control elements do not inherit `text-transform` values. 273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 274 | * Correct `select` style inheritance in Firefox. 275 | */ 276 | 277 | button, 278 | select { 279 | text-transform: none; 280 | } 281 | 282 | /** 283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 284 | * and `video` controls. 285 | * 2. Correct inability to style clickable `input` types in iOS. 286 | * 3. Improve usability and consistency of cursor style between image-type 287 | * `input` and others. 288 | */ 289 | 290 | button, 291 | html input[type="button"], /* 1 */ 292 | input[type="reset"], 293 | input[type="submit"] { 294 | -webkit-appearance: button; /* 2 */ 295 | cursor: pointer; /* 3 */ 296 | } 297 | 298 | /** 299 | * Re-set default cursor for disabled elements. 300 | */ 301 | 302 | button[disabled], 303 | html input[disabled] { 304 | cursor: default; 305 | } 306 | 307 | /** 308 | * Remove inner padding and border in Firefox 4+. 309 | */ 310 | 311 | button::-moz-focus-inner, 312 | input::-moz-focus-inner { 313 | border: 0; 314 | padding: 0; 315 | } 316 | 317 | /** 318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 319 | * the UA stylesheet. 320 | */ 321 | 322 | input { 323 | line-height: normal; 324 | } 325 | 326 | /** 327 | * It's recommended that you don't attempt to style these elements. 328 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 329 | * 330 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 331 | * 2. Remove excess padding in IE 8/9/10. 332 | */ 333 | 334 | input[type="checkbox"], 335 | input[type="radio"] { 336 | box-sizing: border-box; /* 1 */ 337 | padding: 0; /* 2 */ 338 | } 339 | 340 | /** 341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 342 | * `font-size` values of the `input`, it causes the cursor style of the 343 | * decrement button to change from `default` to `text`. 344 | */ 345 | 346 | input[type="number"]::-webkit-inner-spin-button, 347 | input[type="number"]::-webkit-outer-spin-button { 348 | height: auto; 349 | } 350 | 351 | /** 352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 354 | * (include `-moz` to future-proof). 355 | */ 356 | 357 | input[type="search"] { 358 | -webkit-appearance: textfield; /* 1 */ 359 | -moz-box-sizing: content-box; 360 | -webkit-box-sizing: content-box; /* 2 */ 361 | box-sizing: content-box; 362 | } 363 | 364 | /** 365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 366 | * Safari (but not Chrome) clips the cancel button when the search input has 367 | * padding (and `textfield` appearance). 368 | */ 369 | 370 | input[type="search"]::-webkit-search-cancel-button, 371 | input[type="search"]::-webkit-search-decoration { 372 | -webkit-appearance: none; 373 | } 374 | 375 | /** 376 | * Define consistent border, margin, and padding. 377 | */ 378 | 379 | fieldset { 380 | border: 1px solid #c0c0c0; 381 | margin: 0 2px; 382 | padding: 0.35em 0.625em 0.75em; 383 | } 384 | 385 | /** 386 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 388 | */ 389 | 390 | legend { 391 | border: 0; /* 1 */ 392 | padding: 0; /* 2 */ 393 | } 394 | 395 | /** 396 | * Remove default vertical scrollbar in IE 8/9/10/11. 397 | */ 398 | 399 | textarea { 400 | overflow: auto; 401 | } 402 | 403 | /** 404 | * Don't inherit the `font-weight` (applied by a rule above). 405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 406 | */ 407 | 408 | optgroup { 409 | font-weight: bold; 410 | } 411 | 412 | /* Tables 413 | ========================================================================== */ 414 | 415 | /** 416 | * Remove most spacing between table cells. 417 | */ 418 | 419 | table { 420 | border-collapse: collapse; 421 | border-spacing: 0; 422 | } 423 | 424 | td, 425 | th { 426 | padding: 0; 427 | } -------------------------------------------------------------------------------- /styles/libs/skeleton.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Skeleton V2.0.4 3 | * Copyright 2014, Dave Gamache 4 | * www.getskeleton.com 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 12/29/2014 8 | */ 9 | 10 | 11 | /* Table of contents 12 | –––––––––––––––––––––––––––––––––––––––––––––––––– 13 | - Grid 14 | - Base Styles 15 | - Typography 16 | - Links 17 | - Buttons 18 | - Forms 19 | - Lists 20 | - Code 21 | - Tables 22 | - Spacing 23 | - Utilities 24 | - Clearing 25 | - Media Queries 26 | */ 27 | 28 | 29 | /* Grid 30 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 31 | .container { 32 | position: relative; 33 | width: 100%; 34 | max-width: 960px; 35 | margin: 0 auto; 36 | padding: 0 20px; 37 | box-sizing: border-box; } 38 | .column, 39 | .columns { 40 | width: 100%; 41 | float: left; 42 | box-sizing: border-box; } 43 | 44 | /* For devices larger than 400px */ 45 | @media (min-width: 400px) { 46 | .container { 47 | width: 85%; 48 | padding: 0; } 49 | } 50 | 51 | /* For devices larger than 550px */ 52 | @media (min-width: 550px) { 53 | .container { 54 | width: 80%; } 55 | .column, 56 | .columns { 57 | margin-left: 4%; } 58 | .column:first-child, 59 | .columns:first-child { 60 | margin-left: 0; } 61 | 62 | .one.column, 63 | .one.columns { width: 4.66666666667%; } 64 | .two.columns { width: 13.3333333333%; } 65 | .three.columns { width: 22%; } 66 | .four.columns { width: 30.6666666667%; } 67 | .five.columns { width: 39.3333333333%; } 68 | .six.columns { width: 48%; } 69 | .seven.columns { width: 56.6666666667%; } 70 | .eight.columns { width: 65.3333333333%; } 71 | .nine.columns { width: 74.0%; } 72 | .ten.columns { width: 82.6666666667%; } 73 | .eleven.columns { width: 91.3333333333%; } 74 | .twelve.columns { width: 100%; margin-left: 0; } 75 | 76 | .one-third.column { width: 30.6666666667%; } 77 | .two-thirds.column { width: 65.3333333333%; } 78 | 79 | .one-half.column { width: 48%; } 80 | 81 | /* Offsets */ 82 | .offset-by-one.column, 83 | .offset-by-one.columns { margin-left: 8.66666666667%; } 84 | .offset-by-two.column, 85 | .offset-by-two.columns { margin-left: 17.3333333333%; } 86 | .offset-by-three.column, 87 | .offset-by-three.columns { margin-left: 26%; } 88 | .offset-by-four.column, 89 | .offset-by-four.columns { margin-left: 34.6666666667%; } 90 | .offset-by-five.column, 91 | .offset-by-five.columns { margin-left: 43.3333333333%; } 92 | .offset-by-six.column, 93 | .offset-by-six.columns { margin-left: 52%; } 94 | .offset-by-seven.column, 95 | .offset-by-seven.columns { margin-left: 60.6666666667%; } 96 | .offset-by-eight.column, 97 | .offset-by-eight.columns { margin-left: 69.3333333333%; } 98 | .offset-by-nine.column, 99 | .offset-by-nine.columns { margin-left: 78.0%; } 100 | .offset-by-ten.column, 101 | .offset-by-ten.columns { margin-left: 86.6666666667%; } 102 | .offset-by-eleven.column, 103 | .offset-by-eleven.columns { margin-left: 95.3333333333%; } 104 | 105 | .offset-by-one-third.column, 106 | .offset-by-one-third.columns { margin-left: 34.6666666667%; } 107 | .offset-by-two-thirds.column, 108 | .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } 109 | 110 | .offset-by-one-half.column, 111 | .offset-by-one-half.columns { margin-left: 52%; } 112 | 113 | } 114 | 115 | 116 | /* Base Styles 117 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 118 | /* NOTE 119 | html is set to 62.5% so that all the REM measurements throughout Skeleton 120 | are based on 10px sizing. So basically 1.5rem = 15px :) */ 121 | html { 122 | font-size: 62.5%; } 123 | body { 124 | font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */ 125 | line-height: 1.6; 126 | font-weight: 400; 127 | font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; 128 | color: #222; } 129 | 130 | 131 | /* Typography 132 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 133 | h1, h2, h3, h4, h5, h6 { 134 | margin-top: 0; 135 | margin-bottom: 2rem; 136 | font-weight: 300; } 137 | h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} 138 | h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } 139 | h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } 140 | h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } 141 | h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; } 142 | h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } 143 | 144 | /* Larger than phablet */ 145 | @media (min-width: 550px) { 146 | h1 { font-size: 5.0rem; } 147 | h2 { font-size: 4.2rem; } 148 | h3 { font-size: 3.6rem; } 149 | h4 { font-size: 3.0rem; } 150 | h5 { font-size: 2.4rem; } 151 | h6 { font-size: 1.5rem; } 152 | } 153 | 154 | p { 155 | margin-top: 0; } 156 | 157 | 158 | /* Links 159 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 160 | a { 161 | color: #1EAEDB; } 162 | a:hover { 163 | color: #0FA0CE; } 164 | 165 | 166 | /* Buttons 167 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 168 | .button, 169 | button, 170 | input[type="submit"], 171 | input[type="reset"], 172 | input[type="button"] { 173 | display: inline-block; 174 | height: 38px; 175 | padding: 0 30px; 176 | color: #555; 177 | text-align: center; 178 | font-size: 11px; 179 | font-weight: 600; 180 | line-height: 38px; 181 | letter-spacing: .1rem; 182 | text-transform: uppercase; 183 | text-decoration: none; 184 | white-space: nowrap; 185 | background-color: transparent; 186 | border-radius: 4px; 187 | border: 1px solid #bbb; 188 | cursor: pointer; 189 | box-sizing: border-box; } 190 | .button:hover, 191 | button:hover, 192 | input[type="submit"]:hover, 193 | input[type="reset"]:hover, 194 | input[type="button"]:hover, 195 | .button:focus, 196 | button:focus, 197 | input[type="submit"]:focus, 198 | input[type="reset"]:focus, 199 | input[type="button"]:focus { 200 | color: #333; 201 | border-color: #888; 202 | outline: 0; } 203 | .button.button-primary, 204 | button.button-primary, 205 | input[type="submit"].button-primary, 206 | input[type="reset"].button-primary, 207 | input[type="button"].button-primary { 208 | color: #FFF; 209 | background-color: #33C3F0; 210 | border-color: #33C3F0; } 211 | .button.button-primary:hover, 212 | button.button-primary:hover, 213 | input[type="submit"].button-primary:hover, 214 | input[type="reset"].button-primary:hover, 215 | input[type="button"].button-primary:hover, 216 | .button.button-primary:focus, 217 | button.button-primary:focus, 218 | input[type="submit"].button-primary:focus, 219 | input[type="reset"].button-primary:focus, 220 | input[type="button"].button-primary:focus { 221 | color: #FFF; 222 | background-color: #1EAEDB; 223 | border-color: #1EAEDB; } 224 | 225 | 226 | /* Forms 227 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 228 | input[type="email"], 229 | input[type="number"], 230 | input[type="search"], 231 | input[type="text"], 232 | input[type="tel"], 233 | input[type="url"], 234 | input[type="password"], 235 | textarea, 236 | select { 237 | height: 38px; 238 | padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ 239 | background-color: #fff; 240 | border: 1px solid #D1D1D1; 241 | border-radius: 4px; 242 | box-shadow: none; 243 | box-sizing: border-box; } 244 | /* Removes awkward default styles on some inputs for iOS */ 245 | input[type="email"], 246 | input[type="number"], 247 | input[type="search"], 248 | input[type="text"], 249 | input[type="tel"], 250 | input[type="url"], 251 | input[type="password"], 252 | textarea { 253 | -webkit-appearance: none; 254 | -moz-appearance: none; 255 | appearance: none; } 256 | textarea { 257 | min-height: 65px; 258 | padding-top: 6px; 259 | padding-bottom: 6px; } 260 | input[type="email"]:focus, 261 | input[type="number"]:focus, 262 | input[type="search"]:focus, 263 | input[type="text"]:focus, 264 | input[type="tel"]:focus, 265 | input[type="url"]:focus, 266 | input[type="password"]:focus, 267 | textarea:focus, 268 | select:focus { 269 | border: 1px solid #33C3F0; 270 | outline: 0; } 271 | label, 272 | legend { 273 | display: block; 274 | margin-bottom: .5rem; 275 | font-weight: 600; } 276 | fieldset { 277 | padding: 0; 278 | border-width: 0; } 279 | input[type="checkbox"], 280 | input[type="radio"] { 281 | display: inline; } 282 | label > .label-body { 283 | display: inline-block; 284 | margin-left: .5rem; 285 | font-weight: normal; } 286 | 287 | 288 | /* Lists 289 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 290 | ul { 291 | list-style: circle inside; } 292 | ol { 293 | list-style: decimal inside; } 294 | ol, ul { 295 | padding-left: 0; 296 | margin-top: 0; } 297 | ul ul, 298 | ul ol, 299 | ol ol, 300 | ol ul { 301 | margin: 1.5rem 0 1.5rem 3rem; 302 | font-size: 90%; } 303 | li { 304 | margin-bottom: 0.7rem; } 305 | 306 | 307 | /* Code 308 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 309 | code { 310 | padding: .2rem .5rem; 311 | margin: 0 .2rem; 312 | font-size: 90%; 313 | white-space: nowrap; 314 | background: #F1F1F1; 315 | border: 1px solid #E1E1E1; 316 | border-radius: 4px; } 317 | pre > code { 318 | display: block; 319 | padding: 1rem 1.5rem; 320 | white-space: pre; } 321 | 322 | 323 | /* Tables 324 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 325 | th, 326 | td { 327 | padding: 12px 15px; 328 | text-align: left; 329 | border-bottom: 1px solid #E1E1E1; } 330 | th:first-child, 331 | td:first-child { 332 | padding-left: 0; } 333 | th:last-child, 334 | td:last-child { 335 | padding-right: 0; } 336 | 337 | 338 | /* Spacing 339 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 340 | button, 341 | .button { 342 | margin-bottom: 1rem; } 343 | input, 344 | textarea, 345 | select, 346 | fieldset { 347 | margin-bottom: 1.5rem; } 348 | pre, 349 | blockquote, 350 | dl, 351 | figure, 352 | table, 353 | p, 354 | ul, 355 | ol, 356 | form { 357 | margin-bottom: 2.5rem; } 358 | 359 | 360 | /* Utilities 361 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 362 | .u-full-width { 363 | width: 100%; 364 | box-sizing: border-box; } 365 | .u-max-full-width { 366 | max-width: 100%; 367 | box-sizing: border-box; } 368 | .u-pull-right { 369 | float: right; } 370 | .u-pull-left { 371 | float: left; } 372 | 373 | 374 | /* Misc 375 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 376 | hr { 377 | margin-top: 3rem; 378 | margin-bottom: 3.5rem; 379 | border-width: 0; 380 | border-top: 1px solid #E1E1E1; } 381 | 382 | 383 | /* Clearing 384 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 385 | 386 | /* Self Clearing Goodness */ 387 | .container:after, 388 | .row:after, 389 | .u-cf { 390 | content: ""; 391 | display: table; 392 | clear: both; } 393 | 394 | 395 | /* Media Queries 396 | –––––––––––––––––––––––––––––––––––––––––––––––––– */ 397 | /* 398 | Note: The best way to structure the use of media queries is to create the queries 399 | near the relevant code. For example, if you wanted to change the styles for buttons 400 | on small devices, paste the mobile query code up in the buttons section and style it 401 | there. 402 | */ 403 | 404 | 405 | /* Larger than mobile */ 406 | @media (min-width: 400px) {} 407 | 408 | /* Larger than phablet (also point when grid becomes active) */ 409 | @media (min-width: 550px) {} 410 | 411 | /* Larger than tablet */ 412 | @media (min-width: 750px) {} 413 | 414 | /* Larger than desktop */ 415 | @media (min-width: 1000px) {} 416 | 417 | /* Larger than Desktop HD */ 418 | @media (min-width: 1200px) {} 419 | -------------------------------------------------------------------------------- /styles/utils.less: -------------------------------------------------------------------------------- 1 | .no-list-styling { 2 | list-style-type: none; 3 | margin-left: 0; 4 | } 5 | -------------------------------------------------------------------------------- /styles/variables.less: -------------------------------------------------------------------------------- 1 | @grey-300: #555; 2 | @grey-500: #777; 3 | @grey-800: #ccc; 4 | @grey-900: #eee; 5 | --------------------------------------------------------------------------------