diff --git a/assets/stylesheets/course.css b/assets/stylesheets/course.css new file mode 100644 index 0000000..a7735c1 --- /dev/null +++ b/assets/stylesheets/course.css @@ -0,0 +1,46 @@ +.course-card { + display: flex; + flex-direction: column; + min-height: 30vh; + padding: var(--grid-gutter); + + border-radius: 7px; + box-shadow: var(--card-box-shadow); + + & > * + * { + margin-top: var(--grid-gutter); + } +} + +.course-card__categories { + flex: 0 0 var(--line-height); + color: var(--color-text-grey); +} + +.course-card__title { + flex: 1 1 auto; + + & h2 { + margin: 0; + } +} + +.course-card__description { + flex: 1 1 auto; + + & p { + margin: 0; + } +} + +.course-card__link { + flex: 0 0 auto; + + & a { + display: inline-block; + padding-bottom: 0.3em; + border-bottom: 1px solid var(--color-link-content); + text-transform: uppercase; + color: var(--color-link-content); + } +} diff --git a/assets/stylesheets/global.css b/assets/stylesheets/global.css new file mode 100644 index 0000000..8f42fd5 --- /dev/null +++ b/assets/stylesheets/global.css @@ -0,0 +1,135 @@ +body { + background-color: var(--color-bg-default); + color: var(--color-text-default); + font-family: Helvetica Neue, Helvetica, Arial, sans-serif; + font-size: 1rem; + line-height: var(--line-height); +} + +.wrapper { + max-width: 1024px; + margin: 0 auto; + padding: 0 2vw; + + @media (--breakpoint-desktop) { + padding: 0; + } +} + +.wrapper-with-sidebar { + @media (--breakpoint-desktop) { + display: flex; + } +} + +.wrapper__sidebar { + @media (--breakpoint-desktop) { + flex: 0 0 220px; + padding: var(--grid-gutter); + border-radius: 7px; + box-shadow: var(--card-box-shadow); + + & > h2 { + margin-bottom: calc(var(--grid-gutter) * 3); + } + } +} +.wrapper__content { + padding: var(--grid-gutter) 0; + + @media (--breakpoint-desktop) { + flex: 1 1 auto; + margin-left: var(--grid-gutter); + } +} + +.grid-list { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + margin: 0 calc(var(--grid-gutter) / 2 * -1); + + & > * { + box-sizing: border-box; + margin: 0 calc(var(--grid-gutter) / 2) var(--grid-gutter); + flex: 0 0 calc(50% - var(--grid-gutter)); + + @media (--breakpoint-desktop) { + flex: 0 0 calc(33% - var(--grid-gutter)); + } + } +} + +.grid-list-small { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + margin: 0 calc(var(--grid-gutter) / 2 * -1); + + & > * { + box-sizing: border-box; + margin: 0 calc(var(--grid-gutter) / 2) var(--grid-gutter); + flex: 0 0 calc(50% - var(--grid-gutter)); + } +} + +.table-of-contents { + & ul { + list-style: none; + margin: var(--grid-gutter) 0; + padding: 0; + padding-left: calc(var(--grid-gutter) * 2); + + & li { + margin: 0 0 var(--grid-gutter); + padding: 0; + } + + & a { + display: block; + + &.active { + position: relative; + font-weight: bold; + + &:before, + &:after { + position: absolute; + top: 0; + } + &:before { + content: ''; + left: calc(var(--grid-gutter) * 3 * -1); + bottom: 0; + width: 3px; + background: var(--color-course-active); + } + &:after { + content: '👁'; + left: calc(var(--grid-gutter) * 2 * -1); + } + } + } + } +} + +.sidebar-menu { + & ul { + list-style: none; + margin: var(--grid-gutter) 0; + padding: 0; + + & li { + margin: 0 0 var(--grid-gutter); + padding: 0; + } + + & a { + display: block; + + &.active { + font-weight: bold; + } + } + } +} diff --git a/assets/stylesheets/header.css b/assets/stylesheets/header.css new file mode 100644 index 0000000..b411ee2 --- /dev/null +++ b/assets/stylesheets/header.css @@ -0,0 +1,113 @@ +.header { + display: flex; + flex-wrap: wrap; + + margin-top: var(--grid-gutter); + padding-bottom: var(--grid-gutter); + margin-bottom: var(--grid-gutter); + + border-bottom: 2px solid var(--color-bg-separator); + + @media (--breakpoint-desktop) { + flex-wrap: nowrap; + } + + & .header__logo, + & .header__navarea { + display: flex; + flex: 0 0 100%; + } + + & .header__logo { + align-items: center; + + @media (--breakpoint-desktop) { + flex: 0 0 200px; + } + } + + & .header__navarea { + flex-direction: column; + justify-content: space-around; + + @media (--breakpoint-desktop) { + flex: 1 0 auto; + } + } +} + +.header__navarea { + & form { + display: flex; + flex-wrap: wrap; + + @media (--breakpoint-desktop) { + justify-content: flex-end; + } + + & > * { + flex: 0 0 auto; + } + + & fieldset { + padding: 0.2em 1em; + margin: 0; + border: none; + background: var(--color-bg-grey); + color: var(--color-text-grey); + border-radius: var(--border-radius); + font-size: 0.8em; + + & + fieldset { + margin-left: var(--grid-gutter) + } + + & label + select { + margin-left: 0.5em; + } + } + } +} + +.navigation { + & nav { + & ul { + display: flex; + list-style: none; + flex-wrap: wrap; + margin: 0; + padding: 0; + + @media (--breakpoint-desktop) { + justify-content: flex-end; + } + + & li { + margin: 0; + + & + li { + margin-left: calc(var(--grid-gutter) / 4); + } + + & a { + display: block; + text-transform: uppercase; + font-weight: bold; + padding: 0.7em 1em; + color: var(--color-text-grey); + border-radius: var(--border-radius); + + &.active, + &:hover { + background: var(--color-bg-grey); + } + + &.active { + color: var(--color-text-default); + } + } + } + } + } +} + diff --git a/assets/stylesheets/homepage.css b/assets/stylesheets/homepage.css new file mode 100644 index 0000000..5027548 --- /dev/null +++ b/assets/stylesheets/homepage.css @@ -0,0 +1,25 @@ +.hero { + display: flex; + justify-content: space-between; +} +.hero__image { + background-color: #20B5B6; + width: 65%; + height: 600px; + border-radius: .375rem; + box-shadow: var(--card-box-shadow); +} +.featured-cards-list { + width: 30%; + height: 600px; + display:flex; + flex-direction: column; + justify-content: space-between; +} + +.featured-cards__list { + background-color: #00AAE0; + height: 150px; + border-radius: .375rem; + box-shadow: var(--card-box-shadow); +} diff --git a/assets/stylesheets/module.css b/assets/stylesheets/module.css new file mode 100644 index 0000000..12074f7 --- /dev/null +++ b/assets/stylesheets/module.css @@ -0,0 +1,19 @@ +.module { + max-width: 1024px; + margin: 0 auto; + padding: 0 2vw; + + @media (--breakpoint-desktop) { + padding: 0; + } + + + & img { + width: 100%; + height: auto; + } + + & + .module { + margin-top: var(--grid-gutter); + } +} diff --git a/assets/stylesheets/style.css b/assets/stylesheets/style.css new file mode 100644 index 0000000..5d8dafb --- /dev/null +++ b/assets/stylesheets/style.css @@ -0,0 +1,11 @@ +@import 'normalize.css'; + +@import './variables'; + +@import './typography'; +@import './global'; +@import './header'; + +@import './homepage'; +@import './course'; +@import './module'; diff --git a/assets/stylesheets/typography.css b/assets/stylesheets/typography.css new file mode 100644 index 0000000..401cf8f --- /dev/null +++ b/assets/stylesheets/typography.css @@ -0,0 +1,10 @@ +h1, h2, h3, h4, h5, h6 { + &:first-child { + margin-top: 0; + } +} + +a { + color: inherit; + text-decoration: none; +} diff --git a/assets/stylesheets/variables.css b/assets/stylesheets/variables.css new file mode 100644 index 0000000..988f723 --- /dev/null +++ b/assets/stylesheets/variables.css @@ -0,0 +1,23 @@ +@custom-media --breakpoint-desktop (min-width: 700px); + +:root { + --grid-gutter: 1rem; + --border-radius: 3px; + + --line-height: 1.5em; + + --color-text-default: #2a303a; + --color-text-grey: #8091a5; + + --color-link-content: #5c9fef; + + --color-bg-default: #fff; + --color-bg-grey: #f7f9fa; + --color-bg-separator: #f2f5f7; + + --color-sidebar-bg: #f7f9fa; + + --color-course-active: #536171; + + --card-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .45); +} diff --git a/package.json b/package.json index 5fb0761..d1e9055 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "start:watch": "nodemon ./bin/www --ignore public/", "start": "node ./bin/www", "lint": "eslint ./app.js routes", - "format": "eslint --fix . bin --ignore public node_modules" + "format": "eslint --fix . bin --ignore public node_modules", + "styles": "postcss -c ./postcss.config.js ./assets/stylesheets/style.css -d ./public/stylesheets", + "styles:watch": "npm run styles -- -w" }, "dependencies": { "body-parser": "~1.15.2", @@ -16,14 +18,22 @@ "dotenv": "^4.0.0", "express": "~4.14.0", "morgan": "~1.7.0", + "normalize.css": "^7.0.0", "pug": "~2.0.0-beta6", "serve-favicon": "~2.3.0" }, "devDependencies": { - "nodemon": "^1.12.1", "eslint": "^3.16.0", "eslint-config-standard": "^6.2.1", "eslint-plugin-promise": "^3.4.2", - "eslint-plugin-standard": "^2.0.1" + "eslint-plugin-standard": "^2.0.1", + "nodemon": "^1.12.1", + "postcss": "^6.0.12", + "postcss-browser-reporter": "^0.5.0", + "postcss-cli": "^4.1.1", + "postcss-cssnext": "^3.0.2", + "postcss-import": "^11.0.0", + "postcss-reporter": "^5.0.0", + "postcss-url": "^7.1.2" } } diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..642475d --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,9 @@ +module.exports = { + plugins: { + 'postcss-import': {}, + 'postcss-url': {}, + 'postcss-cssnext': {}, + 'postcss-browser-reporter': {}, + 'postcss-reporter': {} + } +} diff --git a/public/images/logo.png b/public/images/logo.png new file mode 100644 index 0000000..0b3607e Binary files /dev/null and b/public/images/logo.png differ diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 8e7280f..95b07f4 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -1,178 +1,929 @@ -* { - box-sizing: border-box; +/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers (opinionated). + */ + +body { + margin: 0; +} + +/** + * Add the correct display in IE 9-. + */ + +article, +aside, +footer, +header, +nav, +section { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * Add the correct display in IE 9-. + * 1. Add the correct display in IE. + */ + +figcaption, +figure, +main { /* 1 */ + display: block; +} + +/** + * Add the correct margin in IE 8. + */ + +figure { + margin: 1em 40px; +} + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + -webkit-box-sizing: content-box; + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * 1. Remove the gray background on active links in IE 10. + * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. + */ + +a { + background-color: transparent; /* 1 */ + -webkit-text-decoration-skip: objects; /* 2 */ +} + +/** + * 1. Remove the bottom border in Chrome 57- and Firefox 39-. + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; /* 2 */ +} + +/** + * Prevent the duplicate application of `bolder` by the next rule in Safari 6. + */ + +b, +strong { + font-weight: inherit; +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font style in Android 4.3-. + */ + +dfn { + font-style: italic; +} + +/** + * Add the correct background and color in IE 9-. + */ + +mark { + background-color: #ff0; + color: #000; +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Add the correct display in IE 9-. + */ + +audio, +video { + display: inline-block; +} + +/** + * Add the correct display in iOS 4-7. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Remove the border on images inside links in IE 10-. + */ + +img { + border-style: none; +} + +/** + * Hide the overflow in IE. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers (opinionated). + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: sans-serif; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` + * controls in Android 4. + * 2. Correct the inability to style clickable types in iOS and Safari. + */ + +button, +html [type="button"], /* 1 */ +[type="reset"], +[type="submit"] { + -webkit-appearance: button; /* 2 */ +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + -webkit-box-sizing: border-box; + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * 1. Add the correct display in IE 9-. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Remove the default vertical scrollbar in IE. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10-. + * 2. Remove the padding in IE 10-. + */ + +[type="checkbox"], +[type="radio"] { + -webkit-box-sizing: border-box; + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in IE 9-. + * 1. Add the correct display in Edge, IE, and Firefox. + */ + +details, /* 1 */ +menu { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Scripting + ========================================================================== */ + +/** + * Add the correct display in IE 9-. + */ + +canvas { + display: inline-block; +} + +/** + * Add the correct display in IE. + */ + +template { + display: none; +} + +/* Hidden + ========================================================================== */ + +/** + * Add the correct display in IE 10-. + */ + +[hidden] { + display: none; +} + +h1:first-child, h2:first-child, h3:first-child, h4:first-child, h5:first-child, h6:first-child { + margin-top: 0; +} + +a { + color: inherit; + text-decoration: none; } body { - background-color: #eee; - color: #333; + background-color: #fff; + color: #2a303a; font-family: Helvetica Neue, Helvetica, Arial, sans-serif; + font-size: 16px; font-size: 1rem; line-height: 1.5em; } -header, section { - background-color: #fff; - margin: 0 auto 2rem; - padding: 1rem 2rem 2rem; - width: 80%; +.wrapper { + max-width: 1024px; + margin: 0 auto; + padding: 0 2vw; } -h1, h2, h3, h4, h5, h6 { - font-family: Montserrat, Helvetica Neue, Helvetica, Arial, sans-serif; - font-weight: bold; - line-height: 1.2em; - margin-bottom: 1.5rem; +@media (min-width: 700px) { + + .wrapper { + padding: 0; + } } -h1 { - font-size: 2rem; - text-align: center; +@media (min-width: 700px) { + + .wrapper-with-sidebar { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + } } -h2 { - font-size: 1.25rem; - margin-bottom: .5rem; +@media (min-width: 700px) { + + .wrapper__sidebar { + -webkit-box-flex: 0; + -ms-flex: 0 0 220px; + flex: 0 0 220px; + padding: 1rem; + border-radius: 7px; + -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .45); + box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .45); + } + + .wrapper__sidebar > h2 { + margin-bottom: 3rem; + } } -a { - color: #b13131; - text-decoration: none; +.wrapper__content { + padding: 16px 0; + padding: 1rem 0; } -p { - margin-bottom: 1.5rem; -} -h2 + p { - color: #757575; - font-family: Montserrat, Helvetica Neue, Helvetica, Arial, sans-serif; - letter-spacing: 1px; - margin-top: -.5rem; - text-transform: uppercase; -} -p code { - background-color: rgba(251, 175, 93, 0.25); - border: 1px solid rgba(0, 0, 0, 0.25); - border-radius: 4px; - display: inline-block; - margin: 0 .25rem; - padding: 0 .25rem; +@media (min-width: 700px) { + + .wrapper__content { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + margin-left: 1rem; + } } -ul { - border-bottom: 1px solid #ccc; +.grid-list { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + margin: 0 -8px; + margin: 0 -0.5rem +} + +.grid-list > * { + -webkit-box-sizing: border-box; + box-sizing: border-box; + margin: 0 8px 16px; + margin: 0 0.5rem 1rem; + -webkit-box-flex: 0; + -ms-flex: 0 0 calc(50% - 1rem); + flex: 0 0 calc(50% - 1rem); +} + +@media (min-width: 700px) { + + .grid-list > * { + -webkit-box-flex: 0; + -ms-flex: 0 0 calc(33% - 1rem); + flex: 0 0 calc(33% - 1rem); + } +} + +.grid-list-small { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + margin: 0 -8px; + margin: 0 -0.5rem +} + +.grid-list-small > * { + -webkit-box-sizing: border-box; + box-sizing: border-box; + margin: 0 8px 16px; + margin: 0 0.5rem 1rem; + -webkit-box-flex: 0; + -ms-flex: 0 0 calc(50% - 1rem); + flex: 0 0 calc(50% - 1rem); +} + +.table-of-contents ul { list-style: none; - margin: 0 0 1.5rem 0; + margin: 16px 0; + margin: 1rem 0; + padding: 0; + padding-left: 32px; + padding-left: 2rem; +} + +.table-of-contents ul li { + margin: 0 0 16px; + margin: 0 0 1rem; padding: 0; } -li { - background-image: linear-gradient(to bottom, transparent 50%, #a2d39c 50%, #a2d39c 95%, #7cc576 95%); - background-size: 100% 200%; - background-position: top center; - color: #666; +.table-of-contents ul a { display: block; - text-align: center; - text-decoration: none; - transition: all .25s ease-in-out; -} -li:hover { - background-position: bottom center; - color: rgba(0, 0, 0, 0.75); -} -li a { - color: #666; - display: block; - padding: 1rem 0; - transition: all .25s ease-in-out; } -nav ul { - background-color: #eee; - border: 0; - display: flex; - padding: 0 2rem; +.table-of-contents ul a.active { position: relative; - left: -2rem; - width: calc(100% + 4rem); -} -nav ul li { - background-image: linear-gradient(to bottom, transparent 50%, #448ccb 50%, #448ccb 95%, #0072bc 95%); - flex: 1 1 auto; -} -nav ul li a:hover { - color: #eee; + font-weight: bold; } -nav ul li { - border-left: 2px solid #ddd; - transform: skew(-15deg); -} -nav ul li:last-child { - border-right: 2px solid #ddd; -} -nav ul li a { - transform: skew(15deg); -} -/* Form */ -input, textarea { - width:100%; - padding:10px; - border: 1px solid $grey; -} - -label { - padding: 10px 0; - display: block; -} -.form { - background: white; - padding: 2rem; - box-shadow: $grad; -} -/* Course */ -.course { - position: relative; - background-color: white; - padding: 10px; - width: 30%; - height: 500px; - border-radius: 7px; - box-shadow: 0px 0px 3px 0px rgba(0,0,0,0.45); - position:relative; -} -.course__description { - border-top: 2px solid black; - margin: 60px 0 20px 0; -} -.course__link { +.table-of-contents ul a.active:before, + .table-of-contents ul a.active:after { position: absolute; - bottom:20px; + top: 0; } -/* Home Page __ hero*/ -.hero { + +.table-of-contents ul a.active:before { + content: ''; + left: -48px; + left: -3rem; + bottom: 0; + width: 3px; + background: #536171; +} + +.table-of-contents ul a.active:after { + content: '👁'; + left: -32px; + left: -2rem; +} + +.sidebar-menu ul { + list-style: none; + margin: 16px 0; + margin: 1rem 0; + padding: 0; +} + +.sidebar-menu ul li { + margin: 0 0 16px; + margin: 0 0 1rem; + padding: 0; +} + +.sidebar-menu ul a { + display: block; +} + +.sidebar-menu ul a.active { + font-weight: bold; +} + +.header { + display: -webkit-box; + display: -ms-flexbox; display: flex; - justify-content: space-between; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + + margin-top: 16px; + + margin-top: 1rem; + padding-bottom: 16px; + padding-bottom: 1rem; + margin-bottom: 16px; + margin-bottom: 1rem; + + border-bottom: 2px solid #f2f5f7; } + +@media (min-width: 700px) { + + .header { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } +} + +.header .header__logo, + .header .header__navarea { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; +} + +.header .header__logo { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +@media (min-width: 700px) { + + .header .header__logo { + -webkit-box-flex: 0; + -ms-flex: 0 0 200px; + flex: 0 0 200px; + } +} + +.header .header__navarea { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -ms-flex-pack: distribute; + justify-content: space-around; +} + +@media (min-width: 700px) { + + .header .header__navarea { + -webkit-box-flex: 1; + -ms-flex: 1 0 auto; + flex: 1 0 auto; + } +} + +.header__navarea form { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; +} + +@media (min-width: 700px) { + + .header__navarea form { + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + } +} + +.header__navarea form > * { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; +} + +.header__navarea form fieldset { + padding: 0.2em 1em; + margin: 0; + border: none; + background: #f7f9fa; + color: #8091a5; + border-radius: 3px; + font-size: 0.8em; +} + +.header__navarea form fieldset + fieldset { + margin-left: 16px; + margin-left: 1rem; +} + +.header__navarea form fieldset label + select { + margin-left: 0.5em; +} + +.navigation nav ul { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + list-style: none; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin: 0; + padding: 0; +} + +@media (min-width: 700px) { + + .navigation nav ul { + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + } +} + +.navigation nav ul li { + margin: 0; +} + +.navigation nav ul li + li { + margin-left: 4px; + margin-left: 0.25rem; +} + +.navigation nav ul li a { + display: block; + text-transform: uppercase; + font-weight: bold; + padding: 0.7em 1em; + color: #8091a5; + border-radius: 3px; +} + +.navigation nav ul li a.active, + .navigation nav ul li a:hover { + background: #f7f9fa; +} + +.navigation nav ul li a.active { + color: #2a303a; +} + +.hero { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + .hero__image { background-color: #20B5B6; width: 65%; height: 600px; border-radius: .375rem; - box-shadow: 5px 5px 25px 0 rgba(46,61,73,.2); + -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .45); + box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .45); } + .featured-cards-list { width: 30%; height: 600px; + display:-webkit-box; + display:-ms-flexbox; display:flex; - flex-direction: column; - justify-content: space-between; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; } .featured-cards__list { background-color: #00AAE0; height: 150px; border-radius: .375rem; - box-shadow: 5px 5px 25px 0 rgba(46,61,73,.2); + -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .45); + box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .45); } +.course-card { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + min-height: 30vh; + padding: 16px; + padding: 1rem; + border-radius: 7px; + -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .45); + box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .45) +} + +.course-card > * + * { + margin-top: 16px; + margin-top: 1rem; +} + +.course-card__categories { + -webkit-box-flex: 0; + -ms-flex: 0 0 1.5em; + flex: 0 0 1.5em; + color: #8091a5; +} + +.course-card__title { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto +} + +.course-card__title h2 { + margin: 0; +} + +.course-card__description { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto +} + +.course-card__description p { + margin: 0; +} + +.course-card__link { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto +} + +.course-card__link a { + display: inline-block; + padding-bottom: 0.3em; + border-bottom: 1px solid #5c9fef; + text-transform: uppercase; + color: #5c9fef; +} + +.module { + max-width: 1024px; + margin: 0 auto; + padding: 0 2vw; +} + +@media (min-width: 700px) { + + .module { + padding: 0; + } +} + +.module img { + width: 100%; + height: auto; +} + +.module + .module { + margin-top: 16px; + margin-top: 1rem; +} diff --git a/services/contentful.js b/services/contentful.js index f783c65..68a3835 100644 --- a/services/contentful.js +++ b/services/contentful.js @@ -17,7 +17,7 @@ exports.getCourses = () => { exports.getLandingPage = () => { // our Home page is fully configureable via contentful - return client.getEntries({content_type: 'landingPage', 'fields.slug': 'contentful-university'}) + return client.getEntries({content_type: 'landingPage', 'fields.slug': 'contentful-university', include: 10}) .then((response) => response.items[0]) } diff --git a/views/about.pug b/views/about.pug index 3d63b9a..208cbad 100644 --- a/views/about.pug +++ b/views/about.pug @@ -1,5 +1,6 @@ extends layout block content - h1= title - p Welcome to #{title} + .wrapper + h1= title + p Welcome to #{title} diff --git a/views/categories.pug b/views/categories.pug index 3d63b9a..208cbad 100644 --- a/views/categories.pug +++ b/views/categories.pug @@ -1,5 +1,6 @@ extends layout block content - h1= title - p Welcome to #{title} + .wrapper + h1= title + p Welcome to #{title} diff --git a/views/course.pug b/views/course.pug index 4ce2383..0eb679e 100644 --- a/views/course.pug +++ b/views/course.pug @@ -1,12 +1,21 @@ extends layout block content - h1= course.fields.title - if lesson - p= lesson.fields.description - else - p= course.fields.description - ul - each lesson in course.fields.lessons - li - a(href=`/courses/${course.fields.slug}/lessons/${lesson.fields.slug}`) #{lesson.fields.title} + .wrapper.wrapper-with-sidebar + section.wrapper__sidebar + h2 Table of contents + .table-of-contents + ul + li + a.active(href=`/courses/${course.fields.slug}`) Course overview + each lesson in course.fields.lessons + li + a(href=`/courses/${course.fields.slug}/lessons/${lesson.fields.slug}`) #{lesson.fields.title} + section.wrapper__content + h1= course.fields.title + + if lesson + h2= lesson.fields.title + p= lesson.fields.description + else + p= course.fields.description diff --git a/views/courses.pug b/views/courses.pug index 23ab070..a653b25 100644 --- a/views/courses.pug +++ b/views/courses.pug @@ -3,9 +3,18 @@ extends layout include mixins/_courseCard block content - ul - each category in categories - li - a(href=`/courses/categories/${category.sys.id}`) #{category.fields.title} - each course in courses - +courseCard(course) + .wrapper.wrapper-with-sidebar + section.wrapper__sidebar + h2 Categories + .sidebar-menu + ul + li + a.active(href=`/courses`) All courses + each category in categories + li + a(href=`/courses/categories/${category.sys.id}`) #{category.fields.title} + section.wrapper__content + h1= title + .courses.grid-list-small + each course in courses + +courseCard(course) diff --git a/views/error.pug b/views/error.pug index 51ec12c..b5d8a8b 100644 --- a/views/error.pug +++ b/views/error.pug @@ -1,6 +1,7 @@ extends layout block content - h1= message - h2= error.status - pre #{error.stack} + .wrapper + h1= message + h2= error.status + pre #{error.stack} diff --git a/views/layout.pug b/views/layout.pug index 4d2b854..7b58bff 100644 --- a/views/layout.pug +++ b/views/layout.pug @@ -4,22 +4,36 @@ html title= title link(rel='stylesheet', href='/stylesheets/style.css') body - header - .header__navbar--logo - a.logo--link(href='#') Contentful University - .header__navbar--navigation - nav - ul - li - a.button--navigation(href='/') Home - li - a.button--navigation(href='/courses') Courses - li - a.button--navigation(href='/categories') Categories - li - a.button--navigation(href='/about') About - li - a.button--navigation(href='/settings') Settings - li - a.button--navigation(href='/sitemap') Sitemap + header.header.wrapper + section.header__logo + a.logo--link(href='#') + img(src='/images/logo.png' alt='Contentful University') + section.header__navarea + section.controls + form(action="." method="get") + fieldset + label(for='api') API type: + select(name='api' onChange='this.form.submit()') + option(value='CDA') Delivery API + option(value='CPA') Preview API + fieldset + label(for='locale') Language: + select(name='locale' onChange='this.form.submit()') + option(value='en-US') English + option(value='de-DE') German + section.navigation + nav + ul + li + a.active(href='/') Home + li + a(href='/courses') Courses + li + a(href='/categories') Categories + li + a(href='/about') About + li + a(href='/settings') Settings + li + a(href='/sitemap') Sitemap block content diff --git a/views/mixins/_courseCard.pug b/views/mixins/_courseCard.pug index fe2c82a..3ea3f39 100644 --- a/views/mixins/_courseCard.pug +++ b/views/mixins/_courseCard.pug @@ -1,10 +1,13 @@ mixin courseCard(course = {fields: {title: '', description: '', categories: [], slug: ''}}) - .course - .course__categories - if course.fields.categories + .course-card + .course-card__categories + if(course.fields.categories) each category in course.fields.categories - a.course__categories--category(href=`categories/${category.fields.slug}`) #{category.title} - h1.course__title #{course.fields.title} - .course__description #{course.fields.shortDescription} - a.course__link(href=`/courses/${course.fields.slug}`) view more + a(href=`categories/${category.fields.slug}`) #{category.title} + .course-card__title + h2= course.fields.title + .course-card__description + p= course.fields.shortDescription + .course-card__link + a(href=`/courses/${course.fields.slug}`) view course diff --git a/views/mixins/_highlightedCourse.pug b/views/mixins/_highlightedCourse.pug index 70315ce..766fbba 100644 --- a/views/mixins/_highlightedCourse.pug +++ b/views/mixins/_highlightedCourse.pug @@ -4,4 +4,4 @@ mixin highlightedCourseModule(module) .module .module__higlightedCourse h1.module__higlightedCourse__title #{module.fields.title} - +courseCard(module.course) + +courseCard(module.fields.course) diff --git a/views/settings.pug b/views/settings.pug index 737d548..b0fae9f 100644 --- a/views/settings.pug +++ b/views/settings.pug @@ -1,12 +1,13 @@ extends layout block content - h1= title - form(action=`/settings` method="POST" class="form") - label(for="space") Space - input(type="text" name="space" value=settings.space) - label(for="cda") Delivery API Key - input(type="text" name="cda" value=settings.cda) - label(for="cpa") Preview API Key - input(type="text" name="cpa" value=settings.cpa) - input(type="submit" value="Save →" class="button") + .wrapper + h1= title + form(action=`/settings` method="POST" class="form") + label(for="space") Space + input(type="text" name="space" value=settings.space) + label(for="cda") Delivery API Key + input(type="text" name="cda" value=settings.cda) + label(for="cpa") Preview API Key + input(type="text" name="cpa" value=settings.cpa) + input(type="submit" value="Save →" class="button") diff --git a/views/sitemap.pug b/views/sitemap.pug index 3d63b9a..208cbad 100644 --- a/views/sitemap.pug +++ b/views/sitemap.pug @@ -1,5 +1,6 @@ extends layout block content - h1= title - p Welcome to #{title} + .wrapper + h1= title + p Welcome to #{title}