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"]
}

4
.gitignore vendored
View File

@@ -198,4 +198,6 @@ notes
.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 NODE_ENV=production
WORKDIR /app
COPY ["package.json", "package-lock.json*", "./"]
RUN npm install && npm install nodemon
RUN npm install
RUN npm install nodemon
COPY . .
RUN npm run build-tailwind
CMD [ "npm", "start" ]

View File

@@ -1,5 +1,5 @@
# 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

70
app.js
View File

@@ -4,7 +4,7 @@ var path = require('path');
var cookieParser = require('cookie-parser');
var mLogger = require('morgan');
var logger = require('./config/winston');
const helmet = require("helmet");
const helmet = require('helmet');
var indexRouter = require('./routes/index');
var aboutRouter = require('./routes/about');
@@ -12,7 +12,8 @@ var contactRouter = require('./routes/contact');
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');
// view engine setup
@@ -20,26 +21,43 @@ app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
if (process.env.NODE_ENV === 'production') {
app.use(mLogger("common", { "stream": logger.stream }));
app.use(mLogger('common', { stream: logger.stream }));
} else {
app.use(mLogger('dev'));
app.use(mLogger('dev'));
}
app.use(helmet());
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "https://hcaptcha.com", "https://*.hcaptcha.com", "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: [],
},
})
);
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: [
"'self'",
"'unsafe-inline'",
"'unsafe-eval'",
'https://hcaptcha.com',
'https://*.hcaptcha.com',
'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.urlencoded({ extended: false }));
@@ -51,19 +69,19 @@ app.use('/about', aboutRouter);
app.use('/contact', contactRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
app.use(function (err, req, res, _next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error', { title: 'Error', description: "Error" });
// render the error page
res.status(err.status || 500);
res.render('error', { title: 'Error', description: 'Error' });
});
module.exports = app;

64
bin/www
View File

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

View File

@@ -2,29 +2,29 @@ var winston = require('winston');
var appRoot = require('app-root-path');
var logger = new winston.createLogger({
transports: [
new winston.transports.File({
level: 'info',
filename: `${appRoot}/logs/app.log`,
handleExceptions: true,
json: true,
maxsize: 5242880, //5MB
maxFiles: 5,
colorize: false
}),
new winston.transports.Console({
level: 'debug',
handleExceptions: true,
json: false,
colorize: true
})
],
exitOnError: false
transports: [
new winston.transports.File({
level: 'info',
filename: `${appRoot}/logs/app.log`,
handleExceptions: true,
json: true,
maxsize: 5242880, //5MB
maxFiles: 5,
colorize: false,
}),
new winston.transports.Console({
level: 'debug',
handleExceptions: true,
json: false,
colorize: true,
}),
],
exitOnError: false,
});
logger.stream = {
write: function(message, encoding){
logger.info(message);
}
write: function (message, _encoding) {
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",
"version": "0.0.0",
"private": true,
"watch": {
"build-tailwind": {
"patterns": [
"views/"
],
"extensions": "pug"
}
},
"scripts": {
"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": {
"@sendgrid/mail": "^7.4.4",
"@sendgrid/mail": "^8.1.3",
"app-root-path": "^3.0.0",
"axios": "^0.21.2",
"autoprefixer": "^10.3.4",
"axios": "^1.6.8",
"cookie-parser": "^1.4.5",
"debug": "^4.3.1",
"express": "^4.17.1",
"express-rate-limit": "^5.2.6",
"hcaptcha": "^0.0.2",
"helmet": "^4.6.0",
"http-errors": "^1.8.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",
"tailwind-hamburgers": "^1.1.1",
"tailwindcss": "^2.2.15",
"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 () {
$('.ham-button').on('click', function () {
$('.ham').toggleClass('open');
$('#menu').on('click', function () {
$('#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();
/* GET home page. */
router.get('/', function(req, res, next) {
const GHOST_KEY = process.env.GHOST_KEY
const base_url = `https://blog.pastel.codes/ghost/api/v3/content/posts/?key=${GHOST_KEY}`
router.get('/', function (req, res, _next) {
const GHOST_KEY = process.env.GHOST_KEY;
const base_url = `https://blog.pastel.codes/ghost/api/v3/content/posts/?key=${GHOST_KEY}`;
axios.all([
axios.get(`${base_url}&limit=3`),
axios.get(`${base_url}&limit=3&filter=tag:project`),
axios
.all([
axios.get(`${base_url}&limit=3`),
axios.get(`${base_url}&limit=3&filter=tag:project`),
])
.then(axios.spread((response1, response2) => {
var base = { title: 'About', 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);
.then(
axios.spread((response1, response2) => {
var base = {
title: 'About',
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);
}))
.catch(error => {
console.log(error);
});
res.render('about', out);
})
)
.catch((error) => {
console.log(error);
});
});
module.exports = router;

View File

@@ -1,73 +1,80 @@
var express = require('express');
var rate_limit = require("express-rate-limit")
const {verify} = require('hcaptcha');
const nodemailer = require('nodemailer')
var rate_limit = require('express-rate-limit');
const { verify } = require('hcaptcha');
var router = express.Router();
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const contact_rate_limit = rate_limit({
windowMs: 10 * 60 * 1000, // 10 minutes
max: 5, // limit each IP to 10 requests per windowMs
message: "Too many contact requests, try again later.",
handler: function (req, res /*, next*/) {
res.render('error', {
title: "Error",
message: "Too many contact requests, try again later.",
error: {status: null}
})
},
windowMs: 10 * 60 * 1000, // 10 minutes
max: 5, // limit each IP to 10 requests per windowMs
message: 'Too many contact requests, try again later.',
handler: function (req, res /*, next*/) {
res.render('error', {
title: 'Error',
message: 'Too many contact requests, try again later.',
error: { status: null },
});
},
});
// POST route from contact form
router.post('/', contact_rate_limit, (req, res) => {
const TO_MAIL_USER = process.env.TO_MAIL_USER
const FROM_MAIL_USER = process.env.FROM_MAIL_USER
const HCAPTCHA_KEY = process.env.HCAPTCHA_KEY
const REPLY_TO_MAIL = process.env.REPLY_TO_MAIL
const token = req.body["g-recaptcha-response"];
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
const TO_MAIL_USER = process.env.TO_MAIL_USER;
const FROM_MAIL_USER = process.env.FROM_MAIL_USER;
const HCAPTCHA_KEY = process.env.HCAPTCHA_KEY;
const REPLY_TO_MAIL = process.env.REPLY_TO_MAIL;
const token = req.body['g-recaptcha-response'];
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
verify(HCAPTCHA_KEY, token)
.then((data) => {
if (data.success === true) {
const msg = {
to: TO_MAIL_USER,
from: FROM_MAIL_USER,
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}`
};
verify(HCAPTCHA_KEY, token)
.then((data) => {
if (data.success === true) {
const msg = {
to: TO_MAIL_USER,
from: FROM_MAIL_USER,
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}`,
};
sgMail
.send(msg)
.then(() => {
res.render('contact', {
title: 'Contact',
message: "I will get back to you soon!",
success: "Make sure the email is from ",
email: REPLY_TO_MAIL
})
})
.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 => {
sgMail
.send(msg)
.then(() => {
res.render('contact', {
title: 'Contact',
message: 'I will get back to you soon!',
success: 'Make sure the email is from ',
email: REPLY_TO_MAIL,
});
})
.catch((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. */
router.get('/', function (req, res, next) {
res.render('contact', {title: 'Contact', description: "Contact me!"});
router.get('/', function (req, res, _next) {
res.render('contact', { title: 'Contact', description: 'Contact me!' });
});
module.exports = router;

View File

@@ -2,8 +2,8 @@ var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Home', description: "Hello, I'm E" });
router.get('/', function (req, res, _next) {
res.render('index', { title: 'Home', description: "Hello, I'm E" });
});
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
block nav-links
li.nav-item
a.nav-link(href='/')
a(href='/')
li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Home
li.nav-item.active
a.nav-link(href='#')
a(href='#')
li(class="py-3 bg-black text-green hover:bg-pink hover:text-black transition duration-500 ease-in-out")
span About
li.nav-item
a.nav-link(href='#')
a(href='#')
li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span CV
li.nav-item
a.nav-link(href='https://github.com/aurora-dot')
a(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
li.nav-item
a.nav-link(href='https://blog.pastel.codes')
a(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
li.nav-item
a.nav-link(href='/contact')
a(href='/contact')
li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Contact
block content
.container
.about-pos
.row
.col
h1
span Hello.
p Im E, a 20 year old student in 3rd year of university, who studies computer science & artificial intelligence.
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.
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
.row
.col.start
h1
span Projects.
.row
div.mt-5
div.text-lg
h1.font-sans.text-6xl.wavy.mb-10 Hello.
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.
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.
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.mb-5 Currently I am working as a freelance developer for Bounce Technologies!
div
h1.font-sans.text-6xl.wavy.my-10 Projects.
div
each val in project
.col
.pr
a(href=val.url)
div(class="mb-10 text-center sm:text-left")
div.contents
a(href=val.url).contents
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
img(src="/images/logo.png")
.pr-text
div.mt-2
a(href=val.url)
h1 #{val.title}
p #{val.excerpt}
span(class="font-sans text-2xl sm:text-3xl mt-3 mb-3") #{val.title}
p.text-lg #{val.excerpt}
.row
.col.start
h1
span Blog.
.row
div
h1.font-sans.text-6xl.wavy.my-10 Blog.
div
each val in blog
.col
.pr
a(href=val.url)
div(class="mb-10 text-center sm:text-left")
div.contents
a(href=val.url).contents
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
img(src="/images/logo.png")
.pr-text
div.mt-2
a(href=val.url)
h1 #{val.title}
p #{val.excerpt}
span(class="font-sans text-2xl sm:text-3xl mt-3 mb-3") #{val.title}
p.text-lg #{val.excerpt}

View File

@@ -4,57 +4,56 @@ block head
script(src='https://hcaptcha.com/1/api.js' async='' defer='defer')
block nav-links
li.nav-item
a.nav-link(href='/')
a(href='/')
li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Home
li.nav-item
a.nav-link(href='/about')
a(href='/about')
li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span About
li.nav-item
a.nav-link(href='#')
a(href='#')
li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span CV
li.nav-item
a.nav-link(href='https://github.com/aurora-dot')
a(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
li.nav-item
a.nav-link(href='https://blog.pastel.codes')
a(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
li.nav-item.active
a.nav-link(href='#')
a(href='#')
li(class="py-3 bg-black text-green hover:bg-pink hover:text-black transition duration-500 ease-in-out")
span Contact
block content
.container
.row
.col
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,}$")
div.w-full
div
h1.font-sans.text-6xl.wavy.mb-10 Contact.
.form-group
label(for='email') Email
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}$")
.form-group
label(for='message') Message
textarea#message(name='message' class="form-control" placeholder='Enter your message here' rows='3' required='true')
.form-group(style="margin-bottom: 0.5rem")
.h-captcha(data-sitekey='49abba50-1813-4ab3-acbf-2a8bfff1f7c3')
button(type='submit' class="button-c") Submit
div
form#contact-form(action='/contact' method='post' role='form')
div.mb-5
label Name
div(class="sm:flex sm:flex-row")
.flex.w-full
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")
div(class="mb-3 sm:mb-0 sm:ml-5")
.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
.col
if message
div.mb-5
label(for='email') Email
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
p=message
if success
p=success
span#email=email
span#email.text-green=email

View File

@@ -1,73 +1,69 @@
extends layout
block nav-links
li.nav-item.active
a.nav-link(href='#')
a(href='#')
li(class="py-3 bg-black text-green hover:bg-pink hover:text-black transition duration-500 ease-in-out")
span Home
li.nav-item
a.nav-link(href='/about')
a(href='/about')
li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span About
li.nav-item
a.nav-link(href='#')
a(href='#')
li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span CV
li.nav-item
a.nav-link(href='https://github.com/aurora-dot')
a(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
li.nav-item
a.nav-link(href='https://blog.pastel.codes')
a(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
li.nav-item
a.nav-link(href='/contact')
a(href='/contact')
li(class="py-3 bg-pink text-black hover:bg-black hover:text-pink transition duration-500 ease-in-out")
span Contact
block content
.container-fluid
.row
.col-sm-2
.center-v.col-sm-4.aaa.ef
div
h1
| Hello,
br
| I'm
|
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')
div(class="flex sm:w-2/4 items-center sm:my-0 mt-10 mb-16")
div.text-2xl
h1(class="font-sans text-7xl pb-5 sm:pb-10")
| Hello,
br
| I'm
|
span.wavy E
p I'm a Programmer &amp; Designer from the UK.
p.pt-5 I like to make stuff.
.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
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='16x16' href='/images/favicon-16x16.png')
link(rel='stylesheet', href='/stylesheets/bootstrap.css')
link(rel='stylesheet', href='/stylesheets/style.css')
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
footer
p &copy; 2020 |
|
|
a(href="/") EEEE.
footer.w-full.text-center.p-4.text-base
p.font-mono &copy; 2020 |
|
|
a(href="/").underline EEEE.
script(src="/javascript/jquery-3.5.1.min.js")
script(src="/javascript/bootstrap.js")
script(src="/javascript/nav.js")
block scripts