├── docs
├── CNAME
├── robots.txt
├── image
│ ├── bg_grid.png
│ ├── og-img.png
│ ├── bg_slash.png
│ ├── img_visual.png
│ ├── favicon-96x96.png
│ ├── img_payment_detail.png
│ ├── bg_dot.svg
│ ├── wave.svg
│ ├── img_bubble_deco.svg
│ ├── grey_bg.svg
│ ├── theme_light_red_bg.svg
│ ├── theme_light_blue_bg.svg
│ ├── img_visual_light.svg
│ ├── red_line_bg.svg
│ ├── index_portrait_1.svg
│ ├── img_features.svg
│ ├── img_project_2.svg
│ ├── img_cta_bg.svg
│ ├── index_portrait_2.svg
│ ├── img_project_1.svg
│ ├── theme_light_character.svg
│ ├── img_apply.svg
│ ├── theme_dark_character.svg
│ └── img_student_experence.svg
├── webfonts
│ ├── fa-brands-400.eot
│ ├── fa-brands-400.ttf
│ ├── fa-brands-400.woff
│ ├── fa-solid-900.eot
│ ├── fa-solid-900.ttf
│ ├── fa-solid-900.woff
│ ├── fa-solid-900.woff2
│ ├── fa-brands-400.woff2
│ ├── fa-solid-900.css
│ └── fa-brands-400.css
├── sitemap.xml
└── humans.txt
├── src
├── statics
│ ├── CNAME
│ ├── robots.txt
│ ├── sitemap.xml
│ └── humans.txt
├── html
│ ├── layout
│ │ ├── banner.pug
│ │ ├── ga.pug
│ │ ├── header.pug
│ │ ├── layout.pug
│ │ └── footer.pug
│ ├── mixin
│ │ └── _mixin.pug
│ └── faq.pug
├── image
│ ├── bg_grid.png
│ ├── bg_slash.png
│ ├── og-img.png
│ ├── img_visual.png
│ ├── favicon-96x96.png
│ ├── img_payment_detail.png
│ ├── bg_dot.svg
│ ├── wave.svg
│ ├── grey_bg.svg
│ ├── theme_light_blue_bg.svg
│ ├── theme_light_red_bg.svg
│ ├── sprite
│ │ ├── logo_lidemy.svg
│ │ ├── icon_arrow_right.svg
│ │ ├── icon_arrow_right_blue.svg
│ │ ├── icon_arrow_right_red.svg
│ │ ├── icon_avatar_4.svg
│ │ ├── img_about_teacher_left.svg
│ │ ├── icon_avatar_2.svg
│ │ ├── icon_avatar_1.svg
│ │ ├── icon_avatar_3.svg
│ │ ├── icon_methods_2.svg
│ │ ├── icon_methods_3.svg
│ │ ├── img_about_teacher.svg
│ │ └── icon_methods_1.svg
│ ├── img_bubble_deco.svg
│ ├── img_visual_light.svg
│ ├── red_line_bg.svg
│ ├── index_portrait_1.svg
│ ├── img_features.svg
│ ├── img_project_2.svg
│ ├── index_portrait_2.svg
│ ├── img_project_1.svg
│ ├── img_cta_bg.svg
│ ├── theme_light_character.svg
│ ├── img_apply.svg
│ ├── theme_dark_character.svg
│ └── img_student_experence.svg
├── webfonts
│ ├── fa-solid-900.ttf
│ └── fa-brands-400.ttf
├── js
│ ├── index.js
│ ├── parallax.js
│ ├── bundle
│ │ ├── faq.js
│ │ ├── clipboard.js
│ │ └── chart.js
│ ├── throttle.js
│ ├── layout.js
│ └── header.js
└── scss
│ ├── _config.scss
│ ├── font-awesome
│ └── scss
│ │ ├── _fixed-width.scss
│ │ ├── _screen-reader.scss
│ │ ├── v4-shims.scss
│ │ ├── _animated.scss
│ │ ├── _list.scss
│ │ ├── _core.scss
│ │ ├── _larger.scss
│ │ ├── fontawesome.scss
│ │ ├── _bordered-pulled.scss
│ │ ├── _stacked.scss
│ │ ├── brands.scss
│ │ ├── solid.scss
│ │ ├── regular.scss
│ │ ├── _rotated-flipped.scss
│ │ └── _mixins.scss
│ ├── layout
│ ├── _banner.scss
│ ├── _cta_block.scss
│ ├── _footer.scss
│ └── _header.scss
│ ├── _variables.scss
│ ├── _reset.scss
│ ├── main.scss
│ ├── _mixin.scss
│ ├── _layout.scss
│ ├── sprite
│ └── view
│ │ └── _sprite.scss
│ ├── page
│ └── _faq.scss
│ └── _element.scss
├── .babelrc
├── .gitignore
├── README.md
├── minfont.js
├── package.json
└── gulpfile.js
/docs/CNAME:
--------------------------------------------------------------------------------
1 | bootcamp.lidemy.com
--------------------------------------------------------------------------------
/src/statics/CNAME:
--------------------------------------------------------------------------------
1 | bootcamp.lidemy.com
--------------------------------------------------------------------------------
/docs/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
--------------------------------------------------------------------------------
/src/statics/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/preset-env"
4 | ]
5 | }
--------------------------------------------------------------------------------
/src/html/layout/banner.pug:
--------------------------------------------------------------------------------
1 | section.banner
2 | p.fixed_info 🎉 第五期報名已截止 🎉
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | public/
3 | node_modules/
4 | build/
5 | src/scss/sprite/
--------------------------------------------------------------------------------
/docs/image/bg_grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/image/bg_grid.png
--------------------------------------------------------------------------------
/docs/image/og-img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/image/og-img.png
--------------------------------------------------------------------------------
/src/image/bg_grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/src/image/bg_grid.png
--------------------------------------------------------------------------------
/src/image/bg_slash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/src/image/bg_slash.png
--------------------------------------------------------------------------------
/src/image/og-img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/src/image/og-img.png
--------------------------------------------------------------------------------
/docs/image/bg_slash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/image/bg_slash.png
--------------------------------------------------------------------------------
/src/image/img_visual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/src/image/img_visual.png
--------------------------------------------------------------------------------
/docs/image/img_visual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/image/img_visual.png
--------------------------------------------------------------------------------
/src/image/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/src/image/favicon-96x96.png
--------------------------------------------------------------------------------
/docs/image/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/image/favicon-96x96.png
--------------------------------------------------------------------------------
/src/webfonts/fa-solid-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/src/webfonts/fa-solid-900.ttf
--------------------------------------------------------------------------------
/docs/webfonts/fa-brands-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/webfonts/fa-brands-400.eot
--------------------------------------------------------------------------------
/docs/webfonts/fa-brands-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/webfonts/fa-brands-400.ttf
--------------------------------------------------------------------------------
/docs/webfonts/fa-brands-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/webfonts/fa-brands-400.woff
--------------------------------------------------------------------------------
/docs/webfonts/fa-solid-900.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/webfonts/fa-solid-900.eot
--------------------------------------------------------------------------------
/docs/webfonts/fa-solid-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/webfonts/fa-solid-900.ttf
--------------------------------------------------------------------------------
/docs/webfonts/fa-solid-900.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/webfonts/fa-solid-900.woff
--------------------------------------------------------------------------------
/docs/webfonts/fa-solid-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/webfonts/fa-solid-900.woff2
--------------------------------------------------------------------------------
/src/image/img_payment_detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/src/image/img_payment_detail.png
--------------------------------------------------------------------------------
/src/js/index.js:
--------------------------------------------------------------------------------
1 | import layout from './layout'
2 | import header from './header'
3 | import parallax from './parallax'
--------------------------------------------------------------------------------
/src/webfonts/fa-brands-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/src/webfonts/fa-brands-400.ttf
--------------------------------------------------------------------------------
/docs/image/img_payment_detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/image/img_payment_detail.png
--------------------------------------------------------------------------------
/docs/webfonts/fa-brands-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Lidemy/mtr-4th-web/HEAD/docs/webfonts/fa-brands-400.woff2
--------------------------------------------------------------------------------
/src/js/parallax.js:
--------------------------------------------------------------------------------
1 | import Rellax from 'rellax';
2 |
3 | if (document.querySelector('.rellax')) {
4 | var rellax = new Rellax('.rellax');
5 | }
6 |
--------------------------------------------------------------------------------
/src/scss/_config.scss:
--------------------------------------------------------------------------------
1 | // rfs: https://github.com/twbs/rfs
2 | $rfs-base-value: 15;
3 | $rfs-breakpoint-unit: px;
4 | $rfs-breakpoint: 1000;
5 | $rfs-factor: 100;
--------------------------------------------------------------------------------
/docs/image/bg_dot.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | text-align: center;
5 | width: $fa-fw-width;
6 | }
7 |
--------------------------------------------------------------------------------
/src/image/bg_dot.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only; }
5 | .sr-only-focusable { @include sr-only-focusable; }
6 |
--------------------------------------------------------------------------------
/docs/image/wave.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/js/bundle/faq.js:
--------------------------------------------------------------------------------
1 | import $ from 'jquery';
2 |
3 | $(document).ready(function () {
4 | $(".faq__list__item-link").click(function (e) {
5 | e.preventDefault()
6 | $(this).closest(".faq__list__item").toggleClass("active").siblings().removeClass("active")
7 | })
8 | });
9 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/v4-shims.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @import 'variables';
6 | @import 'shims';
7 |
--------------------------------------------------------------------------------
/src/image/wave.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/docs/image/img_bubble_deco.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/html/layout/ga.pug:
--------------------------------------------------------------------------------
1 | mixin ga(id)
2 | script(async='', src='https://www.googletagmanager.com/gtag/js?id='+id)
3 | script.
4 | window.dataLayer = window.dataLayer || [];
5 | function gtag(){dataLayer.push(arguments);}
6 | gtag('js', new Date());
7 | gtag('config', '!{id}')
--------------------------------------------------------------------------------
/docs/image/grey_bg.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/image/theme_light_red_bg.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/image/theme_light_blue_bg.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/image/grey_bg.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/image/theme_light_blue_bg.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/image/theme_light_red_bg.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/scss/layout/_banner.scss:
--------------------------------------------------------------------------------
1 | /* banner -------------------- */
2 | .banner {
3 | width: 100%;
4 | height: 40px;
5 | background: #795548;
6 | position: fixed;
7 | bottom: 0;
8 | left: 0;
9 | display: flex;
10 | align-items: center;
11 | justify-content: center;
12 | z-index: 5;
13 | .fixed_info {
14 | color: white;
15 | margin: 0;
16 | }
17 | }
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | animation: fa-spin 2s infinite linear;
6 | }
7 |
8 | .#{$fa-css-prefix}-pulse {
9 | animation: fa-spin 1s infinite steps(8);
10 | }
11 |
12 | @keyframes fa-spin {
13 | 0% {
14 | transform: rotate(0deg);
15 | }
16 |
17 | 100% {
18 | transform: rotate(360deg);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | list-style-type: none;
6 | margin-left: $fa-li-width * 5/4;
7 | padding-left: 0;
8 |
9 | > li { position: relative; }
10 | }
11 |
12 | .#{$fa-css-prefix}-li {
13 | left: -$fa-li-width;
14 | position: absolute;
15 | text-align: center;
16 | width: $fa-li-width;
17 | line-height: inherit;
18 | }
19 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix},
5 | .fas,
6 | .far,
7 | .fal,
8 | .fad,
9 | .fab {
10 | -moz-osx-font-smoothing: grayscale;
11 | -webkit-font-smoothing: antialiased;
12 | display: inline-block;
13 | font-style: normal;
14 | font-variant: normal;
15 | text-rendering: auto;
16 | line-height: 1;
17 | }
18 |
19 | %fa-icon {
20 | @include fa-icon;
21 | }
22 |
--------------------------------------------------------------------------------
/src/image/sprite/logo_lidemy.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/image/img_bubble_deco.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/docs/image/img_visual_light.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | // makes the font 33% larger relative to the icon container
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -.0667em;
9 | }
10 |
11 | .#{$fa-css-prefix}-xs {
12 | font-size: .75em;
13 | }
14 |
15 | .#{$fa-css-prefix}-sm {
16 | font-size: .875em;
17 | }
18 |
19 | @for $i from 1 through 10 {
20 | .#{$fa-css-prefix}-#{$i}x {
21 | font-size: $i * 1em;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/fontawesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @import 'variables';
6 | @import 'mixins';
7 | @import 'core';
8 | @import 'larger';
9 | @import 'fixed-width';
10 | @import 'list';
11 | @import 'bordered-pulled';
12 | @import 'animated';
13 | @import 'rotated-flipped';
14 | @import 'stacked';
15 | @import 'icons';
16 | @import 'screen-reader';
17 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | border: solid .08em $fa-border-color;
6 | border-radius: .1em;
7 | padding: .2em .25em .15em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix},
14 | .fas,
15 | .far,
16 | .fal,
17 | .fab {
18 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
19 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
20 | }
21 |
--------------------------------------------------------------------------------
/docs/webfonts/fa-solid-900.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: "Font Awesome 5 Free Solid";
3 | src: url("fa-solid-900.eot"); /* IE9 */
4 | src: url("fa-solid-900.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
5 | url("fa-solid-900.woff") format("woff"), /* chrome, firefox */
6 | url("fa-solid-900.ttf") format("truetype"), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
7 | url("fa-solid-900.svg#Font Awesome 5 Free Solid") format("svg"); /* iOS 4.1- */
8 | font-style: normal;
9 | font-weight: normal;
10 | }
11 |
12 |
13 |
--------------------------------------------------------------------------------
/docs/webfonts/fa-brands-400.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: "Font Awesome 5 Brands Regular";
3 | src: url("fa-brands-400.eot"); /* IE9 */
4 | src: url("fa-brands-400.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
5 | url("fa-brands-400.woff") format("woff"), /* chrome, firefox */
6 | url("fa-brands-400.ttf") format("truetype"), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
7 | url("fa-brands-400.svg#Font Awesome 5 Brands Regular") format("svg"); /* iOS 4.1- */
8 | font-style: normal;
9 | font-weight: normal;
10 | }
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/js/throttle.js:
--------------------------------------------------------------------------------
1 | export default function throttle(func, limit) {
2 | let lastFunc
3 | let lastRan
4 | return function() {
5 | const context = this
6 | const args = arguments
7 | if (!lastRan) {
8 | func.apply(context, args)
9 | lastRan = Date.now()
10 | } else {
11 | clearTimeout(lastFunc)
12 | lastFunc = setTimeout(function() {
13 | if ((Date.now() - lastRan) >= limit) {
14 | func.apply(context, args)
15 | lastRan = Date.now()
16 | }
17 | }, limit - (Date.now() - lastRan))
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/src/scss/_variables.scss:
--------------------------------------------------------------------------------
1 | // main color
2 | $main-color: #ca4141;
3 | $main-color-dark: #B53939;
4 | $main-bg-Color: #f8f8f8;
5 | $sub-color: #18A0FB;
6 | $logo-color: #eb2629;
7 | $shadow-color: rgba(0, 0, 0, 0.1);
8 |
9 | $color-theme-light: #f5ebeb;
10 | $color-theme-dark: #4F3F43;
11 |
12 | $grey: #666;
13 | $grey-dark: #333;
14 | $grey-light: #999;
15 |
16 | // width
17 | $width-desktop-xl: 1440px;
18 | $width-desktop-l: 1200px;
19 | $width-desktop-m: 1080px;
20 | $width-desktop-s: 900px;
21 |
22 | $width-tablet: 768px;
23 | $width-tablet-s: 640px;
24 |
25 | $width-mobile-l: 480px;
26 | $width-mobile-m: 414px;
27 | $width-mobile-s: 375px;
28 | $width-mobile-xs: 320px;
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | display: inline-block;
6 | height: 2em;
7 | line-height: 2em;
8 | position: relative;
9 | vertical-align: middle;
10 | width: ($fa-fw-width*2);
11 | }
12 |
13 | .#{$fa-css-prefix}-stack-1x,
14 | .#{$fa-css-prefix}-stack-2x {
15 | left: 0;
16 | position: absolute;
17 | text-align: center;
18 | width: 100%;
19 | }
20 |
21 | .#{$fa-css-prefix}-stack-1x {
22 | line-height: inherit;
23 | }
24 |
25 | .#{$fa-css-prefix}-stack-2x {
26 | font-size: 2em;
27 | }
28 |
29 | .#{$fa-css-prefix}-inverse {
30 | color: $fa-inverse;
31 | }
32 |
--------------------------------------------------------------------------------
/docs/image/red_line_bg.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/html/mixin/_mixin.pug:
--------------------------------------------------------------------------------
1 | mixin common_title(title, id, alignType='center')
2 | h3.common__title(class=`${alignType}`)
3 | a(href=`#${id}`)= title
4 |
5 | mixin post_item(title, id, theme)
6 | section.section.post(class=`${id} ${theme ? theme : ''}`)
7 | +common_title(title, id, 'left')
8 | .post__content
9 | block
10 |
11 | mixin cta_block(leftText, leftLink, rightText, rightLink)
12 | section.section.cta.lazy(data-bg="image/img_cta_bg.svg")
13 | h3.cta__title 想要一起來學習程式嗎?
14 | p.cta__content 第五期現正招生中,到三月底截止,強烈建議你先把官網的資訊都看完,全盤了解過後再做決定,有任何問題都可以透過 Lidemy 粉絲專頁與我們聯絡!
15 | .cta__operate
16 | a(href=`${leftLink}`).cta__button.cta__button-apply= leftText
17 | a(href=`${rightLink}`).cta__button.cta__button-mail= rightText
--------------------------------------------------------------------------------
/src/image/img_visual_light.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/js/bundle/clipboard.js:
--------------------------------------------------------------------------------
1 | import boostrap from 'bootstrap';
2 | import $ from 'jquery';
3 | import ClipboardJS from 'clipboard';
4 |
5 | $('[data-toggle="tooltip"]').tooltip()
6 |
7 | function setTooltip(btn, message) {
8 | $(btn).tooltip('hide')
9 | .attr('data-original-title', message)
10 | .tooltip('show');
11 | }
12 |
13 | function hideTooltip(btn) {
14 | setTimeout(function () {
15 | $(btn)
16 | .attr('data-original-title', 'Copy me')
17 | .tooltip('hide');
18 | }, 1000);
19 | }
20 |
21 | const clipboard = new ClipboardJS('.copy__btn');
22 |
23 | clipboard.on('success', function (e) {
24 | setTooltip(e.trigger, 'Copied!');
25 | hideTooltip(e.trigger);
26 | })
27 |
28 | clipboard.on('error', function (e) {
29 | setTooltip(e.trigger, 'Failed!');
30 | hideTooltip(e.trigger);
31 | });
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Lidemy 程式導師實驗計畫第四期
2 |
3 | 不喊口號也不誇大成效,開放透明的前後端線上學習計畫。
4 |
5 | 用六個月的時間,培養出一個找得到工作且基礎紮實的網頁工程師。
6 |
7 | 課綱:https://github.com/Lidemy/mentor-program-4th
8 |
9 |
10 | 
11 |
12 | ---
13 |
14 | ## Install
15 |
16 | ```
17 | $ npm install
18 | ```
19 |
20 |
21 | ## Usage
22 |
23 | ### ✏️ dev
24 |
25 | ```
26 | npm run dev
27 | ```
28 |
29 | ### ✏️ production
30 |
31 | ```
32 | npm run build
33 | ```
34 |
35 | ### optimize webfont
36 |
37 | We defined every font-awesome class we used in `minfont.js` and get this unicode from `src/scss/font-awesome/scss/_variables.scss`. After we have unicodes, we can use [gulp-fontmin](https://www.npmjs.com/package/gulp-fontmin-woff2) to reduce the size of font file.
38 |
39 | Be careful if you want to use new icon, you must add the class name to `minfont.js`
40 |
--------------------------------------------------------------------------------
/src/html/layout/header.pug:
--------------------------------------------------------------------------------
1 | header.header
2 | .header__content
3 | .header__logo
4 | a.header__logo-img(href="/", aria-label="Home")
5 | i(class="fas fa-bars header__responsive__icon")
6 | nav.header__nav
7 | ul
8 | -
9 | var navs = [
10 | { name: "首頁", src: "index" },
11 | { name: "計畫介紹", src: "introduce" },
12 | { name: "課程大綱", src: "syllabus" },
13 | { name: "教學成果", src: "achievement" },
14 | { name: "課程資訊", src: "course-info" },
15 | { name: "FAQ", src: "faq" }
16 | ];
17 | each item in navs
18 | li(class= (currentUrl === item.src ? 'current' : ''))
19 | a(href= (item.src === 'index' ? '/' : item.src + '.html'))= item.name
20 | a.header__cta-btn(href="course-info.html") 了解報名資訊
--------------------------------------------------------------------------------
/src/image/red_line_bg.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/scss/_reset.scss:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: border-box;
5 | letter-spacing: 0.02rem;
6 | font-family: 'Work Sans','Noto Sans TC', '微軟正黑體', Arial, Helvetica, sans-serif;
7 | }
8 |
9 | ul {
10 | list-style: none;
11 | margin: 0;
12 | }
13 |
14 | a, button {
15 | text-decoration: none;
16 | color: inherit;
17 | border: none;
18 | outline: none;
19 | &:hover {
20 | text-decoration: none;
21 | color: $main-color;
22 | }
23 | }
24 |
25 | p {
26 | line-height: 1.8rem;
27 | letter-spacing: 0.04rem;
28 | margin-bottom: 0.5rem;
29 | color: #999;
30 |
31 | strong {
32 | color: #333;
33 | }
34 |
35 | a {
36 | border-bottom: 1px dotted #999;
37 | color: #000;
38 |
39 | &:hover {
40 | color: $main-color;
41 | }
42 | }
43 | }
44 |
45 | code {
46 | font-size: 13px;
47 | color: lighten($main-color, 5%);
48 | }
49 |
--------------------------------------------------------------------------------
/src/scss/main.scss:
--------------------------------------------------------------------------------
1 |
2 | @import './_config.scss';
3 |
4 | @import 'node_modules/bootstrap/scss/bootstrap';
5 |
6 | @import './sprite/view/_sprite.scss';
7 | @import './_variables.scss';
8 |
9 | @import './font-awesome/scss/fontawesome.scss';
10 | @import './font-awesome/scss/solid.scss';
11 | @import './font-awesome/scss/brands.scss';
12 |
13 | @import './_reset.scss';
14 | @import './_mixin.scss';
15 | @import './_layout.scss';
16 | @import './_element.scss';
17 |
18 | @import '../../node_modules/rfs/scss';
19 |
20 | @import './layout/_header.scss';
21 | @import './layout/_footer.scss';
22 | @import './layout/_cta_block.scss';
23 | @import './layout/_banner.scss';
24 |
25 | @import './page/_index.scss';
26 | @import './page/_faq.scss';
27 | @import './page/_course-info.scss';
28 | @import './page/_achievement.scss';
29 | @import './page/_introduce.scss';
30 | @import './page/_syllabus.scss';
31 |
32 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/brands.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @import 'variables';
6 |
7 | @font-face {
8 | font-family: 'Font Awesome 5 Brands';
9 | font-style: normal;
10 | font-weight: 400;
11 | font-display: $fa-font-display;
12 | src: url('#{$fa-font-path}/fa-brands-400.eot');
13 | src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'),
14 | url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'),
15 | url('#{$fa-font-path}/fa-brands-400.woff') format('woff'),
16 | url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'),
17 | url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg');
18 | }
19 |
20 | .fab {
21 | font-family: 'Font Awesome 5 Brands';
22 | font-weight: 400;
23 | }
24 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/solid.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @import 'variables';
6 |
7 | @font-face {
8 | font-family: 'Font Awesome 5 Free';
9 | font-style: normal;
10 | font-weight: 900;
11 | font-display: $fa-font-display;
12 | src: url('#{$fa-font-path}/fa-solid-900.eot');
13 | src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'),
14 | url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'),
15 | url('#{$fa-font-path}/fa-solid-900.woff') format('woff'),
16 | url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'),
17 | url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg');
18 | }
19 |
20 | .fa,
21 | .fas {
22 | font-family: 'Font Awesome 5 Free';
23 | font-weight: 900;
24 | }
25 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/regular.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @import 'variables';
6 |
7 | @font-face {
8 | font-family: 'Font Awesome 5 Free';
9 | font-style: normal;
10 | font-weight: 400;
11 | font-display: $fa-font-display;
12 | src: url('#{$fa-font-path}/fa-regular-400.eot');
13 | src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'),
14 | url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'),
15 | url('#{$fa-font-path}/fa-regular-400.woff') format('woff'),
16 | url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'),
17 | url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg');
18 | }
19 |
20 | .far {
21 | font-family: 'Font Awesome 5 Free';
22 | font-weight: 400;
23 | }
24 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 | .#{$fa-css-prefix}-flip-both, .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); }
11 |
12 | // Hook for IE8-9
13 | // -------------------------
14 |
15 | :root {
16 | .#{$fa-css-prefix}-rotate-90,
17 | .#{$fa-css-prefix}-rotate-180,
18 | .#{$fa-css-prefix}-rotate-270,
19 | .#{$fa-css-prefix}-flip-horizontal,
20 | .#{$fa-css-prefix}-flip-vertical,
21 | .#{$fa-css-prefix}-flip-both {
22 | filter: none;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/scss/layout/_cta_block.scss:
--------------------------------------------------------------------------------
1 | .cta {
2 | max-width: $width-desktop-s;
3 | text-align: center;
4 | padding: 70px 20px;
5 |
6 | background-position: 0 165px;
7 | background-repeat: no-repeat;
8 | background-size: 230px auto;
9 |
10 | &__title {
11 | @include font-size(26px);
12 | margin-bottom: 1rem;
13 | }
14 |
15 | &__content {
16 | @include font-size(14px);
17 | max-width: 500px;
18 | margin: 0 auto 1rem;
19 | }
20 | }
21 |
22 | @include mq('tablet') {
23 | .cta {
24 | padding-bottom: 130px;
25 | background-position: center 250px;
26 | }
27 | }
28 | @include mq('mobile-s') {
29 | .cta {
30 | padding-bottom: 150px;
31 | background-position: center 350px;
32 |
33 | &__button {
34 | width: 100%;
35 | margin-bottom: 0.5rem;
36 | }
37 | }
38 | }
39 |
40 | .cta__button {
41 | @include button_1($withIcon: true);
42 | color: white;
43 | &:not(:nth-last-of-type(1)) {
44 | margin-right: 10px;
45 | }
46 |
47 | &-mail {
48 | background: darken($grey, 15);
49 | &:hover {
50 | background: darken($grey, 25);
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/src/js/layout.js:
--------------------------------------------------------------------------------
1 | import throttle from './throttle';
2 | import smoothscroll from 'smoothscroll-polyfill';
3 | import LazyLoad from "vanilla-lazyload";
4 |
5 | // Support safari scroll behavior
6 | smoothscroll.polyfill();
7 |
8 | function scrollToOffset(e, offset) {
9 | e.preventDefault();
10 |
11 | if ('top' === offset) {
12 | offset = 0;
13 | } else if (!offset) {
14 | const url = location.hash.substr(1);
15 | if (!url) return
16 |
17 | offset = document.querySelector(`.${url}`).offsetTop - 120;
18 | }
19 |
20 | window.scrollTo({
21 | top: offset,
22 | left: 0,
23 | behavior: 'smooth'
24 | });
25 | }
26 |
27 | const btnScroll = document.querySelector(".scroll-top-btn");
28 |
29 | // Add scroll throttle
30 | window.addEventListener('scroll', throttle(function() {
31 | if (window.pageYOffset > 900) {
32 | btnScroll.classList.remove("content-invisible")
33 | } else {
34 | btnScroll.classList.add("content-invisible")
35 | }
36 | }, 500))
37 |
38 | // Add event listener
39 | window.addEventListener('DOMContentLoaded', scrollToOffset);
40 | window.addEventListener('hashchange', scrollToOffset);
41 | btnScroll.addEventListener('click', function(e) { scrollToOffset(e, 'top') })
42 |
43 |
44 | var ll = new LazyLoad({
45 | elements_selector: ".lazy"
46 | });
--------------------------------------------------------------------------------
/docs/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | https://bootcamp.lidemy.com/index.html
12 | 2020-04-29T04:30:42+00:00
13 | 1.00
14 |
15 |
16 | https://bootcamp.lidemy.com/introduce.html
17 | 2020-04-29T04:30:42+00:00
18 | 0.80
19 |
20 |
21 | https://bootcamp.lidemy.com/syllabus.html
22 | 2020-04-29T04:30:42+00:00
23 | 0.80
24 |
25 |
26 | https://bootcamp.lidemy.com/achievement.html
27 | 2020-04-29T04:30:42+00:00
28 | 0.80
29 |
30 |
31 | https://bootcamp.lidemy.com/course-info.html
32 | 2020-04-29T04:30:42+00:00
33 | 0.80
34 |
35 |
36 | https://bootcamp.lidemy.com/faq.html
37 | 2020-04-29T04:30:42+00:00
38 | 0.80
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/statics/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | https://bootcamp.lidemy.com/index.html
12 | 2020-04-29T04:30:42+00:00
13 | 1.00
14 |
15 |
16 | https://bootcamp.lidemy.com/introduce.html
17 | 2020-04-29T04:30:42+00:00
18 | 0.80
19 |
20 |
21 | https://bootcamp.lidemy.com/syllabus.html
22 | 2020-04-29T04:30:42+00:00
23 | 0.80
24 |
25 |
26 | https://bootcamp.lidemy.com/achievement.html
27 | 2020-04-29T04:30:42+00:00
28 | 0.80
29 |
30 |
31 | https://bootcamp.lidemy.com/course-info.html
32 | 2020-04-29T04:30:42+00:00
33 | 0.80
34 |
35 |
36 | https://bootcamp.lidemy.com/faq.html
37 | 2020-04-29T04:30:42+00:00
38 | 0.80
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/image/sprite/icon_arrow_right.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/scss/font-awesome/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | @mixin fa-icon {
5 | -webkit-font-smoothing: antialiased;
6 | -moz-osx-font-smoothing: grayscale;
7 | display: inline-block;
8 | font-style: normal;
9 | font-variant: normal;
10 | font-weight: normal;
11 | line-height: 1;
12 | }
13 |
14 | @mixin fa-icon-rotate($degrees, $rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
16 | transform: rotate($degrees);
17 | }
18 |
19 | @mixin fa-icon-flip($horiz, $vert, $rotation) {
20 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
21 | transform: scale($horiz, $vert);
22 | }
23 |
24 |
25 | // Only display content to screen readers. A la Bootstrap 4.
26 | //
27 | // See: http://a11yproject.com/posts/how-to-hide-content/
28 |
29 | @mixin sr-only {
30 | border: 0;
31 | clip: rect(0, 0, 0, 0);
32 | height: 1px;
33 | margin: -1px;
34 | overflow: hidden;
35 | padding: 0;
36 | position: absolute;
37 | width: 1px;
38 | }
39 |
40 | // Use in conjunction with .sr-only to only display content when it's focused.
41 | //
42 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
43 | //
44 | // Credit: HTML5 Boilerplate
45 |
46 | @mixin sr-only-focusable {
47 | &:active,
48 | &:focus {
49 | clip: auto;
50 | height: auto;
51 | margin: 0;
52 | overflow: visible;
53 | position: static;
54 | width: auto;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/image/sprite/icon_arrow_right_blue.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/image/sprite/icon_arrow_right_red.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/js/header.js:
--------------------------------------------------------------------------------
1 | import throttle from './throttle'
2 |
3 | let timer;
4 | let header = document.querySelector('.header')
5 | let headerContent = document.querySelectorAll(
6 | '.header__cta-btn, .header__nav'
7 | )
8 |
9 | function setShrinkHeader() {
10 | clearTimeout(timer)
11 |
12 | if (window.pageYOffset > 120) {
13 | header.classList.add('is-shrunk')
14 | headerContent.forEach((content) => {
15 | content.classList.add('content-invisible')
16 | })
17 | } else {
18 | header.classList.remove('is-shrunk')
19 | timer = setTimeout(function () {
20 | headerContent.forEach((content) => {
21 | content.classList.remove('content-invisible')
22 | })
23 | }, 50)
24 | }
25 | }
26 |
27 | function openMenu() {
28 | // mobile menu open
29 | header.classList.toggle('menu-opened')
30 |
31 | // desktop nav shrink
32 | header.classList.toggle('is-shrunk')
33 | const isheaderShrunk = header.classList.contains('is-shrunk')
34 |
35 | if (isheaderShrunk) {
36 | headerContent.forEach((content) => {
37 | content.classList.add('content-invisible')
38 | })
39 | } else {
40 | setTimeout(function () {
41 | headerContent.forEach((content) => {
42 | content.classList.remove('content-invisible')
43 | })
44 | }, 50)
45 | }
46 | }
47 |
48 | document.addEventListener('scroll', throttle(setShrinkHeader, 200))
49 | document.querySelector(".header__responsive__icon").addEventListener('click', openMenu)
50 | window.addEventListener('pageshow', function(e) {
51 | if (e.persisted) {
52 | header.classList.remove('menu-opened')
53 | }
54 | })
55 |
--------------------------------------------------------------------------------
/minfont.js:
--------------------------------------------------------------------------------
1 | // grep -Ri "fa-*" ./src/scss
2 | const fs = require('fs')
3 | const fas = `
4 | fa-volume-up
5 | fa-thumbs-up
6 | fa-globe-americas
7 | fa-database
8 | fa-tools
9 | fa-server
10 | fa-chart-line
11 | fa-shield-alt
12 | fa-code-branch
13 | fa-chalkboard-teacher
14 | fa-eye
15 | fa-bars
16 | fa-external-link-alt
17 | fa-chevron-up
18 | fa-check
19 | fa-user-circle
20 | fa-arrow-right
21 | fa-arrow-down
22 | fa-arrow-up
23 | fa-calendar-alt
24 | fa-stream
25 | fa-check-square
26 | fa-arrow-alt-circle-right
27 | fa-copy
28 | fa-long-arrow-alt-right
29 | `.split('\n').filter(n => n)
30 |
31 | const fab = `
32 | fa-github
33 | fa-facebook-square
34 | fa-medium
35 | fa-react
36 | fa-js
37 | fa-html5
38 | fa-css3-alt
39 | fa-chrome
40 | fa-php
41 | `.split('\n').filter(n => n)
42 |
43 | const cssContent = fs.readFileSync('./src/scss/font-awesome/scss/_variables.scss', 'utf8')
44 | function getUnicode(classNames) {
45 | let unicodes = []
46 | let names = classNames.map(name => {
47 | return name.replace('fa-', 'fa-var-')
48 | })
49 | for(let name of names) {
50 | let result = cssContent.match(new RegExp(`${name}: (.*);`))
51 | if (result && result[1]) {
52 | console.log(name, result[1])
53 | unicodes.push(result[1].replace('\\', '\\u'))
54 | } else {
55 | throw new Error('Not found: ' + name)
56 | }
57 | }
58 | return unicodes
59 | }
60 |
61 | let fasCodes = getUnicode(fas)
62 | let fabCodes = getUnicode(fab)
63 |
64 | console.log('fas:')
65 | console.log(fasCodes.join(''))
66 | console.log('fab:')
67 | console.log(fabCodes.join(''))
68 | console.log('all:(copy this string to gulpfile.js)')
69 | console.log(fasCodes.join('') + fabCodes.join(''))
70 |
--------------------------------------------------------------------------------
/docs/image/index_portrait_1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/humans.txt:
--------------------------------------------------------------------------------
1 | ___ ___ ___ ___ ___
2 | /\__\ ___ /\ \ /\ \ /\__\ |\__\
3 | /:/ / /\ \ /::\ \ /::\ \ /::| | |:| |
4 | /:/ / \:\ \ /:/\:\ \ /:/\:\ \ /:|:| | |:| |
5 | /:/ / /::\__\ /:/ \:\__\ /::\~\:\ \ /:/|:|__|__ |:|__|__
6 | /:/__/ __/:/\/__/ /:/__/ \:|__| /:/\:\ \:\__\ /:/ |::::\__\ /::::\__\
7 | \:\ \ /\/:/ / \:\ \ /:/ / \:\~\:\ \/__/ \/__/~~/:/ / /:/~~/~
8 | \:\ \ \::/__/ \:\ /:/ / \:\ \:\__\ /:/ / /:/ /
9 | \:\ \ \:\__\ \:\/:/ / \:\ \/__/ /:/ / \/__/
10 | \:\__\ \/__/ \::/__/ \:\__\ /:/ /
11 | \/__/ ~~ \/__/ \/__/
12 |
13 | ASCII generated by http://www.network-science.de/ascii/
14 |
15 | 恭喜你找到這邊來 (* ̄▽ ̄)/‧★*"`'*-.,_,.-*'`"*-.,_☆
16 | 底下是這個網站背後的團隊以及使用的技術
17 | 如果有任何問題,請聯絡 huli@lidemy.com
18 | 感謝 <(_ _)>
19 |
20 | ───────────────────────────────────────────────────────────────────────
21 |
22 | /* TEAM */
23 | Yakim (Designer, Developer)
24 | GitHub: https://github.com/yakim-shu
25 | Site: https://yakimhsu.com/
26 |
27 | Chih Yang (Developer)
28 | GitHub: https://github.com/ChihYang41
29 | Site: https://chihyang41.github.io/
30 |
31 | Minw (Support)
32 | GitHub: https://github.com/ishin4554
33 | Site: https://medium.com/@minw
34 |
35 | Huli (Support)
36 | GitHub: https://github.com/aszx87410
37 | Site: https://blog.huli.tw
38 |
39 | /* SITE */
40 | Technology: pug, scss, gulp, babel, browserify
41 | Image: font-awesome, Getillustrations
42 | Source code: https://github.com/Lidemy/mtr-4th-web
--------------------------------------------------------------------------------
/src/statics/humans.txt:
--------------------------------------------------------------------------------
1 | ___ ___ ___ ___ ___
2 | /\__\ ___ /\ \ /\ \ /\__\ |\__\
3 | /:/ / /\ \ /::\ \ /::\ \ /::| | |:| |
4 | /:/ / \:\ \ /:/\:\ \ /:/\:\ \ /:|:| | |:| |
5 | /:/ / /::\__\ /:/ \:\__\ /::\~\:\ \ /:/|:|__|__ |:|__|__
6 | /:/__/ __/:/\/__/ /:/__/ \:|__| /:/\:\ \:\__\ /:/ |::::\__\ /::::\__\
7 | \:\ \ /\/:/ / \:\ \ /:/ / \:\~\:\ \/__/ \/__/~~/:/ / /:/~~/~
8 | \:\ \ \::/__/ \:\ /:/ / \:\ \:\__\ /:/ / /:/ /
9 | \:\ \ \:\__\ \:\/:/ / \:\ \/__/ /:/ / \/__/
10 | \:\__\ \/__/ \::/__/ \:\__\ /:/ /
11 | \/__/ ~~ \/__/ \/__/
12 |
13 | ASCII generated by http://www.network-science.de/ascii/
14 |
15 | 恭喜你找到這邊來 (* ̄▽ ̄)/‧★*"`'*-.,_,.-*'`"*-.,_☆
16 | 底下是這個網站背後的團隊以及使用的技術
17 | 如果有任何問題,請聯絡 huli@lidemy.com
18 | 感謝 <(_ _)>
19 |
20 | ───────────────────────────────────────────────────────────────────────
21 |
22 | /* TEAM */
23 | Yakim (Designer, Developer)
24 | GitHub: https://github.com/yakim-shu
25 | Site: https://yakimhsu.com/
26 |
27 | Chih Yang (Developer)
28 | GitHub: https://github.com/ChihYang41
29 | Site: https://chihyang41.github.io/
30 |
31 | Minw (Support)
32 | GitHub: https://github.com/ishin4554
33 | Site: https://medium.com/@minw
34 |
35 | Huli (Support)
36 | GitHub: https://github.com/aszx87410
37 | Site: https://blog.huli.tw
38 |
39 | /* SITE */
40 | Technology: pug, scss, gulp, babel, browserify
41 | Image: font-awesome, Getillustrations
42 | Source code: https://github.com/Lidemy/mtr-4th-web
--------------------------------------------------------------------------------
/src/js/bundle/chart.js:
--------------------------------------------------------------------------------
1 | import Chart from 'chart.js';
2 |
3 | // options
4 | const options = {
5 | maintainAspectRatio: false,
6 | devicePixelRatio: 2,
7 | radius: 10,
8 | layout: {
9 | padding: {
10 | top: 20,
11 | }
12 | },
13 | legend: {
14 | align: 'center',
15 | position: 'top',
16 | fullWidth: false,
17 | labels: {
18 | fontColor: '#666',
19 | fontSize: 12,
20 | }
21 | },
22 | }
23 |
24 | // data
25 | const data = {
26 | labels: ['第四期','第三期', '第二期', '第一期'],
27 | scaleLabel: {
28 | labelString: '###'
29 | },
30 | datasets: [
31 | {
32 | label: '時限內求職成功人數',
33 | backgroundColor: '#D26B6B',
34 | hoverBackgroundColor: '#C25A5A',
35 | borderColor: '#FFD9D9',
36 | data: [21, 14, 8, 2],
37 | barThickness: 'flex',
38 | maxBarThickness: 30,
39 |
40 | },
41 | {
42 | label: '結業人數',
43 | backgroundColor: '#FC849A',
44 | hoverBackgroundColor: '#F28397',
45 | borderColor: '#E27474',
46 | data: [60, 39, 29, 3],
47 | barThickness: 'flex',
48 | maxBarThickness: 30,
49 | },
50 | {
51 | label: '學生總人數',
52 | backgroundColor: '#FFD2D2',
53 | hoverBackgroundColor: '#F6CCCC',
54 | borderColor: '#E27474',
55 | data: [77, 56, 38, 12],
56 | barThickness: 'flex',
57 | maxBarThickness: 30,
58 | },
59 | ]
60 | }
61 |
62 | const ctx = document.getElementById('chart').getContext('2d');
63 | const chart = new Chart(ctx, {
64 | type: 'horizontalBar', data, options,
65 | });
66 |
67 | let isTablet = false;
68 | const updateChartLayout = () => {
69 | if (window.innerWidth < 480) {
70 | if (isTablet) return
71 |
72 | chart.options.legend.align = 'start'
73 | chart.update()
74 | isTablet = true
75 |
76 | } else if (isTablet) {
77 |
78 | chart.options.legend.align = 'center'
79 | chart.update()
80 | isTablet = false
81 | }
82 | }
83 |
84 | // binding events
85 | ['resize', 'DOMContentLoaded'].forEach(function (item) {
86 | window.addEventListener(item, updateChartLayout);
87 | });
88 |
89 |
--------------------------------------------------------------------------------
/docs/image/img_features.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/html/layout/layout.pug:
--------------------------------------------------------------------------------
1 | -
2 | var meta = {
3 | url: 'https://bootcamp.lidemy.com',
4 | title: 'Lidemy 程式導師實驗計畫第五期',
5 | type: 'website',
6 | desc: '不喊口號也不誇大成效,開放透明的前後端線上學習計畫。 試著用六個月的時間,培養出一個找得到工作且基礎紮實的網頁工程師。',
7 | img_src: '/image/og-img.png?v=2',
8 | twitter_card: 'summary_large_image'
9 | }
10 |
11 | mixin head_block(headInfo)
12 | head
13 | meta(charset="UTF-8")
14 | meta(name="viewport" content="width=device-width, initial-scale=1.0")
15 | meta(name="Description" content= meta.desc)
16 | meta(http-equiv="X-UA-Compatible" content="IE=edge")
17 |
18 | meta(property="og:title" content= meta.title)
19 | meta(property="og:description" content= meta.desc)
20 | meta(property="og:image" content= meta.url + meta.img_src)
21 | meta(property="og:type" content= meta.type)
22 | meta(property="og:url" content= meta.url)
23 | meta(property="og:site_name" content= meta.title)
24 | meta(property="og:image:width" content="1200")
25 | meta(property="og:image:height" content="628")
26 |
27 | meta(name="twitter:card" content= meta.twitter_card)
28 | meta(name="twitter:title" content= meta.title)
29 | meta(name="twitter:description" content= meta.desc)
30 | meta(name="twitter:image" content= meta.url + meta.img_src)
31 |
32 | link(rel="author" type="text/plain" href="/humans.txt" )
33 | link(rel='stylesheet' href='css/main.min.css')
34 | link(rel="icon" type="image/png" sizes="96x96" href="./image/favicon-96x96.png")
35 | title #{headInfo.title} | Lidemy 程式導師實驗計畫第五期
36 |
37 | include ga.pug
38 | +ga('UA-77560722-2')
39 |
40 |
41 |
42 | // layout
43 | doctype html
44 | block current
45 | - var currentUrl
46 |
47 | html(lang='en')
48 | block head
49 | +head_block('default')
50 |
51 | body(class= (currentUrl === 'index' && 'theme-index'))
52 | block header
53 | include header.pug
54 | .wrapper
55 | block content
56 | button.scroll-top-btn.content-invisible(aria-label="scrollToTop")
57 | block footer
58 | include footer.pug
59 | block banner
60 | include banner.pug
61 |
62 | script(defer src="js/index.bundle.js")
63 | link(rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Work+Sans&display=swap")
64 |
65 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mtr-4th-web",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "gulpfile.js",
6 | "dependencies": {
7 | "@babel/runtime": "^7.9.2",
8 | "@popperjs/core": "^2.3.3",
9 | "autoprefixer": "^9.7.6",
10 | "babel": "^6.23.0",
11 | "bootstrap": "^4.4.1",
12 | "chart.js": "^2.9.3",
13 | "clipboard": "^2.0.6",
14 | "gulp": "^4.0.2",
15 | "gulp-concat": "^2.6.1",
16 | "gulp-csso": "^4.0.1",
17 | "gulp-fontmin-woff2": "^0.7.6",
18 | "gulp-imagemin": "^7.1.0",
19 | "gulp-postcss": "^8.0.0",
20 | "gulp-pug": "^4.0.1",
21 | "gulp-rename": "^2.0.0",
22 | "gulp-sass": "^4.0.2",
23 | "gulp-sourcemaps": "^2.6.5",
24 | "gulp-uglify": "^3.0.2",
25 | "postcss-uncss": "^0.17.0",
26 | "rellax": "^1.12.1",
27 | "smoothscroll-polyfill": "^0.4.4",
28 | "uncss": "^0.17.3",
29 | "vanilla-lazyload": "^15.1.1",
30 | "vinyl-buffer": "^1.0.1"
31 | },
32 | "devDependencies": {
33 | "@babel/core": "^7.9.0",
34 | "@babel/plugin-transform-runtime": "^7.9.0",
35 | "@babel/preset-env": "^7.9.5",
36 | "babel-core": "^6.26.3",
37 | "babel-preset-env": "^1.7.0",
38 | "babelify": "^10.0.0",
39 | "browserify": "^16.5.1",
40 | "del": "^5.1.0",
41 | "event-stream": "^4.0.1",
42 | "font-awesome": "^4.7.0",
43 | "glob": "^7.1.6",
44 | "gulp-babel": "^8.0.0",
45 | "gulp-connect": "^5.7.0",
46 | "gulp-if": "^3.0.0",
47 | "gulp-svg-sprite": "^1.5.0",
48 | "jquery": "^3.5.0",
49 | "merge-stream": "^2.0.0",
50 | "popper.js": "^1.16.1",
51 | "rfs": "^9.0.3",
52 | "vinyl-source-stream": "^2.0.0"
53 | },
54 | "scripts": {
55 | "test": "echo \"Error: no test specified\" && exit 1",
56 | "gulp": "NODE_ENV='development' gulp",
57 | "gulp-build": "NODE_ENV='production' gulp",
58 | "dev": "npm run gulp",
59 | "start": "npm run gulp",
60 | "build": "npm run gulp-build"
61 | },
62 | "repository": {
63 | "type": "git",
64 | "url": "git+https://github.com/yakim-shu/MTR-4rd-web.git"
65 | },
66 | "author": "",
67 | "license": "ISC",
68 | "bugs": {
69 | "url": "https://github.com/yakim-shu/MTR-4rd-web/issues"
70 | },
71 | "homepage": "https://github.com/yakim-shu/MTR-4rd-web#readme"
72 | }
73 |
--------------------------------------------------------------------------------
/docs/image/img_project_2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/image/img_cta_bg.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/image/index_portrait_2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/scss/_mixin.scss:
--------------------------------------------------------------------------------
1 | /* ------- media query ------- */
2 | $breakpoints: (
3 | 'mobile-s': $width-mobile-s,
4 | 'mobile-m': $width-mobile-m,
5 | 'mobile-l': $width-mobile-l,
6 | 'tablet': $width-tablet,
7 | 'tablet-s': $width-tablet-s,
8 | 'desktop-s': $width-desktop-s,
9 | 'desktop-m': $width-desktop-m,
10 | 'desktop-l': $width-desktop-l,
11 | 'desktop-xl': $width-desktop-xl
12 | );
13 |
14 | @mixin mq($width) {
15 | @if map_has_key($breakpoints, $width) {
16 | $width: map_get($breakpoints, $width);
17 |
18 | @media screen and (max-width: $width) {
19 | @content;
20 | }
21 | }
22 | }
23 |
24 | /* ------- mixins ------- */
25 |
26 | /* size */
27 | @mixin size($width, $height: $width) {
28 | width: $width;
29 | height: $height;
30 | }
31 |
32 | /* pseudo */
33 | @mixin pseudo($display: block, $content: '') {
34 | content: $content;
35 | display: $display;
36 | }
37 |
38 | @mixin arrow-icon-pseudo($width: 45px, $height: 20px) {
39 | @extend .svg-icon_arrow_right;
40 | @include pseudo(inline-block);
41 | @include relative($top: 7px, $left: 15px);
42 | width: $width;
43 | height: $height;
44 | }
45 |
46 | /* position */
47 | @mixin position(
48 | $position,
49 | $top: null,
50 | $right: null,
51 | $bottom: null,
52 | $left: null
53 | ) {
54 | position: $position;
55 | top: $top;
56 | right: $right;
57 | bottom: $bottom;
58 | left: $left;
59 | }
60 |
61 | @mixin absolute($args...) {
62 | @include position(absolute, $args...);
63 | }
64 |
65 | @mixin relative($args...) {
66 | @include position(relative, $args...);
67 | }
68 |
69 | @mixin fixed($args...) {
70 | @include position(fixed, $args...);
71 | }
72 |
73 | /* border-radius */
74 | @mixin border-radius($pixel...) {
75 | border-radius: $pixel;
76 | }
77 |
78 | /* ------- extends ------- */
79 | %transition {
80 | transition: all 0.3s;
81 | }
82 |
83 | %reset {
84 | margin: 0;
85 | padding: 0;
86 | }
87 |
88 | %responsive-img {
89 | overflow: hidden;
90 |
91 | img {
92 | max-width: 100%;
93 | height: auto;
94 | }
95 | }
96 |
97 | %weight-font-style {
98 | font-family: 'Palanquin Dark', sans-serif;
99 | letter-spacing: 0.15rem;
100 | font-weight: bold;
101 | }
102 |
103 | %fontawesome-icon {
104 | @extend %fa-icon;
105 | @extend .fas;
106 | display: inline-block;
107 | text-rendering: auto;
108 | }
109 |
110 | %custom-border-bottom {
111 | content: '';
112 | display: block;
113 | background: #ebd8d8;
114 | width: 100%;
115 | height: 9px;
116 | position: absolute;
117 | left: 0;
118 | bottom: -1px;
119 | z-index: -1;
120 | }
--------------------------------------------------------------------------------
/src/image/index_portrait_1.svg:
--------------------------------------------------------------------------------
1 |
21 |
--------------------------------------------------------------------------------
/docs/image/img_project_1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/image/theme_light_character.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/scss/_layout.scss:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: $main-bg-Color;
3 | padding-bottom: 40px;
4 | }
5 |
6 | body.theme-index {
7 | background-color: white;
8 | background-image: url(./../image/grey_bg.svg), url(./../image/red_line_bg.svg);
9 | background-position: right -60vw top 400px,left -25vw top -300px;
10 | background-repeat: no-repeat;
11 |
12 | @include mq('desktop-m') {
13 | background-position: right -35vw top 43vw,left -40vw top -360px;
14 | background-size: 90%;
15 | }
16 | @include mq('tablet') {
17 | background-position: right -35vw top 55vw;
18 | background-image: url(./../image/grey_bg.svg);
19 | }
20 | @include mq('mobile-l') {
21 | background-position: right -35vw top 65vw;
22 | }
23 | }
24 |
25 | .wrapper {
26 | padding: 160px 0 0;
27 |
28 | @include mq('mobile-l') {
29 | padding-top: 110px;
30 | }
31 | }
32 |
33 | .scroll-top-btn {
34 | @extend %transition;
35 | @include fixed($bottom: 20px, $right: calc((100vw - 1200px) / 2));
36 | @include size(50px);
37 | background-color: lighten($main-color, 8);
38 | border-radius: 50%;
39 | box-shadow: 0 5px 5px rgba(0,0,0, .2);
40 | z-index: 10;
41 |
42 | &:focus {
43 | outline: none;
44 | };
45 |
46 | &:after {
47 | @extend %fontawesome-icon;
48 | @include font-size(15px);
49 | @include pseudo(inline-block);
50 | content: fa-content($fa-var-arrow-up);
51 | color: white;
52 | }
53 |
54 | @include mq('desktop-l') {
55 | right: 20px;
56 | }
57 | }
58 |
59 | /* uncss:ignore start */
60 | .scroll-top-btn.content-invisible {
61 | visibility: hidden;
62 | opacity: 0;
63 | }
64 | /* uncss:ignore end */
65 |
66 |
67 | .theme-index {
68 | .wrapper {
69 | background: url(./../image/img_visual_light.svg) center top no-repeat;
70 | background-position-y: 100px;
71 | padding-top: 220px;
72 |
73 | @include mq('mobile-l') {
74 | background-position-y: 75px;
75 | background-size: 20% auto;
76 | padding-top: 150px;
77 | }
78 | }
79 |
80 | .full-bg {
81 | background-color: white;
82 | background-image: url(./../image/bg_dot.svg), url(./../image/grey_bg.svg), url(./../image/theme_light_red_bg.svg);
83 | background-repeat: repeat, no-repeat, no-repeat;
84 | background-position: center,left 50vw top 150px,left -45vw bottom -50px;
85 | padding: 0;
86 |
87 | @include mq('desktop-l') {
88 | background-image: url(./../image/bg_dot.svg), url(./../image/grey_bg.svg);
89 | background-position: center,left 30vw top 400px;
90 | background-repeat: repeat, no-repeat;
91 | }
92 | }
93 | }
94 |
95 | .section {
96 | padding: 0 20px;
97 | margin: 0 auto;
98 | }
99 |
100 | .full-bg {
101 | background: $color-theme-light;
102 | padding: 4rem 20px;
103 |
104 | &.theme-dark {
105 | background: $main-color;
106 | }
107 |
108 | @include mq('mobile-l') {
109 | padding: 2rem 15px;
110 | }
111 | }
112 |
113 |
--------------------------------------------------------------------------------
/src/scss/sprite/view/_sprite.scss:
--------------------------------------------------------------------------------
1 | %svg-common {
2 | background: url("sprite.svg") no-repeat;
3 | }
4 |
5 | .svg-icon_arrow_right {
6 | @extend %svg-common;
7 | background-position: 0 0;
8 | }
9 |
10 | .svg-icon_arrow_right-dims {
11 | width: 17px;
12 | height: 18px;
13 | }
14 |
15 | .svg-icon_arrow_right_blue {
16 | @extend %svg-common;
17 | background-position: 0 1.2491325468424705%;
18 | }
19 |
20 | .svg-icon_arrow_right_blue-dims {
21 | width: 48px;
22 | height: 23px;
23 | }
24 |
25 | .svg-icon_arrow_right_red {
26 | @extend %svg-common;
27 | background-position: 0 2.8452463566967383%;
28 | }
29 |
30 | .svg-icon_arrow_right_red-dims {
31 | width: 48px;
32 | height: 23px;
33 | }
34 |
35 | .svg-icon_avatar_1 {
36 | @extend %svg-common;
37 | background-position: 0 4.647785039941903%;
38 | }
39 |
40 | .svg-icon_avatar_1-dims {
41 | width: 93px;
42 | height: 87px;
43 | }
44 |
45 | .svg-icon_avatar_2 {
46 | @extend %svg-common;
47 | background-position: 0 10.965867828612927%;
48 | }
49 |
50 | .svg-icon_avatar_2-dims {
51 | width: 87px;
52 | height: 87px;
53 | }
54 |
55 | .svg-icon_avatar_3 {
56 | @extend %svg-common;
57 | background-position: 0 17.423133235724745%;
58 | }
59 |
60 | .svg-icon_avatar_3-dims {
61 | width: 87px;
62 | height: 98px;
63 | }
64 |
65 | .svg-icon_avatar_4 {
66 | @extend %svg-common;
67 | background-position: 0 24.40087145969499%;
68 | }
69 |
70 | .svg-icon_avatar_4-dims {
71 | width: 87px;
72 | height: 87px;
73 | }
74 |
75 | .svg-icon_methods_1 {
76 | @extend %svg-common;
77 | background-position: 0 32.216298552932216%;
78 | }
79 |
80 | .svg-icon_methods_1-dims {
81 | width: 164px;
82 | height: 151px;
83 | }
84 |
85 | .svg-icon_methods_2 {
86 | @extend %svg-common;
87 | background-position: 0 43.6834094368341%;
88 | }
89 |
90 | .svg-icon_methods_2-dims {
91 | width: 164px;
92 | height: 150px;
93 | }
94 |
95 | .svg-icon_methods_3 {
96 | @extend %svg-common;
97 | background-position: 0 55.09893455098935%;
98 | }
99 |
100 | .svg-icon_methods_3-dims {
101 | width: 165px;
102 | height: 150px;
103 | }
104 |
105 | .svg-icon_methods_4 {
106 | @extend %svg-common;
107 | background-position: 0 66.5144596651446%;
108 | }
109 |
110 | .svg-icon_methods_4-dims {
111 | width: 164px;
112 | height: 150px;
113 | }
114 |
115 | .svg-img_about_teacher {
116 | @extend %svg-common;
117 | background-position: 0 77.59633236085325%;
118 | }
119 |
120 | .svg-img_about_teacher-dims {
121 | width: 304px;
122 | height: 144.35px;
123 | }
124 |
125 | .svg-img_about_teacher_left {
126 | @extend %svg-common;
127 | background-position: 0 92.19242902208202%;
128 | }
129 |
130 | .svg-img_about_teacher_left-dims {
131 | width: 91px;
132 | height: 196px;
133 | }
134 |
135 | .svg-logo_lidemy {
136 | @extend %svg-common;
137 | background-position: 0 96.94602272727273%;
138 | }
139 |
140 | .svg-logo_lidemy-dims {
141 | width: 56px;
142 | height: 56px;
143 | }
144 |
145 | .svg-logo_mtr {
146 | @extend %svg-common;
147 | background-position: 0 100%;
148 | }
149 |
150 | .svg-logo_mtr-dims {
151 | width: 114px;
152 | height: 43px;
153 | }
154 |
155 |
--------------------------------------------------------------------------------
/src/scss/page/_faq.scss:
--------------------------------------------------------------------------------
1 | /* faq -------------------- */
2 | .faq {
3 | max-width: $width-desktop-s;
4 | line-height: 1.5em;
5 | margin: 0 auto 30px;
6 | &__title {
7 | @include font-size(36px);
8 | font-weight: bold;
9 | line-height: 2.5em;
10 | color: $main-color;
11 | text-align: center;
12 | }
13 | &__list {
14 | display: flex;
15 | align-items: center;
16 | justify-content: center;
17 | flex-direction: column;
18 | }
19 | }
20 |
21 | /* faq__list__item */
22 | .faq__list__item {
23 | @extend %transition;
24 | @include border-radius(5px);
25 | width: 100%;
26 | margin-bottom: 13px;
27 | color: $grey;
28 | border: 1px solid #dedede;
29 | }
30 |
31 | /* faq__list__item > link */
32 | .faq__list__item-link {
33 | @extend %transition;
34 | @include border-radius(5px);
35 | display: flex;
36 | align-items: center;
37 | justify-content: space-between;
38 | width: 100%;
39 | padding: 25px 20px 25px 0;
40 | color: $grey;
41 | background: white;
42 |
43 | .fa-chevron-up{
44 | transition: transform 0.5s;
45 | }
46 |
47 | &:hover {
48 | background-color: $main-color;
49 | color: white;
50 | }
51 | }
52 |
53 | /* faq__list__item > link > question */
54 | .faq__list__item-question {
55 | display: flex;
56 | flex-direction: row;
57 | align-items: center;
58 | justify-content: flex-start;
59 |
60 | h3 {
61 | @include font-size(16px);
62 | padding: 0 20px;
63 | margin-bottom: 0;
64 |
65 | }
66 |
67 | span {
68 | @include font-size(24px);
69 | font-weight: bold;
70 | padding-left: 24px;
71 |
72 | @include mq('mobile-l') {
73 | display: none;
74 | }
75 | }
76 | }
77 |
78 | /* faq__list__item > content */
79 | .faq__list__item-content {
80 | @include font-size(15px);
81 | @include border-radius(0 0 5px 5px);
82 | transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);
83 | max-height:0;
84 | display: flex;
85 | align-items: flex-start;
86 | background-color: white;
87 | overflow: hidden;
88 |
89 | &-text {
90 | padding: 20px;
91 | }
92 |
93 | p {
94 | margin-bottom: 20px;
95 | color: $grey;
96 | }
97 |
98 | a {
99 | color: $main-color;
100 | }
101 |
102 | span {
103 | @include font-size(24px);
104 | padding: 22px 0 0 26px;
105 | font-weight: bold;
106 | color: $main-color;
107 |
108 | @include mq('mobile-l') {
109 | display: none;
110 | }
111 | }
112 | }
113 |
114 | /* uncss:ignore start */
115 | /* active */
116 | .faq__list__item.active {
117 | box-shadow: 0px 5px 15px rgba(202, 65, 65, 0.15), 0px 2px 0px rgba(0, 0, 0, 0.05);
118 | margin: 15px 0 28px 0;
119 | /* uncss:ignore */
120 | .fa-chevron-up {
121 | transform: rotate(180deg);
122 | }
123 | /* uncss:ignore */
124 | .faq__list__item-link {
125 | @include border-radius(5px 5px 0 0);
126 | background-color: $main-color;
127 | color: white;
128 | }
129 | /* uncss:ignore */
130 | .faq__list__item-content {
131 | transition: max-height 1s ease-in-out;
132 | max-height: 2000px;
133 | }
134 | }
135 | /* uncss:ignore end */
136 |
--------------------------------------------------------------------------------
/src/image/img_features.svg:
--------------------------------------------------------------------------------
1 |
30 |
--------------------------------------------------------------------------------
/docs/image/img_apply.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/image/img_project_2.svg:
--------------------------------------------------------------------------------
1 |
19 |
--------------------------------------------------------------------------------
/src/image/index_portrait_2.svg:
--------------------------------------------------------------------------------
1 |
28 |
--------------------------------------------------------------------------------
/src/scss/layout/_footer.scss:
--------------------------------------------------------------------------------
1 | .footer {
2 | width: 100%;
3 | background: white;
4 | color: $grey;
5 | border-top: 1px solid $main-color;
6 | box-shadow: 0px -5px 20px rgba(202, 65, 65, 0.05);
7 | }
8 |
9 | // footer content
10 | .footer__content {
11 | display: flex;
12 | justify-content: space-evenly;
13 | padding: 60px;
14 | max-width: 1200px;
15 | margin: 0 auto;
16 | }
17 |
18 | // footer social media links
19 | .footer__links {
20 | display: flex;
21 | justify-content: flex-start;
22 | flex-direction: column;
23 | width: 250px;
24 |
25 | .logo {
26 | display: flex;
27 | align-items: center;
28 | margin-bottom: 28px;
29 |
30 | .pic {
31 | @extend .svg-logo_lidemy;
32 | width: 52px;
33 | height: 52px;
34 | margin-right: 16px;
35 | }
36 |
37 | h3 {
38 | @include font-size(24px);
39 | margin: 0;
40 | }
41 | }
42 |
43 | p {
44 | @include font-size(14px);
45 | }
46 |
47 | .footer__follow {
48 | color: black;
49 | font-weight: bold;
50 | letter-spacing: 0.12rem;
51 | }
52 | }
53 |
54 | .social-icons {
55 | a {
56 | @include font-size(27px);
57 | margin-right: 24px;
58 | }
59 | }
60 |
61 | // footer navs
62 | .footer__nav-list {
63 | display: flex;
64 | justify-content: space-evenly;
65 | flex: 1;
66 | max-width: 750px;
67 | }
68 |
69 | .footer__nav-item {
70 | display: flex;
71 | flex-direction: column;
72 | justify-content: flex-start;
73 |
74 | h4 {
75 | @include font-size(14px);
76 | padding-bottom: 12px;
77 | margin-bottom: 15px;
78 | font-weight: bold;
79 | letter-spacing: 0.12rem;
80 | border-bottom: 1px solid $grey-light;
81 | }
82 |
83 | a {
84 | @include font-size(12px);
85 | line-height: 2em;
86 | letter-spacing: 0.15rem;
87 | }
88 | }
89 |
90 | .footer__footnote {
91 | @include font-size(12px);
92 | text-align: center;
93 | background: $main-color;
94 | color: white;
95 | display: flex;
96 | flex-wrap: wrap;
97 | justify-content: center;
98 | align-items: center;
99 | padding: 10px 0;
100 |
101 | a {
102 | margin: 0 5px;
103 | }
104 |
105 | .resource {
106 | a {
107 | color: rgba(white, .8);
108 | border:none;
109 | }
110 | }
111 | .copyright, .resource {
112 | color: white;
113 | margin: 0 10px 0;
114 | }
115 |
116 | &__btn {
117 | display: inline-block;
118 | margin: 5px 0;
119 | a {
120 | display: inline-block;
121 | padding: 0px 5px;
122 | border: 1px solid white;
123 | border-radius: 2px;
124 |
125 | &:hover {
126 | color: white;
127 | background: rgba(white, .2);
128 | }
129 | }
130 | }
131 |
132 | }
133 |
134 |
135 | @include mq('desktop-s') {
136 | .footer {
137 | &__content {
138 | flex-direction: column;
139 | padding: 40px 30px;
140 |
141 | }
142 | &__links {
143 | width: 100%;
144 |
145 | .logo {
146 | margin-bottom: .5rem;
147 | .pic {
148 | transform: scale(0.75);
149 | }
150 |
151 | h3 {
152 | @include font-size(16px)
153 | }
154 | }
155 |
156 | p {
157 | @include font-size(13px)
158 | }
159 |
160 | }
161 |
162 | &__social {
163 | justify-content: center;
164 | }
165 |
166 | &__follow {
167 | display: none;
168 | }
169 | }
170 | }
171 |
172 | .footer__nav {
173 | @include mq('desktop-s') {
174 | &-list {
175 | max-width: 100%;
176 | margin-top: 2rem;
177 | flex-wrap: wrap;
178 | justify-content: space-between;
179 | }
180 |
181 | &-item {
182 | min-width: 170px;
183 | margin-bottom: 1.5rem;
184 | padding: 0 10px;
185 | }
186 | }
187 |
188 | @include mq('mobile-m') {
189 | &-item {
190 | min-width: auto;
191 | width: calc((100% - 20px) / 2);
192 | margin-bottom: 1.5rem;
193 | padding: 0;
194 |
195 | a {
196 | font-size: 13px;
197 | }
198 |
199 | &:nth-child(odd) {
200 | margin-right: 20px;
201 | }
202 | }
203 | }
204 | }
--------------------------------------------------------------------------------
/src/image/sprite/icon_avatar_4.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/docs/image/theme_dark_character.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/html/layout/footer.pug:
--------------------------------------------------------------------------------
1 | mixin footer_nav_item(item)
2 | li.footer__nav-item
3 | h4.footer__nav-title= item.title
4 | each content in item.contents
5 | a(href=`${content.link}`)= content.text
6 |
7 | //- footer
8 | block footer
9 | footer.footer
10 | .footer__content
11 | .footer__links
12 | a(href="index.html").logo
13 | .pic
14 | .footer__logo-img
15 | h3 Lidemy
16 | p 用六個月的時間,培養出一個找得到工作且基礎紮實的網頁工程師。
17 | p.footer__follow FOLLOW US
18 | .footer__social.social-icons
19 | a(href="https://github.com/Lidemy/mentor-program-4th", target="_blank", rel="noopener", aria-label="GitHub").github-link
20 |
21 | a(href="https://www.facebook.com/lidemytw/", target="_blank", rel="noopener", aria-label="Facebook").facebook-link
22 |
23 | a(href="https://medium.com/@hulitw", target="_blank", rel="noopener", aria-label="Medium").medium-link
24 |
25 | ul.footer__nav-list
26 | -
27 | var footerItems = [
28 | {
29 | title: "HOME",
30 | contents: [
31 | { text: "課程特色", link: "/#anchor-features"},
32 | { text: "教學方式", link: "/#anchor-methods"},
33 | { text: "關於導師", link: "/#anchor-about-teacher"},
34 | { text: "課程時程", link: "/#anchor-schedule"},
35 | { text: "適合怎樣的人", link: "/#anchor-target"},
36 | { text: "學員心得節錄", link: "/#anchor-previous-experience"},
37 | ]
38 | },
39 | {
40 | title: "INTRODUCE",
41 | contents: [
42 | { text: "計畫介紹", link: "introduce.html#anchor-projectIntro"},
43 | { text: "老師介紹", link: "introduce.html#anchor-teacherIntro"},
44 | { text: "歷屆改進心得", link: "introduce.html#anchor-improvement"},
45 | ]
46 | },
47 | {
48 | title: "COURSE",
49 | contents: [
50 | { text: "程式基礎", link: "syllabus.html#anchor-part1"},
51 | { text: "網站開發", link: "syllabus.html#anchor-part2"},
52 | { text: "探究原理", link: "syllabus.html#anchor-part3"},
53 | { text: "專案開發", link: "syllabus.html#anchor-part4"},
54 | ]
55 | },
56 | {
57 | title: "RESULT",
58 | contents: [
59 | { text: "歷屆數據", link: "achievement.html#anchor-data"},
60 | { text: "學生求職成果", link: "achievement.html#anchor-report"},
61 | { text: "結業心得", link: "achievement.html#anchor-experience"},
62 | ]
63 | },
64 | {
65 | title: "APPLY",
66 | contents: [
67 | { text: "課程制度", link: "course-info.html#anchor-rule"},
68 | { text: "收費方式", link: "course-info.html#anchor-charge"},
69 | { text: "報名方式", link: "course-info.html#anchor-registration"},
70 | { text: "報名信內容", link: "course-info.html#anchor-letter"},
71 | { text: "時程列表", link: "course-info.html#anchor-schedule-list"},
72 | ]
73 | },
74 | {
75 | title: "FAQ",
76 | contents: [
77 | { text: "常見問題", link: "faq.html#anchor-faq"},
78 | ]
79 | },
80 | ];
81 | each item in footerItems
82 | +footer_nav_item(item)
83 | .footer__footnote
84 | p.resource illustrator from
85 | a(href="https://getillustrations.com/illustration-pack/ghost-illustrations-builder" target="_blank" rel="noopener") getillustrations.com
86 | p.copyright © 2020 Lidemy. All rights reserved.
87 | .footer__footnote__btn
88 | a(href="https://github.com/Lidemy/mtr-4th-web" target="_blank" rel="noopener") Source Code.
89 | a(href="/humans.txt" target="_blank" rel="noopener") Team.
--------------------------------------------------------------------------------
/src/image/img_project_1.svg:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/src/image/img_cta_bg.svg:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/src/image/sprite/img_about_teacher_left.svg:
--------------------------------------------------------------------------------
1 |
29 |
--------------------------------------------------------------------------------
/src/image/theme_light_character.svg:
--------------------------------------------------------------------------------
1 |
35 |
--------------------------------------------------------------------------------
/docs/image/img_student_experence.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/html/faq.pug:
--------------------------------------------------------------------------------
1 | extends layout/layout.pug
2 |
3 | include mixin/_mixin.pug
4 |
5 | //- mixin
6 | mixin list_item(title, activeClass)
7 | li(class= `faq__list__item ${activeClass || ''}`)
8 | a(href='#').faq__list__item-link
9 | .faq__list__item-question
10 | span Q
11 | h3= title
12 | i(class="fas fa-chevron-up")
13 | .faq__list__item-content
14 | span A
15 | .faq__list__item-content-text
16 | if(block)
17 | block
18 |
19 | block head
20 | +head_block({
21 | title: 'FAQ'
22 | })
23 |
24 | block current
25 | - var currentUrl = "faq"
26 |
27 | block content
28 | .section.faq.anchor-faq
29 | //- h2.faq__title FAQ
30 | +common_title('FAQ', 'anchor-faq')
31 | ul.faq__list
32 | +list_item('為什麼這個計畫到了第五期還是「實驗」計畫?', 'active')
33 | p 這個計畫搞不好永遠都會叫做「實驗」計畫,因為每一期我都當作一個實驗,實驗我的教學成效如何、品質如何,根據學生的回饋調整課程內容,繼續做下一輪的實驗,持續優化、改進。
34 | +list_item('為什麼我要花這麼多錢只為了看線上影片?')
35 | p 因為這個課程不只有線上影片。
36 | p 除了線上影片以外,還有批改作業的服務以及學習社群,還有學員專屬的直播 QA 時間。這些東西全都加在一起,才是這個計畫的獨特之處。若是你覺得只看線上影片就很足夠了,部分的課程內容其實有在對外販售,可以參考:
37 | a(href="https://lidemy.com/", target="_blank", rel="noopener") Lidemy 課程列表 。
38 | +list_item('為什麼課程裡前後端都有而不是只專注在一個?兩邊都學會不會樣樣通樣樣鬆?')
39 | p 首先,讓你前後端都學絕對不是讓你成為 Full-stack 工程師,成為 Half-stack 倒是有點機會。無論你是前端還是後端,別忘了前面還有大家經常性忽略的一個詞「Web」,Web 前端與後端才是全名。
40 | p 既然 Web 包含了前後端兩個部分,少了任何一部份都不完整,都會讓你對於整個網路的理解缺了一塊。因此這堂課從前到後再由後到前,希望把你對網路的知識整個打通,這樣我覺得才是最完整、最全面的學習。
41 | p 至於樣樣通樣樣鬆,不會。
42 | p 一併學習前後端的好處就是對網路的基礎會比只學單個的紮實許多,因為你對整體有個全面性的理解。而且這邊前後端都注重原理與基礎,基礎打好之後學工具便不是難事。
43 | +list_item('學生出來會不會沒人帶就什麼都不會?')
44 | p 首先,大家要很清楚知道的一點是,在職場上沒人帶才是常態。很有可能你進去的公司只有你一個工程師,或是儘管有一個 team,但也不會有一個人專門去帶你。本來就沒有人有義務去帶你。
45 | p 為了不讓學生變成只會看影片跟著打 code ,關了影片什麼都寫不出來的那種人,我在作業上有做一些調整,很多作業的內容跟要你寫的東西是課程裡面沒有的,你就必須自己去找資料才能實作得出來。
46 | p 所以在課程中就已經培養了一定程度的自學能力。
47 | +list_item('學費方案是怎麼訂的?')
48 | p 在一開始的程式導師實驗計畫,只有「A 求職方案」,背後的理念是:「你來我這邊學半年,如果還找不到工作,那是我的問題,是我沒教好」所以一毛錢都不用付,但如果找到工作了,代表我教得不錯,那就要收一筆學費。
49 | p 但是轉職可不是件簡單的事,雖然說六個月很長了,但是這跟你每天付出多少時間是有關的,一天只能付出兩小時跟一天付出六小時,最後的時數就差了三倍。
50 | p 我規劃的課綱以及作業大概是「每週至少付出 50 個小時」的量,這差不多就是要全職學習了,否則很難做到。而我也認為對想要在半年內轉職的人來說,這樣的時間是必須的。
51 | p 但是一開始的收費規則並沒有很強硬的規定時間以及轉職意願,所以幾期下來,有一些學生是課程開始時想要轉職,到後面卻因為各種因素不想轉了,也有一些可以付出的時間越來越少。
52 | p 若是「沒辦法付出時間」或者「沒有求職意願」,那我前面所說的「你來我這邊學半年,如果還找不到工作,那是我的問題,是我沒教好」這句話就不成立了,因為這句話的前提是:「這半年要持續付出一定時間」以及「你要有求職意願」。
53 | p 但如果只收這種人,就會沒辦法顧到其他的人。例如說已經有工作想來加強基礎,或者是想要邊工作邊學習程式轉職成工程師,時間也可以接受拉得比較長(可能多兩個月之類的),或是純粹對程式有興趣想要學習的人。針對這些人,原本的付費規則就不適用了,因此才有了第四期這個新的付費規則:「就直接付學費吧」。
54 | p 以前幾期的資料來看,若是課程有好好上完,年薪 50 萬跑不掉,那學費就是 60k,因此 B 方案就以這個價錢為基準再降 5k,所以總額才定在 55k。
55 | p 為什麼要降 5k?這是為了讓想要轉職的人也可以考慮 B 方案。如果有人符合選擇 A 方案的資格,但是對自己很有自信,覺得一定可以轉職成功,那就可以選擇 B 方案。對他來說,整體學費變少了,對我來說,我也不須承擔找不到工作學費歸零的風險,是對雙方都有利益的行為。
56 | +list_item('收費方案有點複雜,可以舉一些例子嗎?')
57 | p 案例一:兩個月後選擇「A 求職方案」,繳交保證金 5000 元,跟到課程結束,於課程開始七個月後找到工作,年薪為 50 萬,總共的學費為:500k * 12% = 60k,扣掉保證金 5k,還要再繳 55k
58 | p 案例二:兩個月後選擇「A 求職方案」,繳交保證金 5000 元,課程開始八個月後都還沒找到工作,可以選擇什麼都不做,繼續留在課程,或是退出計畫,退回保證金 5000 元以及收回課程
59 | p 案例三:兩個月後選擇「A 求職方案」,繳交保證金 5000,在第四個月的時候沒有求職意願了,選擇退出課程,需要付 (4-2) * 12500 = 25000 元學費。
60 | p 案例四:兩個月後選擇「B 買斷方案」,繳交保證金 5000 元,一個月後開始每個月付 12500 元學費,付一個月之後就不想上了,退出課程,不收其他費用。
61 | p 附上幾個時間點:
62 | 2021-04-12 課程開始
63 |
64 | 2021-06-01 開始繳交保證金 5000 元並選擇課程方案,選擇「B 買斷方案」的同學需要繳交第一期 5000 + 12500 的款項,之後每個月再付 12500 元,總共要付四期
65 |
66 | 2021-10-12 課程結束,「A 求職方案」的同學開始準備求職
67 |
68 | 2021-12-12 求職期限截止,選擇「A 求職方案」的同學在這個時間點以前沒有找到工作都不用付學費
69 | +list_item('上了這堂課以後,就可以做出這個網站嗎?')
70 | p 很遺憾地告訴你,沒辦法。
71 | p 因為網站漂亮大部分是設計師的功勞,而不是工程師的。工程師通常都只是照著設計稿把網頁刻出來,而這堂課裡面完全不教設計,所以就算上完,也不會掌握任何設計相關能力。
72 | p 不過若是已經有了設計稿,要照著設計稿把這個網站刻出來,我相信是有辦法的(但要花很多時間)
73 | +list_item('上這個課真的不需要有任何程式基礎嗎?')
74 | p 真的,一點都不需要。
75 | p 但同時我也不否認,如果有程式基礎這堂課會上的比較順利。以前滿多學生其實都沒有程式基礎,而且背景跟程式甚至跟理科一點關係都沒有,最後有在時限內轉職成功的,也有失敗的。
76 | p 這堂課原本就是設計給毫無程式基礎的初學者上的,將來也會是這樣,所以不需要擔心。若是還有疑慮,可以參考歷屆學生的心得,找看看有沒有跟你背景差不多的人,聽一下他們怎麼說。
77 | +list_item('上了這堂課以後,一定可以轉職成工程師嗎?')
78 | p 很遺憾地告訴你,不一定。
79 | p 過去也帶了不少學生,並不是每一個人都可以轉職成工程師。不過根據過往的經歷來看,如果有把課程修完,基本上要找到工作是沒有問題的。所以其實最難的點是難在「把課程修完」,因為中途會碰到很多原因讓你想放棄,例如說自己的私事或是提不起興趣、時間不夠等等,也有可能是我的課程設計得不夠好,或者是課程太無聊,老師講得太爛。
80 | p 但我會努力做好我的部分,會盡量去改善課程,讓課程變得更好。
81 |
82 | script(defer src="js/faq.bundle.js")
--------------------------------------------------------------------------------
/src/scss/_element.scss:
--------------------------------------------------------------------------------
1 | @mixin button_1($withIcon, $iconId: $fa-var-long-arrow-alt-right) {
2 | @extend %transition;
3 | display: inline-block;
4 | padding: 12px 25px;
5 | background: $main-color;
6 | color: white;
7 | box-shadow: 0px 5px 5px rgba(75, 93, 104, 0.1);
8 | border-radius: 30px;
9 | letter-spacing: 0.2rem;
10 | font-size: 15px;
11 |
12 | &:hover {
13 | color: white;
14 | }
15 |
16 | @if ($withIcon) {
17 | &:after {
18 | @extend %fontawesome-icon;
19 | @extend %transition;
20 | color: white;
21 | content: fa-content($iconId);
22 | position: relative;
23 | right: -5px;
24 | }
25 |
26 | &:hover {
27 | background-color: darken($main-color, 5);
28 |
29 | &:after {
30 | right: -10px;
31 | }
32 | }
33 | }
34 | }
35 |
36 | %shadow-card {
37 | background: white;
38 | box-shadow: 0px 4px 30px rgba(0, 0, 0, 0.1);
39 | border-radius: 10px;
40 | padding: 40px 20px;
41 | margin: 0 auto;
42 | }
43 |
44 | /* common__title -------------------- */
45 | .common__title {
46 | @include font-size(22px);
47 | line-height: 3.2rem;
48 | margin-bottom: 20px;
49 | color: $color-theme-dark;
50 | width: 100%;
51 | margin: 0 auto;
52 | text-align: center;
53 |
54 | &.left {
55 | text-align: left;
56 | }
57 |
58 | a {
59 | position: relative;
60 | padding-left: 15px;
61 |
62 | &:before {
63 | @include pseudo(inline-block, '#');
64 | @include absolute($left: 0);
65 | color: $main-color;
66 | font-size: 16px;
67 | font-weight: bold;
68 | }
69 |
70 | &:hover {
71 | color: $main-color;
72 | }
73 | }
74 | }
75 |
76 |
77 | /* link -------------------- */
78 | %link {
79 | @include font-size(15px);
80 | display: inline-flex;
81 | align-items: center;
82 | justify-content: center;
83 | font-weight: normal;
84 | font-weight: normal;
85 |
86 | &:before {
87 | @extend .svg-icon_arrow_right_red;
88 | @include pseudo(inline-block);
89 | @include relative($top: 7px, $left: 15px);
90 | width: 45px;
91 | height: 20px;
92 | }
93 | }
94 |
95 | /* wave -------------------- */
96 | .wave {
97 | height: 24px;
98 | background-position: left top;
99 | background-repeat: repeat-x;
100 | }
101 |
102 | /* post -------------------- */
103 | .post {
104 | max-width: $width-tablet;
105 | margin: 0 auto;
106 |
107 | &:not(:nth-last-of-type(1)) {
108 | margin-bottom: 2.5rem;
109 | }
110 |
111 | &__content {
112 | border-top: 1px dashed $grey-light;
113 | padding: 25px 0;
114 |
115 | p {
116 | @include font-size(16px);
117 | line-height: 2rem;
118 | color: $grey;
119 | }
120 |
121 | ol {
122 | padding-left: 40px;
123 | }
124 |
125 | .annotation {
126 | @include font-size(14px);
127 | }
128 | }
129 | }
130 |
131 | /* post > strong, a */
132 | .post__content a {
133 | display: inline-block;
134 | margin: 2px 5px;
135 | color: $color-theme-dark;
136 | font-weight: bold;
137 | border: none;
138 | text-decoration: underline;
139 | text-underline-position: under;
140 | text-decoration-style: wavy;
141 | text-decoration-color: lighten($color-theme-dark, 30);
142 | line-height: 1.7rem;
143 |
144 | .theme-light & {
145 | color: white;
146 | }
147 |
148 | &:hover {
149 | border-color: lighten($color-theme-dark, 30);
150 | color: lighten($color-theme-dark, 30);
151 | }
152 | }
153 | .post__content strong{
154 | margin-bottom: 10px;
155 | position: relative;
156 | margin: 0 5px;
157 | z-index: 1;
158 | padding: 0 5px;
159 | font-weight: normal;
160 |
161 | &:before {
162 | content: '';
163 | display: block;
164 | background: #ebd8d8;
165 | width: 100%;
166 | height: 9px;
167 | position: absolute;
168 | left: 0;
169 | bottom: -1px;
170 | z-index: -1;
171 |
172 | .theme-light & {
173 | background: darken($main-color, 10);
174 | }
175 | }
176 | }
177 |
178 | /* post: theme-light */
179 | .post {
180 | .theme-light &__title {
181 | color: white;
182 | &:before {
183 | color: rgba(white, 0.5);
184 | }
185 |
186 | a:hover {
187 | color: rgba(white, 0.9);
188 | }
189 | }
190 | .theme-light &__content {
191 | border-color: white;
192 | p {
193 | color: white;
194 | strong {
195 | color: white;
196 | }
197 | }
198 | }
199 | }
--------------------------------------------------------------------------------
/src/image/sprite/icon_avatar_2.svg:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/src/image/sprite/icon_avatar_1.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/src/image/img_apply.svg:
--------------------------------------------------------------------------------
1 |
33 |
--------------------------------------------------------------------------------
/src/image/sprite/icon_avatar_3.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/src/image/sprite/icon_methods_2.svg:
--------------------------------------------------------------------------------
1 |
39 |
--------------------------------------------------------------------------------
/src/image/sprite/icon_methods_3.svg:
--------------------------------------------------------------------------------
1 |
37 |
--------------------------------------------------------------------------------
/src/scss/layout/_header.scss:
--------------------------------------------------------------------------------
1 | $width-header: 1000px;
2 |
3 | /* header -------------------- */
4 | .header {
5 | position: fixed;
6 | z-index: 9;
7 | display: flex;
8 | justify-content: flex-end;
9 | width: 100%;
10 | margin: 30px auto;
11 | pointer-events: none;
12 |
13 | @include mq('desktop-m') {
14 | padding: 0 30px;
15 | }
16 |
17 | @include mq('tablet') {
18 | padding: 0 4vw;
19 | }
20 |
21 | @include mq('mobile-l') {
22 | margin: 15px auto;
23 | }
24 |
25 | }
26 |
27 | /* uncss:ignore start */
28 | header.menu-opened {
29 | @include mq('desktop-s') {
30 | .header__content {
31 | height: auto;
32 | flex-direction: column;
33 | align-items: flex-start;
34 | }
35 |
36 | .header__logo {
37 | margin-bottom: 30px;
38 | }
39 |
40 | nav ul {
41 | display: flex;
42 | flex-direction: column;
43 | }
44 |
45 | .header__cta-btn {
46 | display: block;
47 | }
48 | }
49 | }
50 | /* uncss:ignore end */
51 |
52 | /* header > content */
53 | .header__content {
54 | height: 90px;
55 | width: $width-header;
56 | max-width: 100%;
57 | margin: 0 auto;
58 | display: flex;
59 | align-items: center;
60 | padding: 25px 40px;
61 | background: white;
62 | border-radius: 50px;
63 | pointer-events: auto;
64 | box-shadow: 0 4px 30px 0 $shadow-color;
65 | border: solid 0.5px $shadow-color;
66 | transition: all 0.275s cubic-bezier(0.07, 0.82, 0.41, 0.97);
67 | transition-property: width, height;
68 |
69 | @include mq('desktop-s') {
70 | overflow: hidden;
71 | }
72 |
73 | @include mq('mobile-l') {
74 | padding: 20px 30px;
75 | height: 70px;
76 | }
77 | }
78 |
79 | /* header > content > logo */
80 | .header__logo {
81 | display: flex;
82 | flex-direction: row;
83 | justify-content: space-between;
84 | align-items: center;
85 |
86 | @include mq('desktop-s') {
87 | width: 100%;
88 | }
89 | }
90 |
91 | .header__logo-img {
92 | @extend .svg-logo_mtr;
93 | display: block;
94 | height: 40px;
95 | width: 110px;
96 |
97 | @include mq('mobile-l') {
98 | transform: scale(0.85);
99 | }
100 | }
101 |
102 | /* header > content > icon */
103 | .header__responsive__icon {
104 | @extend %transition;
105 | @include border-radius(50%);
106 | width: 45px;
107 | height: 45px;
108 | display: none;
109 | color: white;
110 | background-color: $main-color;
111 | cursor: pointer;
112 |
113 | &:hover {
114 | transform: scale(1.04);
115 | }
116 |
117 | @include mq('desktop-s') {
118 | display: flex;
119 | align-items: center;
120 | justify-content: center;
121 | width: 35px;
122 | height: 35px;
123 | }
124 | }
125 |
126 | /* header > content > nav */
127 | .header nav {
128 | width: 100%;
129 | display: flex;
130 | flex: 1;
131 | justify-content: center;
132 | opacity: 1;
133 | transition: opacity .5s;
134 |
135 | ul {
136 | display: flex;
137 | flex: 1;
138 | flex-direction: row;
139 | justify-content: center;
140 |
141 | @include mq('desktop-s') {
142 | flex-direction: column;
143 | display: none;
144 | }
145 | }
146 | }
147 |
148 | /* nav > ul > li */
149 | .header nav li {
150 | display: inline-block;
151 | font-size: 15px;
152 | color: $grey;
153 |
154 | @include mq('desktop-s') {
155 | border-top: 1px solid rgba(0, 0, 0, 0.08);
156 |
157 | &:nth-last-of-type(1) {
158 | border-bottom: 1px solid rgba(0, 0, 0, 0.08);
159 | margin-bottom: 27px;
160 | }
161 | }
162 |
163 | &.current a {
164 | color: $main-color;
165 | border-bottom: 1px solid $main-color;
166 |
167 | @include mq('desktop-s') {
168 | border: none;
169 | }
170 |
171 | &:before {
172 | display: none;
173 | }
174 | }
175 |
176 | a {
177 | @extend %transition;
178 | display: inline-block;
179 | padding: 16px 0;
180 | margin: 0 13px;
181 | position: relative;
182 |
183 | @include mq('desktop-s') {
184 | width: 100%;
185 | }
186 |
187 | &:before {
188 | z-index: 1;
189 | content: '';
190 | position: absolute;
191 | left: 0;
192 | bottom: -2px;
193 | width: 100%;
194 | height: 1px;
195 | background: $main-color;
196 | transform: scale(0, 1);
197 | transition: transform 0.6s ease;
198 |
199 | @include mq('desktop-s') {
200 | width: 0;
201 | }
202 | }
203 | }
204 | }
205 |
206 | /* nav > ul > li:hover */
207 | nav li:hover {
208 | a {
209 | color: $main-color;
210 |
211 | &:before {
212 | transform-origin: left;
213 | transform: scale(1, 1);
214 | }
215 | }
216 | }
217 |
218 | /* header > content > CTA button */
219 | .header__cta-btn {
220 | @include button_1($withIcon: true);
221 | transition-delay: 0.2s;
222 |
223 | @include mq('desktop-s') {
224 | display: none;
225 | }
226 | }
227 |
228 | /* uncss:ignore start */
229 | /* media query */
230 | @media (min-width: $width-header) {
231 | .header.is-shrunk {
232 | .header__content {
233 | margin-right:calc((100% - 1000px) / 2);
234 | }
235 | }
236 | }
237 |
238 | @media (min-width: 901px) {
239 | // header shrunk
240 | .header.is-shrunk {
241 | .header__logo {
242 | width: 100%;
243 | }
244 |
245 | .header__content {
246 | display: flex;
247 | justify-content: space-between;
248 | width: 280px;
249 | margin-right:calc((100% - 900px) / 2);
250 | }
251 |
252 | nav {
253 | display: none;
254 | }
255 |
256 | .header__cta-btn {
257 | display: none;
258 | }
259 |
260 | .header__responsive__icon {
261 | width: 45px;
262 | height: 45px;
263 | display: flex;
264 | align-items: center;
265 | justify-content: center;
266 | }
267 | }
268 |
269 | /* header invisible */
270 | .header__nav.content-invisible,
271 | .header__cta-btn.content-invisible {
272 | visibility: hidden;
273 | opacity: 0;
274 | }
275 | }
276 |
277 | /* uncss:ignore end */
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp');
2 | const { src, dest } = require('gulp');
3 | const pug = require('gulp-pug');
4 | const sass = require('gulp-sass');
5 | const postcss = require('gulp-postcss');
6 | const uncss = require('postcss-uncss');
7 | const autoprefixer = require('autoprefixer');
8 | const minifyCSS = require('gulp-csso');
9 | const rename = require('gulp-rename');
10 | const sourcemaps = require('gulp-sourcemaps');
11 | const connect = require('gulp-connect');
12 | const imageMin = require('gulp-imagemin');
13 | const del = require('del')
14 | const browserify = require("browserify");
15 | const babelify = require("babelify");
16 | const source = require("vinyl-source-stream");
17 | const glob = require('glob');
18 | const es = require('event-stream');
19 | const uglify = require('gulp-uglify');
20 | const buffer = require('vinyl-buffer');
21 | const svgSprite = require('gulp-svg-sprite');
22 | const merge = require('merge-stream');
23 | const gulpif = require('gulp-if');
24 | const fontmin = require('gulp-fontmin-woff2');
25 |
26 | // run minfont.js to get this string
27 | const fontText = '\uf028\uf164\uf57d\uf1c0\uf7d9\uf233\uf201\uf3ed\uf126\uf51c\uf06e\uf0c9\uf35d\uf077\uf00c\uf2bd\uf061\uf063\uf062\uf073\uf550\uf14a\uf35a\uf0c5\uf30b\uf09b\uf082\uf23a\uf41b\uf3b8\uf13b\uf38b\uf268\uf457'
28 | const env = process.env.NODE_ENV;
29 |
30 | console.log('--- current mode: ', env);
31 |
32 | const base = {
33 | src: 'src',
34 | dest: 'docs',
35 | }
36 | const paths = {
37 | css: {
38 | src: `${base.src}/scss/*.scss`,
39 | dest: `${base.dest}/css`,
40 | },
41 | js: {
42 | src: `${base.src}/js/**/*.js`,
43 | dest: `${base.dest}/js`,
44 | },
45 | html: {
46 | src: `${base.src}/html/*.pug`,
47 | dest: base.dest,
48 | },
49 | image: {
50 | src: `${base.src}/image/*.+(jpg|jpeg|gif|png|svg)`,
51 | dest: `${base.dest}/image`,
52 | }
53 | };
54 |
55 | function clean() {
56 | return del([
57 | `${base.dest}/*`,
58 | `!${base.dest}/.git`,
59 | `!${base.dest}/.gitignore`,
60 | `!${base.dest}/robots.txt`,
61 | ]);
62 | }
63 |
64 | const js = (done) => {
65 | glob('./src/js/bundle/*.js', function (err, files) {
66 | if (err) done(err);
67 |
68 | files.push('src/js/index.js');
69 | var tasks = files.map(function (entry) {
70 | return browserify({
71 | entries: [entry],
72 | debug: env === 'development',
73 | transform: [babelify.configure(),]
74 | })
75 | .bundle()
76 | .pipe(source(entry.match(/[^\\/]+$/)[0]))
77 | .pipe(buffer())
78 | .pipe(sourcemaps.init({ loadMaps: true }))
79 | .pipe(uglify())
80 | .pipe(gulpif(env === 'development', sourcemaps.write()))
81 | .pipe(rename({
82 | extname: '.bundle.js'
83 | }))
84 | .pipe(gulp.dest(paths.js.dest));
85 | });
86 | es.merge(tasks).on('end', done)
87 | .pipe(connect.reload());
88 | })
89 | }
90 |
91 | function html() {
92 | return src(paths.html.src)
93 | .pipe(pug())
94 | .pipe(dest(base.dest))
95 | .pipe(connect.reload())
96 | }
97 |
98 | function sprite() {
99 | const config = {
100 | shape: {
101 | dimension: {
102 | maxWidth: 300,
103 | maxHeight: 300,
104 | },
105 | spacing: {
106 | padding: 2,
107 | },
108 | },
109 | mode: {
110 | view: {
111 | bust: false,
112 | example: true,
113 | layout: 'vertical',
114 | sprite: 'sprite.svg',
115 | render: {
116 | scss: { dest: '_sprite.scss' }
117 | }
118 | },
119 | }
120 | };
121 | return src('src/image/sprite/*.svg')
122 | .pipe(svgSprite(config))
123 | .pipe(gulp.dest('src/scss/sprite'));
124 | }
125 |
126 | function css() {
127 | const processors = [
128 | autoprefixer({ overrideBrowserslist: ['last 2 version'] }),
129 | ];
130 |
131 | if (env === 'production') {
132 | processors.push(
133 | uncss({
134 | html: ['docs/*.html'],
135 | })
136 | )
137 | }
138 | const css = gulp.src(paths.css.src)
139 | .pipe(sourcemaps.init())
140 | .pipe(sass().on('error', sass.logError))
141 | .pipe(postcss(processors))
142 | .pipe(minifyCSS())
143 | .pipe(gulpif(env === 'development', sourcemaps.write()))
144 | .pipe(rename({
145 | basename: 'main',
146 | suffix: '.min'
147 | }))
148 | .pipe(dest(paths.css.dest))
149 | .pipe(connect.reload())
150 |
151 | const copySprite = gulp.src('src/scss/sprite/view/*.svg')
152 | .pipe(gulp.dest('docs/css/'))
153 |
154 | return merge(css, copySprite);
155 | }
156 |
157 | function font() {
158 | return src(`${base.src}/webfonts/*.ttf`)
159 | .pipe(fontmin({
160 | text: fontText,
161 | }))
162 | .pipe(dest(`${base.dest}/webfonts`))
163 | }
164 |
165 | function img() {
166 | return src(paths.image.src)
167 | .pipe(imageMin())
168 | .pipe(dest(paths.image.dest))
169 | .pipe(connect.reload())
170 | }
171 |
172 | function beforeEnd() {
173 | return src(`${base.src}/statics/*`)
174 | .pipe(dest(`${base.dest}`))
175 | }
176 |
177 | function watch(done) {
178 | if (env !== 'production') {
179 | gulp.watch(`${base.src}/scss/**/*`, css);
180 | gulp.watch(`${base.src}/html/**/*`, html);
181 | gulp.watch(`${base.src}/js/**/*`, js);
182 | gulp.watch(`${base.src}/image/*`, img);
183 | gulp.watch(`${base.src}/image/*`, gulp.series(sprite, css));
184 | }
185 | done();
186 | }
187 |
188 | function server(done) {
189 | if (env !== 'production') {
190 | var options = {
191 | root: 'docs',
192 | port: 8080,
193 | livereload: true,
194 | };
195 | connect.server(options);
196 | }
197 | done();
198 | };
199 |
200 | const resource = gulp.series(js, gulp.parallel(html, css, img, font))
201 | const build = gulp.series(clean, sprite, resource, beforeEnd, gulp.parallel(watch, server))
202 |
203 | exports.clean = clean;
204 | exports.default = build;
205 | exports.js = js;
206 | exports.css = css
207 | exports.img = img
208 | exports.beforeEnd = beforeEnd
209 | exports.sprite = gulp.series(sprite, css);
--------------------------------------------------------------------------------
/src/image/theme_dark_character.svg:
--------------------------------------------------------------------------------
1 |
48 |
--------------------------------------------------------------------------------
/src/image/img_student_experence.svg:
--------------------------------------------------------------------------------
1 |
45 |
--------------------------------------------------------------------------------
/src/image/sprite/img_about_teacher.svg:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/src/image/sprite/icon_methods_1.svg:
--------------------------------------------------------------------------------
1 |
40 |
--------------------------------------------------------------------------------