Compare commits

...

10 Commits

Author SHA1 Message Date
snyk-bot
7ff9f6f361 fix: package.json & package-lock.json to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-SEMVER-3247795
2024-04-29 12:21:39 +00:00
E
8449b30401 Add linting, formatting and pre-commit (#53)
* Add dev-dependancies

* Security update npm packages

* Force audit fix

* Add linting, formatting and precommit

* Format files
2024-04-29 13:21:31 +01:00
E
80813d48e3 Fix UI issues on desktop and mobile (#31) 2021-09-12 11:48:35 +01:00
Snyk bot
96d69992a0 fix: package.json & package-lock.json to reduce vulnerabilities (#29)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-AXIOS-1579269
2021-09-12 08:54:00 +01:00
Snyk bot
138a8de86c fix: package.json & package-lock.json to reduce vulnerabilities (#28)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-NODEMAILER-1296415
2021-09-12 08:51:36 +01:00
Snyk bot
7d230410f1 fix: package.json & package-lock.json to reduce vulnerabilities (#27)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-AXIOS-1579269
2021-09-12 08:49:42 +01:00
Snyk bot
6850b3152e fix: package.json & package-lock.json to reduce vulnerabilities (#25)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-NODEMAILER-1296415
2021-09-12 08:48:17 +01:00
Snyk bot
fc85964ed9 fix: Dockerfile to reduce vulnerabilities (#26)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-DEBIAN10-GLIBC-1315333
- https://snyk.io/vuln/SNYK-DEBIAN10-PYTHON27-1063178
- https://snyk.io/vuln/SNYK-DEBIAN10-PYTHON27-1063178
- https://snyk.io/vuln/SNYK-DEBIAN10-PYTHON27-1063178
- https://snyk.io/vuln/SNYK-DEBIAN10-PYTHON27-1063178
2021-09-12 08:48:01 +01:00
E
de6ab6277b Fix incorrect command and split into several runs (#19)
* Change node version in Dockerfile and steps

* Change name of scripts in package.json
2021-09-11 22:07:23 +01:00
E
61a0713ad5 Switch to tailwind (#16)
* Add tailwind to project
* Adapt previous design into tailwind
* Remove bootstrap
* Fix docker steps
2021-09-11 21:32:23 +01:00
42 changed files with 7342 additions and 27193 deletions

15
.editorconfig Normal file
View File

@@ -0,0 +1,15 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false
[pug.ts]
indent_size = 4

3
.eslintrc.json Normal file
View File

@@ -0,0 +1,3 @@
{
"extends": ["prettier"]
}

2
.gitignore vendored
View File

@@ -199,3 +199,5 @@ notes
.secrets .secrets
public/stylesheets/style.css public/stylesheets/style.css
ngrok
.dccache

1
.husky/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
_

4
.husky/pre-commit Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged

8
.prettierrc.json Normal file
View File

@@ -0,0 +1,8 @@
{
"trailingComma": "es5",
"semi": true,
"tabWidth": 2,
"singleQuote": true,
"jsxSingleQuote": true,
"plugins": ["prettier-plugin-tailwindcss"]
}

View File

@@ -1,11 +1,13 @@
FROM node:10.19.0 FROM node:16-bullseye-slim
ENV IS_DOCKER=true ENV IS_DOCKER=true
ENV NODE_ENV=production ENV NODE_ENV=production
WORKDIR /app WORKDIR /app
COPY ["package.json", "package-lock.json*", "./"] COPY ["package.json", "package-lock.json*", "./"]
RUN npm install && npm install nodemon RUN npm install
RUN npm install nodemon
COPY . . COPY . .
RUN npm run build-tailwind
CMD [ "npm", "start" ] CMD [ "npm", "start" ]

View File

@@ -1,5 +1,5 @@
# pastel.codes # pastel.codes
My portfolio website written in node.js, pug and sass My portfolio website written in node.js, pug and tailwind
Docker image: https://hub.docker.com/r/auroradot/pastel.codes Docker image: https://hub.docker.com/r/auroradot/pastel.codes

70
app.js
View File

@@ -4,7 +4,7 @@ var path = require('path');
var cookieParser = require('cookie-parser'); var cookieParser = require('cookie-parser');
var mLogger = require('morgan'); var mLogger = require('morgan');
var logger = require('./config/winston'); var logger = require('./config/winston');
const helmet = require("helmet"); const helmet = require('helmet');
var indexRouter = require('./routes/index'); var indexRouter = require('./routes/index');
var aboutRouter = require('./routes/about'); var aboutRouter = require('./routes/about');
@@ -12,7 +12,8 @@ var contactRouter = require('./routes/contact');
var app = express(); var app = express();
if (process.env.IS_DOCKER != 'true') app.set('trust proxy', 'loopback,uniquelocal'); if (process.env.IS_DOCKER != 'true')
app.set('trust proxy', 'loopback,uniquelocal');
app.disable('x-powered-by'); app.disable('x-powered-by');
// view engine setup // view engine setup
@@ -20,26 +21,43 @@ app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug'); app.set('view engine', 'pug');
if (process.env.NODE_ENV === 'production') { if (process.env.NODE_ENV === 'production') {
app.use(mLogger("common", { "stream": logger.stream })); app.use(mLogger('common', { stream: logger.stream }));
} else { } else {
app.use(mLogger('dev')); app.use(mLogger('dev'));
} }
app.use(helmet()); app.use(helmet());
app.use( app.use(
helmet.contentSecurityPolicy({ helmet.contentSecurityPolicy({
directives: { directives: {
defaultSrc: ["'self'"], defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "https://hcaptcha.com", "https://*.hcaptcha.com", "https://cdn.ravenjs.com/"], scriptSrc: [
imgSrc: ["'self'", "https://blog.pastel.codes", "https://static.ghost.org", "https://secure.gravatar.com"], "'self'",
styleSrc: ["'self'", "'unsafe-inline'", "https://hcaptcha.com", "https://*.hcaptcha.com"], "'unsafe-inline'",
fontSrc: ["'self'", "data:"], "'unsafe-eval'",
frameSrc: ["https://hcaptcha.com", "https://*.hcaptcha.com"], 'https://hcaptcha.com',
objectSrc: ["'none'"], 'https://*.hcaptcha.com',
upgradeInsecureRequests: [], 'https://cdn.ravenjs.com/',
}, ],
}) imgSrc: [
); "'self'",
'https://blog.pastel.codes',
'https://static.ghost.org',
'https://secure.gravatar.com',
],
styleSrc: [
"'self'",
"'unsafe-inline'",
'https://hcaptcha.com',
'https://*.hcaptcha.com',
],
fontSrc: ["'self'", 'data:'],
frameSrc: ['https://hcaptcha.com', 'https://*.hcaptcha.com'],
objectSrc: ["'none'"],
upgradeInsecureRequests: [],
},
})
);
app.use(express.json()); app.use(express.json());
app.use(express.urlencoded({ extended: false })); app.use(express.urlencoded({ extended: false }));
@@ -51,19 +69,19 @@ app.use('/about', aboutRouter);
app.use('/contact', contactRouter); app.use('/contact', contactRouter);
// catch 404 and forward to error handler // catch 404 and forward to error handler
app.use(function(req, res, next) { app.use(function (req, res, next) {
next(createError(404)); next(createError(404));
}); });
// error handler // error handler
app.use(function(err, req, res, next) { app.use(function (err, req, res, _next) {
// set locals, only providing error in development // set locals, only providing error in development
res.locals.message = err.message; res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {}; res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page // render the error page
res.status(err.status || 500); res.status(err.status || 500);
res.render('error', { title: 'Error', description: "Error" }); res.render('error', { title: 'Error', description: 'Error' });
}); });
module.exports = app; module.exports = app;

64
bin/www
View File

@@ -35,19 +35,19 @@ server.on('listening', onListening);
*/ */
function normalizePort(val) { function normalizePort(val) {
var port = parseInt(val, 10); var port = parseInt(val, 10);
if (isNaN(port)) { if (isNaN(port)) {
// named pipe // named pipe
return val; return val;
} }
if (port >= 0) { if (port >= 0) {
// port number // port number
return port; return port;
} }
return false; return false;
} }
/** /**
@@ -55,27 +55,25 @@ function normalizePort(val) {
*/ */
function onError(error) { function onError(error) {
if (error.syscall !== 'listen') { if (error.syscall !== 'listen') {
throw error; throw error;
} }
var bind = typeof port === 'string' var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages // handle specific listen errors with friendly messages
switch (error.code) { switch (error.code) {
case 'EACCES': case 'EACCES':
console.error(bind + ' requires elevated privileges'); console.error(bind + ' requires elevated privileges');
process.exit(1); process.exit(1);
break; break;
case 'EADDRINUSE': case 'EADDRINUSE':
console.error(bind + ' is already in use'); console.error(bind + ' is already in use');
process.exit(1); process.exit(1);
break; break;
default: default:
throw error; throw error;
} }
} }
/** /**
@@ -83,9 +81,7 @@ function onError(error) {
*/ */
function onListening() { function onListening() {
var addr = server.address(); var addr = server.address();
var bind = typeof addr === 'string' var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
? 'pipe ' + addr debug('Listening on ' + bind);
: 'port ' + addr.port;
debug('Listening on ' + bind);
} }

View File

@@ -2,29 +2,29 @@ var winston = require('winston');
var appRoot = require('app-root-path'); var appRoot = require('app-root-path');
var logger = new winston.createLogger({ var logger = new winston.createLogger({
transports: [ transports: [
new winston.transports.File({ new winston.transports.File({
level: 'info', level: 'info',
filename: `${appRoot}/logs/app.log`, filename: `${appRoot}/logs/app.log`,
handleExceptions: true, handleExceptions: true,
json: true, json: true,
maxsize: 5242880, //5MB maxsize: 5242880, //5MB
maxFiles: 5, maxFiles: 5,
colorize: false colorize: false,
}), }),
new winston.transports.Console({ new winston.transports.Console({
level: 'debug', level: 'debug',
handleExceptions: true, handleExceptions: true,
json: false, json: false,
colorize: true colorize: true,
}) }),
], ],
exitOnError: false exitOnError: false,
}); });
logger.stream = { logger.stream = {
write: function(message, encoding){ write: function (message, _encoding) {
logger.info(message); logger.info(message);
} },
}; };
module.exports = logger module.exports = logger;

20
eslint.config.mjs Normal file
View File

@@ -0,0 +1,20 @@
import globals from 'globals';
import pluginJs from '@eslint/js';
export default [
{ files: ['**/*.js'], languageOptions: { sourceType: 'commonjs' } },
{ languageOptions: { globals: { ...globals.browser, ...globals.node } } },
pluginJs.configs.recommended,
{
rules: {
'no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
},
},
];

6970
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,24 +2,56 @@
"name": "pastel.codes", "name": "pastel.codes",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"watch": {
"build-tailwind": {
"patterns": [
"views/"
],
"extensions": "pug"
}
},
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"start": "npx node-sass -r public/stylesheets/style.sass -o public/stylesheets && npx nodemon ./bin/www -e js,pug,sass" "dev": "npx nodemon ./bin/www -e js,pug,sass",
"start": "npx ./bin/www -e js,pug,sass",
"watch-tailwind": "npx npm-watch",
"build-tailwind": "npx postcss src/tailwind.css -o public/stylesheets/style.css",
"lint": "prettier --check . && eslint .",
"format": "prettier --write --ignore-path .gitignore .",
"prepare": "husky install"
}, },
"dependencies": { "dependencies": {
"@sendgrid/mail": "^7.4.4", "@sendgrid/mail": "^8.1.3",
"app-root-path": "^3.0.0", "app-root-path": "^3.0.0",
"axios": "^0.21.2", "autoprefixer": "^10.3.4",
"axios": "^1.6.8",
"cookie-parser": "^1.4.5", "cookie-parser": "^1.4.5",
"debug": "^4.3.1",
"express": "^4.17.1", "express": "^4.17.1",
"express-rate-limit": "^5.2.6", "express-rate-limit": "^5.2.6",
"hcaptcha": "^0.0.2", "hcaptcha": "^0.0.2",
"helmet": "^4.6.0", "helmet": "^4.6.0",
"http-errors": "^1.8.0", "http-errors": "^1.8.0",
"morgan": "^1.10.0", "morgan": "^1.10.0",
"nodemailer": "^6.6.0", "nodemailer": "^6.6.1",
"npm-watch": "^0.12.0",
"postcss-cli": "^8.3.1",
"pug": "^3.0.2", "pug": "^3.0.2",
"tailwind-hamburgers": "^1.1.1",
"tailwindcss": "^2.2.15",
"winston": "^3.3.3" "winston": "^3.3.3"
},
"devDependencies": {
"@eslint/js": "^9.1.1",
"eslint": "^9.1.1",
"eslint-config-prettier": "^9.1.0",
"globals": "^15.1.0",
"husky": "^9.0.11",
"lint-staged": "^15.2.2",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.14"
},
"lint-staged": {
"*.js": "eslint --cache --fix",
"*.{js,css,md,pug}": "prettier --write"
} }
} }

3
postcss.config.js Normal file
View File

@@ -0,0 +1,3 @@
module.exports = {
plugins: [require('tailwindcss'), require('autoprefixer')],
};

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,6 @@
$(document).ready(function () { $(document).ready(function () {
$('.ham-button').on('click', function () { $('#menu').on('click', function () {
$('.ham').toggleClass('open'); $('#menu').toggleClass('tham-active');
$('#menu-items').slideToggle(300);
}); });
}); });

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,327 +0,0 @@
/*!
* Bootstrap Reboot v4.4.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus:not(:focus-visible) {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]) {
color: inherit;
text-decoration: none;
}
a:not([href]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
select {
word-wrap: normal;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

View File

@@ -1,8 +0,0 @@
/*!
* Bootstrap Reboot v4.4.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]){color:inherit;text-decoration:none}a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,291 @@
$pink: #CC7A98
$black: #002234
$green: #CDE7B0
@font-face
font-family: 'Titling Gothic FB'
src: url("../fonts/TITLINGGOTHICFB-WIDE.OTF") format('opentype')
@font-face
font-family: 'Gilroy'
src: url("../fonts/Gilroy-ExtraBold.otf") format('opentype')
@font-face
font-family: 'Apercu Mono'
src: url("../fonts/ApercuMono.ttf") format('truetype')
html, body
width: 100%
height: 100%
body
background-color: $black
color: $pink
h1
font-family: "Gilroy", sans-serif
h2
font-weight: bold
font-family: "Apercu Mono", monospace
p, label, input, textarea
font-family: "Apercu Mono", monospace
label
font-size: 3vh
a:hover
color: $green
article
min-height: 100%
display: grid
grid-template-rows: auto 1fr auto
grid-template-columns: 100%
header
nav
a
span
font-size: 2rem
font-family: 'Titling Gothic FB', sans-serif
color: $pink
#navbarSupportedContent23
ul
background-color: $pink
li
transition: 0.5s
background-color: $pink
text-align: center
a
span
transition: 0.2s
color: $black
font-family: "Apercu Mono", monospace
li:hover
background-color: $black
a
span
color: $pink
.active
background-color: $black
a
span
color: $green
.active:hover
background-color: $pink
a
span
color: $black
main
padding: 0.5rem
h1
padding-bottom: 1rem
font-size: 4.5rem
span
text-decoration: underline $pink
text-decoration-style: wavy
p
font-size: 2rem
margin-bottom: 5px
footer
text-align: center
font-size: 1rem
padding: 0.5rem
a
color: $pink
text-decoration: underline $pink
.ef
max-height: 85vh
min-height: 85vh !important
.error
text-align: center
.pink-block
background-color: $pink
min-height: 100vh
.center-v
min-height: 100% /* Fallback for browsers do NOT support vh unit */
min-height: 100vh /* These two lines are counted as one :-) */
display: flex
align-items: center
.center-v-h
display: flex
justify-content: center
align-items: center
min-height: 100vh
.logos-container
width: 3.5rem
.logo
width: auto
height: 3.5rem
fill: $black
margin-bottom: 2.5rem
.logo-container
cursor: pointer
.about-pos
p
font-size: 3vh
margin-bottom: 3vh
.pr
img
width: 100%
border: 2vh solid $pink
margin-bottom: 3vh
margin-top: 1vh
.pr-text
a
color: $pink
h1
font-size: 4vh
margin-bottom: 0
padding-bottom: 0
a:hover
color: $green
p
font-size: 3vh
.start
margin-top: 3vh
#contact-message
margin-top: 2vh
p
color: $green
span
text-decoration: underline $green
.h-captcha
margin-bottom: 0.5vh
.button-c
display: inline-block
font-weight: 400
color: #212529
text-align: center
vertical-align: middle
cursor: pointer
user-select: none
border: 1px solid $black
padding: 0.375rem 0.75rem
font-size: 1rem
line-height: 1.5
border-radius: 0.25rem
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out
font-family: "Apercu Mono"
.button-c
background-color: $pink
.button-c:hover
background-color: $black
color: $pink
border-color: $pink
// Nav stuff
.ham
width: 30px
height: 20px
position: relative
margin: 0px
-webkit-transform: rotate(0deg)
-moz-transform: rotate(0deg)
-o-transform: rotate(0deg)
transform: rotate(0deg)
-webkit-transition: .5s ease-in-out
-moz-transition: .5s ease-in-out
-o-transition: .5s ease-in-out
transition: .5s ease-in-out
cursor: pointer
.ham span
display: block
position: absolute
height: 3px
width: 100%
border-radius: 9px
opacity: 1
left: 0
-webkit-transform: rotate(0deg)
-moz-transform: rotate(0deg)
-o-transform: rotate(0deg)
transform: rotate(0deg)
-webkit-transition: .25s ease-in-out
-moz-transition: .25s ease-in-out
-o-transition: .25s ease-in-out
transition: .25s ease-in-out
background: $pink
.ham span:nth-child(1)
top: 0
.ham span:nth-child(2), .ham span:nth-child(3)
top: 10px
.ham span:nth-child(4)
top: 20px
.ham.open span:nth-child(1)
top: 11px
width: 0
left: 50%
.ham.open span:nth-child(2)
-webkit-transform: rotate(45deg)
-moz-transform: rotate(45deg)
-o-transform: rotate(45deg)
transform: rotate(45deg)
.ham.open span:nth-child(3)
-webkit-transform: rotate(-45deg)
-moz-transform: rotate(-45deg)
-o-transform: rotate(-45deg)
transform: rotate(-45deg)
.ham.open span:nth-child(4)
top: 11px
width: 0
left: 50%
@media only screen and (max-height: 421px)
.pr-text
margin-bottom: 5vh !important
@media only screen and (max-width: 575px)
.logo
height: 5rem
.logos-container
width: 5rem
.aaa
min-height: 40vh !important
.aaaa
margin-top: 5vh !important
.ef
max-height: none !important
min-height: 0 !important
.ff
min-height: 82.8vh !important
@media only screen and (max-height: 815px)
.ef
max-height: none !important
min-height: 0 !important

View File

@@ -1,295 +0,0 @@
$pink: #CC7A98
$black: #002234
$green: #CDE7B0
@font-face
font-family: 'Titling Gothic FB'
src: url("../fonts/TITLINGGOTHICFB-WIDE.OTF") format('opentype')
@font-face
font-family: 'Gilroy'
src: url("../fonts/Gilroy-ExtraBold.otf") format('opentype')
@font-face
font-family: 'Apercu Mono'
src: url("../fonts/ApercuMono.ttf") format('truetype')
html, body
width: 100%
height: 100%
body
background-color: $black
color: $pink
h1
font-family: "Gilroy", sans-serif
h2
font-weight: bold
font-family: "Apercu Mono", monospace
p, label, input, textarea
font-family: "Apercu Mono", monospace
label
font-size: 3vh
a:hover
color: $green
article
min-height: 100%
display: grid
grid-template-rows: auto 1fr auto
grid-template-columns: 100%
header
nav
a
span
font-size: 2rem
font-family: 'Titling Gothic FB', sans-serif
color: $pink
#navbarSupportedContent23
ul
background-color: $pink
li
transition: 0.5s
background-color: $pink
text-align: center
a
span
transition: 0.2s
color: $black
font-family: "Apercu Mono", monospace
li:hover
background-color: $black
a
span
color: $pink
.active
background-color: $black
a
span
color: $green
.active:hover
background-color: $pink
a
span
color: $black
main
padding: 0.5rem
h1
padding-bottom: 1rem
font-size: 4.5rem
span
text-decoration: underline $pink
text-decoration-style: wavy
p
font-size: 2rem
margin-bottom: 5px
footer
text-align: center
font-size: 1rem
padding: 0.5rem
a
color: $pink
text-decoration: underline $pink
.ef
max-height: 85vh
min-height: 85vh !important
.error
text-align: center
.pink-block
background-color: $pink
min-height: 100vh
.center-v
min-height: 100% /* Fallback for browsers do NOT support vh unit */
min-height: 100vh /* These two lines are counted as one :-) */
display: flex
align-items: center
.center-v-h
display: flex
justify-content: center
align-items: center
min-height: 100vh
.logos-container
width: 3.5rem
.logo
width: auto
height: 3.5rem
fill: $black
margin-bottom: 2.5rem
.logo-container
cursor: pointer
.about-pos
p
font-size: 3vh
margin-bottom: 3vh
.pr
img
width: 100%
border: 2vh solid $pink
margin-bottom: 3vh
margin-top: 1vh
.pr-text
a
color: $pink
h1
font-size: 4vh
margin-bottom: 0
padding-bottom: 0
a:hover
color: $green
p
font-size: 3vh
.start
margin-top: 3vh
#contact-message
margin-top: 2vh
p
color: $green
span
text-decoration: underline $green
.h-captcha
margin-bottom: 0.5vh
.button-c
display: inline-block
font-weight: 400
color: #212529
text-align: center
vertical-align: middle
cursor: pointer
user-select: none
border: 1px solid $black
padding: 0.375rem 0.75rem
font-size: 1rem
line-height: 1.5
border-radius: 0.25rem
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out
font-family: "Apercu Mono"
.button-c
background-color: $pink
.button-c:hover
background-color: $black
color: $pink
border-color: $pink
// Nav stuff
.ham
width: 30px
height: 20px
position: relative
margin: 0px
-webkit-transform: rotate(0deg)
-moz-transform: rotate(0deg)
-o-transform: rotate(0deg)
transform: rotate(0deg)
-webkit-transition: .5s ease-in-out
-moz-transition: .5s ease-in-out
-o-transition: .5s ease-in-out
transition: .5s ease-in-out
cursor: pointer
.ham span
display: block
position: absolute
height: 3px
width: 100%
border-radius: 9px
opacity: 1
left: 0
-webkit-transform: rotate(0deg)
-moz-transform: rotate(0deg)
-o-transform: rotate(0deg)
transform: rotate(0deg)
-webkit-transition: .25s ease-in-out
-moz-transition: .25s ease-in-out
-o-transition: .25s ease-in-out
transition: .25s ease-in-out
background: $pink
.ham span:nth-child(1)
top: 0
.ham span:nth-child(2), .ham span:nth-child(3)
top: 10px
.ham span:nth-child(4)
top: 20px
.ham.open span:nth-child(1)
top: 11px
width: 0
left: 50%
.ham.open span:nth-child(2)
-webkit-transform: rotate(45deg)
-moz-transform: rotate(45deg)
-o-transform: rotate(45deg)
transform: rotate(45deg)
.ham.open span:nth-child(3)
-webkit-transform: rotate(-45deg)
-moz-transform: rotate(-45deg)
-o-transform: rotate(-45deg)
transform: rotate(-45deg)
.ham.open span:nth-child(4)
top: 11px
width: 0
left: 50%
@media only screen and (max-height: 421px)
.pr-text
margin-bottom: 5vh !important
@media only screen and (max-width: 575px)
.logo
height: 5rem
.logos-container
width: 5rem
.aaa
min-height: 40vh !important
.aaaa
margin-top: 5vh !important
.ef
max-height: none !important
min-height: 0 !important
.ff
min-height: 82.8vh !important
@media only screen and (max-height: 815px)
.ef
max-height: none !important
min-height: 0 !important

View File

@@ -3,25 +3,35 @@ const axios = require('axios');
var router = express.Router(); var router = express.Router();
/* GET home page. */ /* GET home page. */
router.get('/', function(req, res, next) { router.get('/', function (req, res, _next) {
const GHOST_KEY = process.env.GHOST_KEY const GHOST_KEY = process.env.GHOST_KEY;
const base_url = `https://blog.pastel.codes/ghost/api/v3/content/posts/?key=${GHOST_KEY}` const base_url = `https://blog.pastel.codes/ghost/api/v3/content/posts/?key=${GHOST_KEY}`;
axios.all([ axios
axios.get(`${base_url}&limit=3`), .all([
axios.get(`${base_url}&limit=3&filter=tag:project`), axios.get(`${base_url}&limit=3`),
axios.get(`${base_url}&limit=3&filter=tag:project`),
]) ])
.then(axios.spread((response1, response2) => { .then(
var base = { title: 'About', description: 'Who??? What??? AAAAaaa, about me.'}; axios.spread((response1, response2) => {
var blog = JSON.parse(JSON.stringify(response1.data).split('"posts":').join('"blog":')); var base = {
var projects = JSON.parse(JSON.stringify(response2.data).split('"posts":').join('"project":')); title: 'About',
var out = Object.assign(base, blog, projects); description: 'Who??? What??? AAAAaaa, about me.',
};
var blog = JSON.parse(
JSON.stringify(response1.data).split('"posts":').join('"blog":')
);
var projects = JSON.parse(
JSON.stringify(response2.data).split('"posts":').join('"project":')
);
var out = Object.assign(base, blog, projects);
res.render('about', out); res.render('about', out);
})) })
.catch(error => { )
console.log(error); .catch((error) => {
}); console.log(error);
});
}); });
module.exports = router; module.exports = router;

View File

@@ -1,73 +1,80 @@
var express = require('express'); var express = require('express');
var rate_limit = require("express-rate-limit") var rate_limit = require('express-rate-limit');
const {verify} = require('hcaptcha'); const { verify } = require('hcaptcha');
const nodemailer = require('nodemailer')
var router = express.Router(); var router = express.Router();
const sgMail = require('@sendgrid/mail'); const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY); sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const contact_rate_limit = rate_limit({ const contact_rate_limit = rate_limit({
windowMs: 10 * 60 * 1000, // 10 minutes windowMs: 10 * 60 * 1000, // 10 minutes
max: 5, // limit each IP to 10 requests per windowMs max: 5, // limit each IP to 10 requests per windowMs
message: "Too many contact requests, try again later.", message: 'Too many contact requests, try again later.',
handler: function (req, res /*, next*/) { handler: function (req, res /*, next*/) {
res.render('error', { res.render('error', {
title: "Error", title: 'Error',
message: "Too many contact requests, try again later.", message: 'Too many contact requests, try again later.',
error: {status: null} error: { status: null },
}) });
}, },
}); });
// POST route from contact form // POST route from contact form
router.post('/', contact_rate_limit, (req, res) => { router.post('/', contact_rate_limit, (req, res) => {
const TO_MAIL_USER = process.env.TO_MAIL_USER const TO_MAIL_USER = process.env.TO_MAIL_USER;
const FROM_MAIL_USER = process.env.FROM_MAIL_USER const FROM_MAIL_USER = process.env.FROM_MAIL_USER;
const HCAPTCHA_KEY = process.env.HCAPTCHA_KEY const HCAPTCHA_KEY = process.env.HCAPTCHA_KEY;
const REPLY_TO_MAIL = process.env.REPLY_TO_MAIL const REPLY_TO_MAIL = process.env.REPLY_TO_MAIL;
const token = req.body["g-recaptcha-response"]; const token = req.body['g-recaptcha-response'];
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
verify(HCAPTCHA_KEY, token) verify(HCAPTCHA_KEY, token)
.then((data) => { .then((data) => {
if (data.success === true) { if (data.success === true) {
const msg = { const msg = {
to: TO_MAIL_USER, to: TO_MAIL_USER,
from: FROM_MAIL_USER, from: FROM_MAIL_USER,
subject: 'New message from contact form at pastel.codes', subject: 'New message from contact form at pastel.codes',
text: `${req.body.firstname} ${req.body.lastname} (${req.body.email})\nsays: ${req.body.message}\n\nip: ${ip}` text: `${req.body.firstname} ${req.body.lastname} (${req.body.email})\nsays: ${req.body.message}\n\nip: ${ip}`,
}; };
sgMail sgMail
.send(msg) .send(msg)
.then(() => { .then(() => {
res.render('contact', { res.render('contact', {
title: 'Contact', title: 'Contact',
message: "I will get back to you soon!", message: 'I will get back to you soon!',
success: "Make sure the email is from ", success: 'Make sure the email is from ',
email: REPLY_TO_MAIL email: REPLY_TO_MAIL,
}) });
}) })
.catch(error => { .catch((error) => {
console.log(error)
res.render('error', {title: 'Contact', message: "Email did not send"})
});
} else {
// rerender with same info in the text box and show error message
res.render('contact', {title: 'Contact', message: "Captcha failed, try again"});
}
})
.catch(error => {
console.log(error); console.log(error);
res.render('contact', {title: 'Contact', message: "Something wrong happened, try again later"}); res.render('error', {
title: 'Contact',
message: 'Email did not send',
});
});
} else {
// rerender with same info in the text box and show error message
res.render('contact', {
title: 'Contact',
message: 'Captcha failed, try again',
}); });
}) }
})
.catch((error) => {
console.log(error);
res.render('contact', {
title: 'Contact',
message: 'Something wrong happened, try again later',
});
});
});
/* GET home page. */ /* GET home page. */
router.get('/', function (req, res, next) { router.get('/', function (req, res, _next) {
res.render('contact', {title: 'Contact', description: "Contact me!"}); res.render('contact', { title: 'Contact', description: 'Contact me!' });
}); });
module.exports = router; module.exports = router;

View File

@@ -2,8 +2,8 @@ var express = require('express');
var router = express.Router(); var router = express.Router();
/* GET home page. */ /* GET home page. */
router.get('/', function(req, res, next) { router.get('/', function (req, res, _next) {
res.render('index', { title: 'Home', description: "Hello, I'm E" }); res.render('index', { title: 'Home', description: "Hello, I'm E" });
}); });
module.exports = router; module.exports = router;

24
src/tailwind.css Normal file
View File

@@ -0,0 +1,24 @@
@tailwind base;
@tailwind components;
@font-face {
font-family: 'Titling Gothic FB';
src: url('../fonts/TITLINGGOTHICFB-WIDE.OTF') format('opentype');
}
@font-face {
font-family: 'Gilroy';
src: url('../fonts/Gilroy-ExtraBold.otf') format('opentype');
}
@font-face {
font-family: 'Apercu Mono';
src: url('../fonts/ApercuMono.ttf') format('truetype');
}
.wavy {
text-decoration: underline;
text-decoration-style: wavy;
}
@tailwind utilities;

31
tailwind.config.js Normal file
View File

@@ -0,0 +1,31 @@
module.exports = {
mode: 'jit',
purge: ['views/*.pug'],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {
fontFamily: {
extra: ['"Titling Gothic FB"'],
sans: ['Gilroy'],
mono: ['"Apercu Mono"'],
},
colors: {
transparent: 'transparent',
current: 'currentColor',
black: {
DEFAULT: '#002234',
},
pink: {
DEFAULT: '#CC7A98',
},
green: {
DEFAULT: '#CDE7B0',
},
},
},
},
variants: {
extend: {},
},
plugins: [require('tailwind-hamburgers')],
};

View File

@@ -1,68 +1,62 @@
extends layout extends layout
block nav-links block nav-links
li.nav-item a(href='/')
a.nav-link(href='/') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Home span Home
li.nav-item.active a(href='#')
a.nav-link(href='#') li(class="py-3 bg-black text-green hover:bg-pink hover:text-black transition duration-500 ease-in-out")
span About span About
li.nav-item a(href='#')
a.nav-link(href='#') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span CV span CV
li.nav-item a(href='https://github.com/aurora-dot')
a.nav-link(href='https://github.com/aurora-dot') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Projects span Projects
li.nav-item a(href='https://blog.pastel.codes')
a.nav-link(href='https://blog.pastel.codes') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Blog span Blog
li.nav-item a(href='/contact')
a.nav-link(href='/contact') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Contact span Contact
block content block content
.container div.mt-5
.about-pos div.text-lg
.row h1.font-sans.text-6xl.wavy.mb-10 Hello.
.col p.mb-5 Im E, a 20 year old student in 3rd year of university, who studies computer science & artificial intelligence, somehow achieved a 1:1 for the previous two years.
h1 p.mb-5 In my free time, I create small projects to learn new skills to be helpful for others, recently i have been focusing on Django and tailwind for my job.
span Hello. p.mb-5 Graphic design is also very fun and i enjoy making small projects to post on instagram, it has helped a lot with UX/UI design for applications.
p Im E, a 20 year old student in 3rd year of university, who studies computer science & artificial intelligence. p.mb-5 Currently I am working as a freelance developer for Bounce Technologies!
p In my free time, I create small projects to learn new skills to be helpful for others, recently i have been focusing on node.js. div
p Graphic design is also very fun and i enjoy making small projects to post on instagram, it helps with programming too which is neat h1.font-sans.text-6xl.wavy.my-10 Projects.
.row
.col.start
h1
span Projects.
.row
div
each val in project each val in project
.col div(class="mb-10 text-center sm:text-left")
.pr div.contents
a(href=val.url) a(href=val.url).contents
if val.feature_image if val.feature_image
img(src=val.feature_image) img(class="sm:w-2/3 mx-auto sm:mx-0" src=val.feature_image)
else else
img(src="/images/logo.png") img(src="/images/logo.png")
.pr-text div.mt-2
a(href=val.url) a(href=val.url)
h1 #{val.title} span(class="font-sans text-2xl sm:text-3xl mt-3 mb-3") #{val.title}
p #{val.excerpt} p.text-lg #{val.excerpt}
.row div
.col.start h1.font-sans.text-6xl.wavy.my-10 Blog.
h1 div
span Blog.
.row
each val in blog each val in blog
.col div(class="mb-10 text-center sm:text-left")
.pr div.contents
a(href=val.url) a(href=val.url).contents
if val.feature_image if val.feature_image
img(src=val.feature_image) img(class="sm:w-2/3 mx-auto sm:mx-0" src=val.feature_image)
else else
img(src="/images/logo.png") img(src="/images/logo.png")
.pr-text div.mt-2
a(href=val.url) a(href=val.url)
h1 #{val.title} span(class="font-sans text-2xl sm:text-3xl mt-3 mb-3") #{val.title}
p #{val.excerpt} p.text-lg #{val.excerpt}

View File

@@ -4,57 +4,56 @@ block head
script(src='https://hcaptcha.com/1/api.js' async='' defer='defer') script(src='https://hcaptcha.com/1/api.js' async='' defer='defer')
block nav-links block nav-links
li.nav-item a(href='/')
a.nav-link(href='/') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Home span Home
li.nav-item a(href='/about')
a.nav-link(href='/about') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span About span About
li.nav-item a(href='#')
a.nav-link(href='#') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span CV span CV
li.nav-item a(href='https://github.com/aurora-dot')
a.nav-link(href='https://github.com/aurora-dot') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Projects span Projects
li.nav-item a(href='https://blog.pastel.codes')
a.nav-link(href='https://blog.pastel.codes') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Blog span Blog
li.nav-item.active a(href='#')
a.nav-link(href='#') li(class="py-3 bg-black text-green hover:bg-pink hover:text-black transition duration-500 ease-in-out")
span Contact span Contact
block content block content
.container div.w-full
.row div
.col h1.font-sans.text-6xl.wavy.mb-10 Contact.
h1
span Contact.
.row
.col
form#contact-form(action='/contact' method='post' role='form')
.form-group
label Name
.form-row
.col
input#fname(name='firstname' class="form-control" type='text' placeholder='First name' required="true" pattern="^[\\w'\\-,.][^0-9_!¡?÷?¿/\\\\+=@#$%ˆ&*(){}|~<>;:[\\]]{2,}$")
.col
input#lname(name='lastname' class="form-control" type='text' placeholder='Last name' required="true" pattern="^[\\w'\\-,.][^0-9_!¡?÷?¿/\\\\+=@#$%ˆ&*(){}|~<>;:[\\]]{2,}$")
.form-group div
label(for='email') Email form#contact-form(action='/contact' method='post' role='form')
input#email(name='email' class="form-control" type='text' placeholder='Email (example@email.com)' required='true' pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$") div.mb-5
.form-group label Name
label(for='message') Message div(class="sm:flex sm:flex-row")
textarea#message(name='message' class="form-control" placeholder='Enter your message here' rows='3' required='true') .flex.w-full
.form-group(style="margin-bottom: 0.5rem") input#fname(class="w-full border-2 border-pink bg-black p-2 text-base" name='firstname' class="form-control" type='text' placeholder='First name' required="true")
.h-captcha(data-sitekey='49abba50-1813-4ab3-acbf-2a8bfff1f7c3') div(class="mb-3 sm:mb-0 sm:ml-5")
button(type='submit' class="button-c") Submit .flex.w-full
input#lname(class="w-full border-2 border-pink bg-black p-2 text-base" name='lastname' class="form-control" type='text' placeholder='Last name' required="true")
.row div.mb-5
.col label(for='email') Email
if message input#email(class="w-full border-2 border-pink bg-black p-2 text-base" name='email' class="form-control" type='text' placeholder='Email (example@email.com)' required='true' pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$")
div.mb-5
label(for='message') Message
textarea#message(class="w-full border-2 border-pink bg-black p-2 text-base" name='message' class="form-control" placeholder='Enter your message here' rows='3' required='true')
div(class="mb-5 justify-center sm:justify-items-start flex sm:block")
.h-captcha(data-sitekey='49abba50-1813-4ab3-acbf-2a8bfff1f7c3')
button(type='submit' class="rounded-lg px-3 py-2 bg-pink text-black text-lg hover:ring-pink hover:ring-2 hover:bg-black hover:text-pink sm:w-auto w-full sm:text-base") Submit
div
if message
div(class="mt-10 mb-6 sm:text-left text-center")
#contact-message #contact-message
p=message p=message
if success if success
p=success p=success
span#email=email span#email.text-green=email

View File

@@ -1,73 +1,69 @@
extends layout extends layout
block nav-links block nav-links
li.nav-item.active a(href='#')
a.nav-link(href='#') li(class="py-3 bg-black text-green hover:bg-pink hover:text-black transition duration-500 ease-in-out")
span Home span Home
li.nav-item a(href='/about')
a.nav-link(href='/about') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span About span About
li.nav-item a(href='#')
a.nav-link(href='#') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span CV span CV
li.nav-item a(href='https://github.com/aurora-dot')
a.nav-link(href='https://github.com/aurora-dot') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Projects span Projects
li.nav-item a(href='https://blog.pastel.codes')
a.nav-link(href='https://blog.pastel.codes') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Blog span Blog
li.nav-item a(href='/contact')
a.nav-link(href='/contact') li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Contact span Contact
block content block content
.container-fluid div(class="flex sm:w-2/4 items-center sm:my-0 mt-10 mb-16")
.row div.text-2xl
.col-sm-2 h1(class="font-sans text-7xl pb-5 sm:pb-10")
.center-v.col-sm-4.aaa.ef | Hello,
div br
h1 | I'm
| Hello, |
br span.wavy E
| I'm p I'm a Programmer &amp; Designer from the UK.
| p.pt-5 I like to make stuff.
span E
p I'm a Programmer & Designer from the UK.
p I like to make stuff.
.col-sm-2.aaaa
.col-sm.pink-block.ef
.center-v-h.ef
.logos-container
a(class="logo-container" id="email" target="_blank")
svg(class="logo" role='img' style="margin-top: 2.5rem;" viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Mail icon
path(d='M11.585 5.267c1.834 0 3.558.811 4.824 2.08v.004c0-.609.41-1.068.979-1.068h.145c.891 0 1.073.842 1.073 1.109l.005 9.475c-.063.621.64.941 1.029.543 1.521-1.564 3.342-8.038-.946-11.79-3.996-3.497-9.357-2.921-12.209-.955-3.031 2.091-4.971 6.718-3.086 11.064 2.054 4.74 7.931 6.152 11.424 4.744 1.769-.715 2.586 1.676.749 2.457-2.776 1.184-10.502 1.064-14.11-5.188C-.977 13.521-.847 6.093 5.62 2.245 10.567-.698 17.09.117 21.022 4.224c4.111 4.294 3.872 12.334-.139 15.461-1.816 1.42-4.516.037-4.498-2.031l-.019-.678c-1.265 1.256-2.948 1.988-4.782 1.988-3.625 0-6.813-3.189-6.813-6.812 0-3.659 3.189-6.885 6.814-6.885zm4.561 6.623c-.137-2.653-2.106-4.249-4.484-4.249h-.09c-2.745 0-4.268 2.159-4.268 4.61 0 2.747 1.842 4.481 4.256 4.481 2.693 0 4.464-1.973 4.592-4.306l-.006-.536z')
a(class="logo-container" href="https://github.com/aurora-dot" target="_blank")
svg(class="logo" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg")
title GitHub icon
path(d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12")
a(class="logo-container" href="https://git.pastel.codes/Blankie" target="_blank")
svg(class="logo" role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Gitea icon
path(d='M4.186 5.421C2.341 5.417-.13 6.59.006 9.531c.213 4.594 4.92 5.02 6.801 5.057.206.862 2.42 3.834 4.059 3.99h7.18c4.306-.286 7.53-13.022 5.14-13.07-3.953.186-6.296.28-8.305.296v3.975l-.626-.277-.004-3.696c-2.306-.001-4.336-.108-8.189-.298-.482-.003-1.154-.085-1.876-.087zm.261 1.625h.22c.262 2.355.688 3.732 1.55 5.836-2.2-.26-4.072-.899-4.416-3.285-.178-1.235.422-2.524 2.646-2.552zm8.557 2.315c.15.002.303.03.447.096l.749.323-.537.979a.672.597 0 0 0-.241.038.672.597 0 0 0-.405.764.672.597 0 0 0 .112.174l-.926 1.686a.672.597 0 0 0-.222.038.672.597 0 0 0-.405.764.672.597 0 0 0 .86.36.672.597 0 0 0 .404-.765.672.597 0 0 0-.158-.22l.902-1.642a.672.597 0 0 0 .293-.03.672.597 0 0 0 .213-.112c.348.146.633.265.838.366.308.152.417.253.45.365.033.11-.003.322-.177.694-.13.277-.345.67-.599 1.133a.672.597 0 0 0-.251.038.672.597 0 0 0-.405.764.672.597 0 0 0 .86.36.672.597 0 0 0 .404-.764.672.597 0 0 0-.137-.202c.251-.458.467-.852.606-1.148.188-.402.286-.701.2-.99-.086-.289-.35-.477-.7-.65-.23-.113-.517-.233-.86-.377a.672.597 0 0 0-.038-.239.672.597 0 0 0-.145-.209l.528-.963 2.924 1.263c.528.229.746.79.49 1.26l-2.01 3.68c-.257.469-.888.663-1.416.435l-4.137-1.788c-.528-.228-.747-.79-.49-1.26l2.01-3.679c.176-.323.53-.515.905-.53h.064z')
a(class="logo-container" href="https://blog.pastel.codes" target="_blank")
svg(class="logo" role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Ghost icon
path(d='M9.604 19.199H.008V24h9.597v-4.801zm14.39 0h-9.591V24h9.591v-4.801zm.003-9.599H0v4.8h23.997V9.6zM24 0h-4.801v4.801H24V0zm-9.596 0H.008v4.801h14.396V0z')
a(class="logo-container" href="https://matrix.to/#/@blankie:matrix.pastel.codes" target="_blank")
svg(class="logo" role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Matrix icon
path(d='M.632.55v22.9H2.28V24H0V0h2.28v.55zm7.043 7.26v1.157h.033c.309-.443.683-.784 1.117-1.024.433-.245.936-.365 1.5-.365.54 0 1.033.107 1.481.314.448.208.785.582 1.02 1.108.254-.374.6-.706 1.034-.992.434-.287.95-.43 1.546-.43.453 0 .872.056 1.26.167.388.11.716.286.993.53.276.245.489.559.646.951.152.392.23.863.23 1.417v5.728h-2.349V11.52c0-.286-.01-.559-.032-.812a1.755 1.755 0 0 0-.18-.66 1.106 1.106 0 0 0-.438-.448c-.194-.11-.457-.166-.785-.166-.332 0-.6.064-.803.189a1.38 1.38 0 0 0-.48.499 1.946 1.946 0 0 0-.231.696 5.56 5.56 0 0 0-.06.785v4.768h-2.35v-4.8c0-.254-.004-.503-.018-.752a2.074 2.074 0 0 0-.143-.688 1.052 1.052 0 0 0-.415-.503c-.194-.125-.476-.19-.854-.19-.111 0-.259.024-.439.074-.18.051-.36.143-.53.282-.171.138-.319.337-.439.595-.12.259-.18.6-.18 1.02v4.966H5.46V7.81zm15.693 15.64V.55H21.72V0H24v24h-2.28v-.55z')
a(class="logo-container" href="https://twitter.com/ErrorFacade" target="_blank")
svg(class="logo" role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Twitter icon
path(d='M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z')
a(class="logo-container" href="https://instagram.com/_e.psd" target="_blank")
svg(class="logo" role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Instagram icon
path(d='M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913.306.788.717 1.459 1.384 2.126.667.666 1.336 1.079 2.126 1.384.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558.788-.306 1.459-.718 2.126-1.384.666-.667 1.079-1.335 1.384-2.126.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913-.306-.789-.718-1.459-1.384-2.126C21.319 1.347 20.651.935 19.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227-.224.562-.479.96-.899 1.382-.419.419-.824.679-1.38.896-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421-.569-.224-.96-.479-1.379-.899-.421-.419-.69-.824-.9-1.38-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678c-3.405 0-6.162 2.76-6.162 6.162 0 3.405 2.76 6.162 6.162 6.162 3.405 0 6.162-2.76 6.162-6.162 0-3.405-2.76-6.162-6.162-6.162zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405c0 .795-.646 1.44-1.44 1.44-.795 0-1.44-.646-1.44-1.44 0-.794.646-1.439 1.44-1.439.793-.001 1.44.645 1.44 1.439z')
.col-sm-2 div(class="sm:w-1/4")
div(id="side-social" c class="flex bg-pink justify-center sm:w-1/4")
div(class="w-16 sm:w-14 fill-current text-black flex flex-col justify-around")
a(id="email" target="_blank")
svg.mt-5(role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Mail icon
path(d='M11.585 5.267c1.834 0 3.558.811 4.824 2.08v.004c0-.609.41-1.068.979-1.068h.145c.891 0 1.073.842 1.073 1.109l.005 9.475c-.063.621.64.941 1.029.543 1.521-1.564 3.342-8.038-.946-11.79-3.996-3.497-9.357-2.921-12.209-.955-3.031 2.091-4.971 6.718-3.086 11.064 2.054 4.74 7.931 6.152 11.424 4.744 1.769-.715 2.586 1.676.749 2.457-2.776 1.184-10.502 1.064-14.11-5.188C-.977 13.521-.847 6.093 5.62 2.245 10.567-.698 17.09.117 21.022 4.224c4.111 4.294 3.872 12.334-.139 15.461-1.816 1.42-4.516.037-4.498-2.031l-.019-.678c-1.265 1.256-2.948 1.988-4.782 1.988-3.625 0-6.813-3.189-6.813-6.812 0-3.659 3.189-6.885 6.814-6.885zm4.561 6.623c-.137-2.653-2.106-4.249-4.484-4.249h-.09c-2.745 0-4.268 2.159-4.268 4.61 0 2.747 1.842 4.481 4.256 4.481 2.693 0 4.464-1.973 4.592-4.306l-.006-.536z')
a(href="https://github.com/aurora-dot" target="_blank")
svg.mt-5(role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg")
title GitHub icon
path(d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12")
a(href="https://git.pastel.codes/Blankie" target="_blank")
svg.mt-5(role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Gitea icon
path(d='M4.186 5.421C2.341 5.417-.13 6.59.006 9.531c.213 4.594 4.92 5.02 6.801 5.057.206.862 2.42 3.834 4.059 3.99h7.18c4.306-.286 7.53-13.022 5.14-13.07-3.953.186-6.296.28-8.305.296v3.975l-.626-.277-.004-3.696c-2.306-.001-4.336-.108-8.189-.298-.482-.003-1.154-.085-1.876-.087zm.261 1.625h.22c.262 2.355.688 3.732 1.55 5.836-2.2-.26-4.072-.899-4.416-3.285-.178-1.235.422-2.524 2.646-2.552zm8.557 2.315c.15.002.303.03.447.096l.749.323-.537.979a.672.597 0 0 0-.241.038.672.597 0 0 0-.405.764.672.597 0 0 0 .112.174l-.926 1.686a.672.597 0 0 0-.222.038.672.597 0 0 0-.405.764.672.597 0 0 0 .86.36.672.597 0 0 0 .404-.765.672.597 0 0 0-.158-.22l.902-1.642a.672.597 0 0 0 .293-.03.672.597 0 0 0 .213-.112c.348.146.633.265.838.366.308.152.417.253.45.365.033.11-.003.322-.177.694-.13.277-.345.67-.599 1.133a.672.597 0 0 0-.251.038.672.597 0 0 0-.405.764.672.597 0 0 0 .86.36.672.597 0 0 0 .404-.764.672.597 0 0 0-.137-.202c.251-.458.467-.852.606-1.148.188-.402.286-.701.2-.99-.086-.289-.35-.477-.7-.65-.23-.113-.517-.233-.86-.377a.672.597 0 0 0-.038-.239.672.597 0 0 0-.145-.209l.528-.963 2.924 1.263c.528.229.746.79.49 1.26l-2.01 3.68c-.257.469-.888.663-1.416.435l-4.137-1.788c-.528-.228-.747-.79-.49-1.26l2.01-3.679c.176-.323.53-.515.905-.53h.064z')
a(href="https://blog.pastel.codes" target="_blank")
svg.mt-5(role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Ghost icon
path(d='M9.604 19.199H.008V24h9.597v-4.801zm14.39 0h-9.591V24h9.591v-4.801zm.003-9.599H0v4.8h23.997V9.6zM24 0h-4.801v4.801H24V0zm-9.596 0H.008v4.801h14.396V0z')
a(href="https://matrix.to/#/@blankie:matrix.pastel.codes" target="_blank")
svg.mt-5(role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Matrix icon
path(d='M.632.55v22.9H2.28V24H0V0h2.28v.55zm7.043 7.26v1.157h.033c.309-.443.683-.784 1.117-1.024.433-.245.936-.365 1.5-.365.54 0 1.033.107 1.481.314.448.208.785.582 1.02 1.108.254-.374.6-.706 1.034-.992.434-.287.95-.43 1.546-.43.453 0 .872.056 1.26.167.388.11.716.286.993.53.276.245.489.559.646.951.152.392.23.863.23 1.417v5.728h-2.349V11.52c0-.286-.01-.559-.032-.812a1.755 1.755 0 0 0-.18-.66 1.106 1.106 0 0 0-.438-.448c-.194-.11-.457-.166-.785-.166-.332 0-.6.064-.803.189a1.38 1.38 0 0 0-.48.499 1.946 1.946 0 0 0-.231.696 5.56 5.56 0 0 0-.06.785v4.768h-2.35v-4.8c0-.254-.004-.503-.018-.752a2.074 2.074 0 0 0-.143-.688 1.052 1.052 0 0 0-.415-.503c-.194-.125-.476-.19-.854-.19-.111 0-.259.024-.439.074-.18.051-.36.143-.53.282-.171.138-.319.337-.439.595-.12.259-.18.6-.18 1.02v4.966H5.46V7.81zm15.693 15.64V.55H21.72V0H24v24h-2.28v-.55z')
a(href="https://twitter.com/ErrorFacade" target="_blank")
svg.mt-5(role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Twitter icon
path(d='M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z')
a(href="https://instagram.com/_e.psd" target="_blank")
svg.my-5(role='img' viewbox='0 0 24 24' xmlns='http://www.w3.org/2000/svg')
title Instagram icon
path(d='M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913.306.788.717 1.459 1.384 2.126.667.666 1.336 1.079 2.126 1.384.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558.788-.306 1.459-.718 2.126-1.384.666-.667 1.079-1.335 1.384-2.126.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913-.306-.789-.718-1.459-1.384-2.126C21.319 1.347 20.651.935 19.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227-.224.562-.479.96-.899 1.382-.419.419-.824.679-1.38.896-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421-.569-.224-.96-.479-1.379-.899-.421-.419-.69-.824-.9-1.38-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678c-3.405 0-6.162 2.76-6.162 6.162 0 3.405 2.76 6.162 6.162 6.162 3.405 0 6.162-2.76 6.162-6.162 0-3.405-2.76-6.162-6.162-6.162zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405c0 .795-.646 1.44-1.44 1.44-.795 0-1.44-.646-1.44-1.44 0-.794.646-1.439 1.44-1.439.793-.001 1.44.645 1.44 1.439z')
block scripts block scripts
script(src="/javascript/index.js") script(src="/javascript/index.js")

View File

@@ -11,40 +11,36 @@ html
link(rel='icon' type='image/png' sizes='96x96' href='/images/favicon-96x96.png') link(rel='icon' type='image/png' sizes='96x96' href='/images/favicon-96x96.png')
link(rel='icon' type='image/png' sizes='16x16' href='/images/favicon-16x16.png') link(rel='icon' type='image/png' sizes='16x16' href='/images/favicon-16x16.png')
link(rel='stylesheet', href='/stylesheets/bootstrap.css')
link(rel='stylesheet', href='/stylesheets/style.css') link(rel='stylesheet', href='/stylesheets/style.css')
block head block head
body
article
header
// Navbar
nav.navbar
// Navbar brand
a.navbar-brand(href='/')
span EEEE.
// Collapse button
button.navbar-toggler.ham-button(type='button' data-toggle='collapse' data-target='#navbarSupportedContent23' aria-controls='navbarSupportedContent23' aria-expanded='false' aria-label='Toggle navigation' style='cursor: pointer;')
.ham
span
span
span
span
// Collapsible content
#navbarSupportedContent23.collapse.navbar-collapse
// Links
ul.navbar-nav.mr-auto
block nav-links
main body.flex.flex-col.min-h-screen.bg-black.text-pink.font-mono.text-xl
nav
div(class="mx-auto px-5")
div.relative.flex.items-center.justify-between.h-16
div.flex-shrink-0.flex.items-center
p.block.text-3xl.font-extra.font
a(href="/") EEEE.
div(class="absolute inset-y-0 right-0 flex items-center")
div(id="menu").tham.tham-e-squeeze.tham-w-8
div.tham-box
div(class="tham-inner bg-pink")
div
ul(class="hidden transition duration-500 ease-in-out text-center mx-5 list-none mb-5" id="menu-items")
block nav-links
main(class="flex flex-grow sm:items-stretch")
div(class="flex flex-col sm:flex-row flex-grow max-w-4xl mx-auto px-5")
block content block content
footer footer.w-full.text-center.p-4.text-base
p &copy; 2020 | p.font-mono &copy; 2020 |
| |
| |
a(href="/") EEEE. a(href="/").underline EEEE.
script(src="/javascript/jquery-3.5.1.min.js") script(src="/javascript/jquery-3.5.1.min.js")
script(src="/javascript/bootstrap.js")
script(src="/javascript/nav.js") script(src="/javascript/nav.js")
block scripts block scripts