diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4b48d59
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,112 @@
+# MACBOOK Default File
+.DS_Store
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# TypeScript v1 declaration files
+typings/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+.env.test
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+
+# Next.js build output
+.next
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and *not* Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port
+
+# others
+node_modules
+yarn.lock
+  
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..138f45f
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,10 @@
+{
+  "printWidth": 100,
+  "tabWidth": 2,
+  "singleQuote": true,
+  "trailingComma": "all",
+  "bracketSpacing": true,
+  "semi": false,
+  "useTabs": false,
+  "endOfLine": "lf"
+}
diff --git a/1-Colors/index.html b/1-Colors/index.html
new file mode 100644
index 0000000..1022c2c
--- /dev/null
+++ b/1-Colors/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+  
+  
+  Random Color Change
+  
+  
+
+
+
+
+  
+  
+
+
+
+
\ No newline at end of file
diff --git a/1-Colors/src/css/style.css b/1-Colors/src/css/style.css
new file mode 100644
index 0000000..97f38c1
--- /dev/null
+++ b/1-Colors/src/css/style.css
@@ -0,0 +1,29 @@
+html,
+body {
+  width: 100%;
+  height: 100vh;
+  overflow: hidden;
+}
+
+#app {
+  width: 100%;
+  height: 100vh;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.color-btn {
+  background-color: transparent;
+  border: 3.5px solid;
+  border-radius: 8px;
+  color: gray;
+  outline: none;
+  width: 80px;
+  height: 30px;
+  font-size: 15px;
+}
+
+.color-btn:hover {
+  background-color: #e6e6e6;
+}
diff --git a/1-Colors/src/js/App.js b/1-Colors/src/js/App.js
new file mode 100644
index 0000000..78f8dcb
--- /dev/null
+++ b/1-Colors/src/js/App.js
@@ -0,0 +1,17 @@
+export default function App({ $target }) {
+  const $background = document.getElementById('app')
+  const $button = document.createElement('button')
+  $button.className = 'color-btn'
+  $button.innerText = 'Click me'
+  $target.appendChild($button)
+
+  $button.addEventListener('click', () => {
+    onColorChange()
+  })
+
+  function onColorChange() {
+    const colors = ['#FC5C7D', '#6A82FB', '#38ef7d', '#fffbd5', 'eee8aa', '#ffdab9', '#fffaf0']
+    let num = Math.floor(Math.random() * colors.length)
+    $background.style.backgroundColor = colors[num]
+  }
+}
diff --git a/1-Colors/src/main.js b/1-Colors/src/main.js
new file mode 100644
index 0000000..7c7b3a8
--- /dev/null
+++ b/1-Colors/src/main.js
@@ -0,0 +1,7 @@
+import App from './js/App.js'
+
+const $app = document.querySelector('#app')
+
+new App({
+  $target: $app,
+})
diff --git a/2-Hex_Color/index.html b/2-Hex_Color/index.html
new file mode 100644
index 0000000..9df0995
--- /dev/null
+++ b/2-Hex_Color/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+  
+  
+  Hex Colors gradient
+  
+  
+
+
+
+
+  
+  
+
+
+
+
+
diff --git a/2-Hex_Color/src/css/reset.css b/2-Hex_Color/src/css/reset.css
new file mode 100644
index 0000000..5bca465
--- /dev/null
+++ b/2-Hex_Color/src/css/reset.css
@@ -0,0 +1,129 @@
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font-size: 100%;
+  font: inherit;
+  vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+  display: block;
+}
+body {
+  line-height: 1;
+}
+ol,
+ul {
+  list-style: none;
+}
+blockquote,
+q {
+  quotes: none;
+}
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+  content: '';
+  content: none;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+input:focus {
+  outline: none;
+}
+a {
+  color: inherit;
+  text-decoration: none;
+}
diff --git a/2-Hex_Color/src/css/style.css b/2-Hex_Color/src/css/style.css
new file mode 100644
index 0000000..7f515a4
--- /dev/null
+++ b/2-Hex_Color/src/css/style.css
@@ -0,0 +1,75 @@
+@import 'reset.css';
+
+:root {
+  --left: white;
+  --right: white;
+  --font: black;
+  --direction: to left;
+}
+
+html,
+body {
+  width: 100%;
+  height: 100vh;
+  overflow: hidden;
+}
+
+#app {
+  width: 100%;
+  height: 100vh;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background: linear-gradient(var(--direction), var(--left), var(--right));
+  -webkit-animation: colorchange 8s linear infinite alternate;
+}
+
+@-webkit-keyframes colorchange {
+  0% {
+    color: white;
+  }
+  30% {
+    color: gray;
+  }
+  60% {
+    color: darkgray;
+  }
+  100% {
+    color: black;
+  }
+}
+
+.description {
+  width: 900px;
+  font-size: 45px;
+  font-weight: bold;
+  margin-left: 3%;
+}
+
+.subDescription {
+  width: 800px;
+  font-size: 45px;
+  font-weight: bold;
+  margin-left: 7.5%;
+}
+
+.gradient {
+  width: 900px;
+  font-size: 35px;
+  font-weight: bold;
+  margin: 7% 0% 0% 7%;
+}
+
+.color_btn {
+  margin: 3% 0% 0% 43%;
+  width: 90px;
+  height: 50px;
+  font-weight: bold;
+  background: transparent;
+  border: 4px solid black;
+  border-radius: 4px;
+}
+
+.color_btn:hover {
+  background-color: var(--left);
+}
diff --git a/2-Hex_Color/src/js/App.js b/2-Hex_Color/src/js/App.js
new file mode 100644
index 0000000..e2f0623
--- /dev/null
+++ b/2-Hex_Color/src/js/App.js
@@ -0,0 +1,62 @@
+import { leftOption, rightOption, directOption } from '../utils/Constant.js'
+import Background from './Background.js'
+import Description from './Description.js'
+
+export default function App({ $target }) {
+  this.state = {
+    left: 'white',
+    right: 'white',
+    direction: 'to right',
+  }
+
+  const { left, right, direction } = this.state
+
+  const description = new Description({
+    $target,
+    initialState: {
+      left,
+      right,
+      direction,
+    },
+    onChangeColor: () => {
+      const colorRandomNum = Math.floor(Math.random() * leftOption.length)
+      const direcRandomNum = Math.floor(Math.random() * directOption.length)
+
+      const selectedLeft = leftOption[colorRandomNum]
+      const selectedRight = rightOption[colorRandomNum]
+      const selectedDirection = directOption[direcRandomNum]
+
+      this.setState({
+        left: selectedLeft,
+        right: selectedRight,
+        direction: selectedDirection,
+      })
+    },
+  })
+
+  const background = new Background({
+    $target,
+    initialState: {
+      left,
+      right,
+      direction,
+    },
+  })
+
+  this.setState = (nextState) => {
+    this.state = nextState
+
+    const { left, right, direction } = this.state
+    description.setState({
+      left,
+      right,
+      direction,
+    })
+
+    background.setState({
+      left,
+      right,
+      direction,
+    })
+  }
+}
diff --git a/2-Hex_Color/src/js/Background.js b/2-Hex_Color/src/js/Background.js
new file mode 100644
index 0000000..0dc603b
--- /dev/null
+++ b/2-Hex_Color/src/js/Background.js
@@ -0,0 +1,16 @@
+import { $setProperty } from '../utils/document.js'
+
+export default function Background({ $target, initialState }) {
+  this.state = initialState
+
+  this.setState = (nextState) => {
+    this.state = nextState
+    this.render()
+  }
+
+  this.render = () => {
+    $setProperty($target, '--left', this.state.left)
+    $setProperty($target, '--right', this.state.right)
+    $setProperty($target, '--direction', this.state.direction)
+  }
+}
diff --git a/2-Hex_Color/src/js/Description.js b/2-Hex_Color/src/js/Description.js
new file mode 100644
index 0000000..16773af
--- /dev/null
+++ b/2-Hex_Color/src/js/Description.js
@@ -0,0 +1,32 @@
+export default function Description({ $target, initialState, onChangeColor }) {
+  const $itemDiv = document.createElement('div')
+  $target.appendChild($itemDiv)
+
+  this.state = initialState
+
+  this.setState = (nextState) => {
+    this.state = nextState
+    this.render()
+  }
+
+  this.render = () => {
+    const { left, right, direction } = this.state
+
+    $itemDiv.innerHTML = `
+      CLICK THE BUTTON BELLOW TO GENERATE
+      A RANDOM  HEX COLOR COMBINATION
+      background liner-gradient(${direction}, ${left}, ${right})
+      
+    `
+  }
+
+  this.render()
+
+  $itemDiv.addEventListener('click', (e) => {
+    const { className } = e.target
+
+    if (className === 'color_btn') {
+      onChangeColor()
+    }
+  })
+}
diff --git a/2-Hex_Color/src/main.js b/2-Hex_Color/src/main.js
new file mode 100644
index 0000000..7c7b3a8
--- /dev/null
+++ b/2-Hex_Color/src/main.js
@@ -0,0 +1,7 @@
+import App from './js/App.js'
+
+const $app = document.querySelector('#app')
+
+new App({
+  $target: $app,
+})
diff --git a/2-Hex_Color/src/utils/Constant.js b/2-Hex_Color/src/utils/Constant.js
new file mode 100644
index 0000000..ce99761
--- /dev/null
+++ b/2-Hex_Color/src/utils/Constant.js
@@ -0,0 +1,29 @@
+export const leftOption = [
+  '#2193b0',
+  '#bdc3c7',
+  '#12c2e9',
+  '#1f4037',
+  '#8360c3',
+  '#E94057',
+  '#007991',
+]
+export const rightOption = [
+  '#6dd5ed',
+  '#2c3e50',
+  '#f64f59',
+  '#99f2c8',
+  '#2ebf91',
+  '#F27121',
+  '#78ffd6',
+]
+export const directOption = [
+  'to right',
+  'to left',
+  'to top',
+  'to bottom',
+  '45deg',
+  '90deg',
+  '75deg',
+  '15deg',
+  '60deg',
+]
diff --git a/2-Hex_Color/src/utils/document.js b/2-Hex_Color/src/utils/document.js
new file mode 100644
index 0000000..c0c2ded
--- /dev/null
+++ b/2-Hex_Color/src/utils/document.js
@@ -0,0 +1,2 @@
+export const $setProperty = ($target, startPoint, color) =>
+  $target.style.setProperty(startPoint, color)
diff --git a/3-Quote/index.html b/3-Quote/index.html
new file mode 100644
index 0000000..d447afc
--- /dev/null
+++ b/3-Quote/index.html
@@ -0,0 +1,26 @@
+
+
+
+
+  
+  
+  
+  
+  
+
+
+
+
+  
+      
+      
+  
+  
+
+
+
+
+
diff --git a/3-Quote/src/css/reset.css b/3-Quote/src/css/reset.css
new file mode 100644
index 0000000..5bca465
--- /dev/null
+++ b/3-Quote/src/css/reset.css
@@ -0,0 +1,129 @@
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font-size: 100%;
+  font: inherit;
+  vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+  display: block;
+}
+body {
+  line-height: 1;
+}
+ol,
+ul {
+  list-style: none;
+}
+blockquote,
+q {
+  quotes: none;
+}
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+  content: '';
+  content: none;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+input:focus {
+  outline: none;
+}
+a {
+  color: inherit;
+  text-decoration: none;
+}
diff --git a/3-Quote/src/css/style.css b/3-Quote/src/css/style.css
new file mode 100644
index 0000000..579767e
--- /dev/null
+++ b/3-Quote/src/css/style.css
@@ -0,0 +1,59 @@
+@import 'reset.css';
+
+html,
+body {
+  width: 100%;
+  height: 100vh;
+  overflow: hidden;
+}
+
+.app {
+  width: 100%;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  background: linear-gradient(to right, #5d52a2, #3683b0, #5d52a2);
+}
+
+.quote_wrapper {
+  width: 60%;
+  height: 42%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  border: 10px solid #06bdc1;
+  border-radius: 4px;
+  background-color: #f4edea;
+}
+
+.quote_text {
+  width: 750px;
+  margin-top: 12%;
+  margin-left: 5%;
+  font-size: 26px;
+  line-height: 150%;
+  text-align: center;
+}
+
+.quote_author {
+  margin-top: 5%;
+  font-size: 25px;
+}
+
+button {
+  width: 140px;
+  height: 40px;
+  font-size: 16px;
+  margin-top: 3%;
+  color: white;
+  border: none;
+  border-radius: 4px;
+  background-color: #17a2b8;
+  outline: none;
+}
+
+button:hover {
+  background-color: #138799;
+}
diff --git a/3-Quote/src/js/App.js b/3-Quote/src/js/App.js
new file mode 100644
index 0000000..ea1852c
--- /dev/null
+++ b/3-Quote/src/js/App.js
@@ -0,0 +1,15 @@
+import { request } from '../service/api.js'
+
+export default function App({ $target }) {
+  const $app = document.querySelector('.app')
+  const $text = document.querySelector('.quote_text')
+  const $author = document.querySelector('.quote_author')
+  const $button = document.querySelector('button')
+
+  $button.addEventListener('click', async (e) => {
+    const { quote, author } = await request()
+    $text.innerText = '"' + quote + '"'
+
+    $author.innerText = author ? '- ' + author : 'anonymous'
+  })
+}
diff --git a/3-Quote/src/main.js b/3-Quote/src/main.js
new file mode 100644
index 0000000..7c7b3a8
--- /dev/null
+++ b/3-Quote/src/main.js
@@ -0,0 +1,7 @@
+import App from './js/App.js'
+
+const $app = document.querySelector('#app')
+
+new App({
+  $target: $app,
+})
diff --git a/3-Quote/src/service/api.js b/3-Quote/src/service/api.js
new file mode 100644
index 0000000..833839a
--- /dev/null
+++ b/3-Quote/src/service/api.js
@@ -0,0 +1,13 @@
+export const request = async () => {
+  try {
+    const res = await fetch('https://free-quotes-api.herokuapp.com/')
+
+    if (!res.ok) {
+      throw new Error('Fail to fetch API data')
+    }
+
+    return await res.json()
+  } catch (e) {
+    alert(e.message)
+  }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..2c3a1b3
--- /dev/null
+++ b/package.json
@@ -0,0 +1,16 @@
+{
+  "scripts": {
+    "start": "node main.js",
+    "lint": "eslint *.js",
+    "lint:fix": "eslint --fix *.js"
+  },
+  "devDependencies": {
+    "eslint": "^7.32.0",
+    "eslint-config-airbnb-base": "^14.2.1",
+    "eslint-config-google": "^0.14.0",
+    "eslint-config-prettier": "^8.3.0",
+    "eslint-plugin-import": "^2.24.0",
+    "eslint-plugin-prettier": "^3.4.0",
+    "prettier": "^2.3.2"
+  }
+}