Initial Build
This commit is contained in:
parent
71cd3acccd
commit
6c0d9a3f98
140 changed files with 9802 additions and 2403 deletions
|
|
@ -5,7 +5,7 @@ root = true
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
indent_size = 4
|
indent_size = 2
|
||||||
indent_style = space
|
indent_style = space
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
|
||||||
48
.env
48
.env
|
|
@ -1,48 +0,0 @@
|
||||||
# In all environments, the following files are loaded if they exist,
|
|
||||||
# the latter taking precedence over the former:
|
|
||||||
#
|
|
||||||
# * .env contains default values for the environment variables needed by the app
|
|
||||||
# * .env.local uncommitted file with local overrides
|
|
||||||
# * .env.$APP_ENV committed environment-specific defaults
|
|
||||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
|
||||||
#
|
|
||||||
# Real environment variables win over .env files.
|
|
||||||
#
|
|
||||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
|
||||||
# https://symfony.com/doc/current/configuration/secrets.html
|
|
||||||
#
|
|
||||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
|
||||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
|
||||||
|
|
||||||
###> symfony/framework-bundle ###
|
|
||||||
APP_ENV=dev
|
|
||||||
APP_SECRET=
|
|
||||||
APP_SHARE_DIR=var/share
|
|
||||||
###< symfony/framework-bundle ###
|
|
||||||
|
|
||||||
###> symfony/routing ###
|
|
||||||
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
|
||||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
|
||||||
DEFAULT_URI=http://localhost
|
|
||||||
###< symfony/routing ###
|
|
||||||
|
|
||||||
###> doctrine/doctrine-bundle ###
|
|
||||||
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
|
||||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
|
||||||
#
|
|
||||||
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db"
|
|
||||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
|
|
||||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
|
|
||||||
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
|
|
||||||
###< doctrine/doctrine-bundle ###
|
|
||||||
|
|
||||||
###> symfony/messenger ###
|
|
||||||
# Choose one of the transports below
|
|
||||||
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
|
|
||||||
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
|
|
||||||
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
|
|
||||||
###< symfony/messenger ###
|
|
||||||
|
|
||||||
###> symfony/mailer ###
|
|
||||||
MAILER_DSN=null://null
|
|
||||||
###< symfony/mailer ###
|
|
||||||
4
.env.dev
4
.env.dev
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
###> symfony/framework-bundle ###
|
|
||||||
APP_SECRET=add2825264a0dd588b79e4681ba37d1a
|
|
||||||
###< symfony/framework-bundle ###
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# define your env variables for the test env here
|
|
||||||
KERNEL_CLASS='App\Kernel'
|
|
||||||
APP_SECRET='$ecretf0rt3st'
|
|
||||||
10
.gitignore
vendored
10
.gitignore
vendored
|
|
@ -1,4 +1,6 @@
|
||||||
|
.env
|
||||||
|
.env.dev
|
||||||
|
.env.test
|
||||||
###> symfony/framework-bundle ###
|
###> symfony/framework-bundle ###
|
||||||
/.env.local
|
/.env.local
|
||||||
/.env.local.php
|
/.env.local.php
|
||||||
|
|
@ -18,3 +20,9 @@
|
||||||
/public/assets/
|
/public/assets/
|
||||||
/assets/vendor/
|
/assets/vendor/
|
||||||
###< symfony/asset-mapper ###
|
###< symfony/asset-mapper ###
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
/assets/styles/*.css.map
|
||||||
|
###> dont upload files to repo
|
||||||
|
/public/photos
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import './stimulus_bootstrap.js';
|
|
||||||
/*
|
|
||||||
* Welcome to your app's main JavaScript file!
|
|
||||||
*
|
|
||||||
* This file will be included onto the page via the importmap() Twig function,
|
|
||||||
* which should already be in your base.html.twig.
|
|
||||||
*/
|
|
||||||
import './styles/app.css';
|
|
||||||
|
|
||||||
console.log('This log comes from assets/app.js - welcome to AssetMapper! 🎉');
|
|
||||||
100
assets/brain.js
Normal file
100
assets/brain.js
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
import './styles/brain.css';
|
||||||
|
import './stimulus_bootstrap.js';
|
||||||
|
|
||||||
|
const init = () => {
|
||||||
|
menu();
|
||||||
|
editorInit();
|
||||||
|
photosUploadInit();
|
||||||
|
};
|
||||||
|
|
||||||
|
const menu = () => {
|
||||||
|
const subMenus = document.querySelectorAll('.sub-menu--link');
|
||||||
|
|
||||||
|
subMenus.forEach((menu) => {
|
||||||
|
|
||||||
|
menu.addEventListener('mouseover', (event) => {
|
||||||
|
const targetedMenu = event.target.nextElementSibling;
|
||||||
|
|
||||||
|
const openMenu = document.querySelector('.level-2.open');
|
||||||
|
if (openMenu) {
|
||||||
|
openMenu.classList.remove('open');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetedMenu.classList.contains('open')) {
|
||||||
|
targetedMenu.classList.remove('open');
|
||||||
|
} else {
|
||||||
|
targetedMenu.classList.add('open');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const editorInit = () => {
|
||||||
|
if (document.querySelector('#post_text')) {
|
||||||
|
const editor = Jodit.make('#post_text', {
|
||||||
|
"enter": "P",
|
||||||
|
"theme": 'dark',
|
||||||
|
"disablePlugins": "ai-assistant,about",
|
||||||
|
"width": 800,
|
||||||
|
"height": 500
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.querySelector('#page_text')) {
|
||||||
|
const editor = Jodit.make('#page_text', {
|
||||||
|
"enter": "P",
|
||||||
|
"theme": 'dark',
|
||||||
|
"disablePlugins": "ai-assistant,about",
|
||||||
|
"width": 800,
|
||||||
|
"height": 500
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.querySelector('#photos_text')) {
|
||||||
|
const editor = Jodit.make('#photos_text', {
|
||||||
|
"enter": "P",
|
||||||
|
"theme": 'dark',
|
||||||
|
"disablePlugins": "ai-assistant,about",
|
||||||
|
"width": 800,
|
||||||
|
"height": 500
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const photosUploadInit = () => {
|
||||||
|
document
|
||||||
|
.querySelectorAll('.add_item_link')
|
||||||
|
.forEach(btn => {
|
||||||
|
btn.addEventListener("click", addFormToCollection)
|
||||||
|
});
|
||||||
|
|
||||||
|
function addFormToCollection(e) {
|
||||||
|
const collectionHolder = document.querySelector('#' + e.target.dataset.collectionHolderId);
|
||||||
|
const item = document.createElement('li');
|
||||||
|
|
||||||
|
let index;
|
||||||
|
|
||||||
|
if (!collectionHolder.dataset.index) {
|
||||||
|
collectionHolder.dataset.index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = collectionHolder.dataset.index;
|
||||||
|
|
||||||
|
item.innerHTML = collectionHolder
|
||||||
|
.dataset
|
||||||
|
.prototype
|
||||||
|
.replace(
|
||||||
|
/__name__/g,
|
||||||
|
index
|
||||||
|
);
|
||||||
|
|
||||||
|
collectionHolder.appendChild(item);
|
||||||
|
|
||||||
|
collectionHolder.dataset.index++;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,5 +1,16 @@
|
||||||
{
|
{
|
||||||
"controllers": {
|
"controllers": {
|
||||||
|
"@symfony/ux-autocomplete": {
|
||||||
|
"autocomplete": {
|
||||||
|
"enabled": true,
|
||||||
|
"fetch": "eager",
|
||||||
|
"autoimport": {
|
||||||
|
"tom-select/dist/css/tom-select.default.css": true,
|
||||||
|
"tom-select/dist/css/tom-select.bootstrap4.css": false,
|
||||||
|
"tom-select/dist/css/tom-select.bootstrap5.css": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@symfony/ux-turbo": {
|
"@symfony/ux-turbo": {
|
||||||
"turbo-core": {
|
"turbo-core": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|
|
||||||
57
assets/landing.js
Normal file
57
assets/landing.js
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
import './styles/landing.css';
|
||||||
|
import './stimulus_bootstrap.js';
|
||||||
|
|
||||||
|
const mobileMenu = () => {
|
||||||
|
const icon = document.querySelector('.icon-menu');
|
||||||
|
const menu = document.querySelector('.front-menu');
|
||||||
|
|
||||||
|
icon.addEventListener('click', (event) => {
|
||||||
|
icon.classList.toggle('open');
|
||||||
|
menu.classList.toggle('open');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const jobInfoToggle = () => {
|
||||||
|
const jobs = document.querySelectorAll('#work .jobs .job');
|
||||||
|
|
||||||
|
jobs.forEach((job) => {
|
||||||
|
job.addEventListener('click', (event) => {
|
||||||
|
const jobId = job.dataset.jobId;
|
||||||
|
const jobInfo = document.querySelector(`#${jobId}`);
|
||||||
|
const activeJobLabel = document.querySelector('#work .jobs .job.active');
|
||||||
|
|
||||||
|
if (jobInfo.classList.contains('hide')) {
|
||||||
|
const openJob = document.querySelector('#work .jobs .job-highlight.show');
|
||||||
|
|
||||||
|
if (jobInfo.classList.contains('hide')) {
|
||||||
|
|
||||||
|
jobInfo.classList.remove('hide');
|
||||||
|
jobInfo.classList.add('show');
|
||||||
|
openJob.classList.remove('show');
|
||||||
|
openJob.classList.add('hide');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!job.classList.contains('active')) {
|
||||||
|
job.classList.add('active');
|
||||||
|
activeJobLabel.classList.remove('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollTo = () => {
|
||||||
|
const links = document.querySelectorAll('#outro .menu a');
|
||||||
|
|
||||||
|
links.forEach((link) => {
|
||||||
|
link.addEventListener('click', (event) => {
|
||||||
|
const anchor = link.dataset.scrollTo;
|
||||||
|
const element = document.querySelector(`#${anchor}`).scrollIntoView();
|
||||||
|
window.history.pushState({}, '', `#${anchor}`);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
mobileMenu();
|
||||||
|
jobInfoToggle();
|
||||||
|
scrollTo();
|
||||||
52
assets/main.js
Normal file
52
assets/main.js
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import './stimulus_bootstrap.js';
|
||||||
|
import './styles/main.css';
|
||||||
|
|
||||||
|
const mobileMenu = () => {
|
||||||
|
const icon = document.querySelector('.icon-menu');
|
||||||
|
const menu = document.querySelector('.menu');
|
||||||
|
const header = document.querySelector('header');
|
||||||
|
const body = document.querySelector('body');
|
||||||
|
|
||||||
|
icon.addEventListener('click', (event) => {
|
||||||
|
icon.classList.toggle('open');
|
||||||
|
menu.classList.toggle('open');
|
||||||
|
header.classList.toggle('open');
|
||||||
|
body.classList.toggle('menu-open');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const album = () => {
|
||||||
|
const album = document.querySelector('#album');
|
||||||
|
|
||||||
|
if (album) {
|
||||||
|
const photos = album.querySelectorAll('.photo');
|
||||||
|
const openImageContainer = document.querySelector('#open-image');
|
||||||
|
const close = openImageContainer.querySelector('.close');
|
||||||
|
|
||||||
|
photos.forEach((photo) => {
|
||||||
|
photo.addEventListener('click', (event) => {
|
||||||
|
const dataset = photo.dataset;
|
||||||
|
openImageContainer.querySelector('#image').setAttribute('src', dataset.url);
|
||||||
|
openImageContainer.querySelector('#image').setAttribute('alt', dataset.alt);
|
||||||
|
openImageContainer.querySelector('#caption').innerHTML = dataset.caption;
|
||||||
|
openImageContainer.querySelector('#date').innerHTML = `Date Taken: ${dataset.date}`;
|
||||||
|
openImageContainer.querySelector('#location').innerHTML = `Location: ${dataset.location}`;
|
||||||
|
openImageContainer.querySelector('#equipment').innerHTML = `Camera Used: ${dataset.equipment}`;
|
||||||
|
openImageContainer.classList.toggle('open');
|
||||||
|
document.querySelector('body').classList.toggle('photo-open');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
close.addEventListener('click', (event) => {
|
||||||
|
if (openImageContainer.classList.contains('open')) {
|
||||||
|
openImageContainer.classList.remove('open');
|
||||||
|
document.querySelector('body').classList.remove('photo-open');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mobileMenu();
|
||||||
|
album();
|
||||||
446
assets/package-lock.json
generated
Normal file
446
assets/package-lock.json
generated
Normal file
|
|
@ -0,0 +1,446 @@
|
||||||
|
{
|
||||||
|
"name": "brain",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "brain",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"sass": "^1.100.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"detect-libc": "^2.0.3",
|
||||||
|
"is-glob": "^4.0.3",
|
||||||
|
"node-addon-api": "^7.0.0",
|
||||||
|
"picomatch": "^4.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@parcel/watcher-android-arm64": "2.5.6",
|
||||||
|
"@parcel/watcher-darwin-arm64": "2.5.6",
|
||||||
|
"@parcel/watcher-darwin-x64": "2.5.6",
|
||||||
|
"@parcel/watcher-freebsd-x64": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-arm-glibc": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-arm-musl": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-arm64-glibc": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-arm64-musl": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-x64-glibc": "2.5.6",
|
||||||
|
"@parcel/watcher-linux-x64-musl": "2.5.6",
|
||||||
|
"@parcel/watcher-win32-arm64": "2.5.6",
|
||||||
|
"@parcel/watcher-win32-ia32": "2.5.6",
|
||||||
|
"@parcel/watcher-win32-x64": "2.5.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-android-arm64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-darwin-arm64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-darwin-x64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-freebsd-x64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-arm-glibc": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"libc": [
|
||||||
|
"glibc"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-arm-musl": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"libc": [
|
||||||
|
"musl"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-arm64-glibc": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"libc": [
|
||||||
|
"glibc"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-arm64-musl": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"libc": [
|
||||||
|
"musl"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-x64-glibc": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"libc": [
|
||||||
|
"glibc"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-linux-x64-musl": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"libc": [
|
||||||
|
"musl"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-win32-arm64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-win32-ia32": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@parcel/watcher-win32-x64": {
|
||||||
|
"version": "2.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
|
||||||
|
"integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/parcel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chokidar": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"readdirp": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 20.19.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/detect-libc": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/immutable": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz",
|
||||||
|
"integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/is-extglob": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-glob": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-extglob": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/node-addon-api": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"node_modules/picomatch": {
|
||||||
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/readdirp": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 20.19.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/sass": {
|
||||||
|
"version": "1.100.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.100.0.tgz",
|
||||||
|
"integrity": "sha512-B5j0rYMlinhhOo9tjQebMVVn0TfyXAF+wB3b2ggZUuJ/is/Y+7+JGjirAMxHZ9Z3hIP98NPfamlAkBHa1lAaXQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"chokidar": "^5.0.0",
|
||||||
|
"immutable": "^5.1.5",
|
||||||
|
"source-map-js": ">=0.6.2 <2.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"sass": "sass.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.19.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@parcel/watcher": "^2.4.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/source-map-js": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
assets/package.json
Normal file
26
assets/package.json
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"name": "brain",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"author": "",
|
||||||
|
"type": "commonjs",
|
||||||
|
"main": "index.js",
|
||||||
|
"directories": {
|
||||||
|
"test": "tests"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"fe-watch": "sass styles/scss/main.scss styles/main.css -w",
|
||||||
|
"be-watch": "sass styles/scss/brain.scss styles/brain.css -w",
|
||||||
|
"landing-watch": "sass styles/scss/landing.scss styles/landing.css -W",
|
||||||
|
"fe-build": "sass styles/scss/main.scss styles/main.css --style compressed --no-source-map",
|
||||||
|
"be-build": "sass styles/scss/brain.scss styles/brain.css --style compressed --no-source-map",
|
||||||
|
"landing-build": "sass styles/scss/brain.scss styles/brain.css --style compressed --no-source-map",
|
||||||
|
"all-build": "npm run fe-build && npm run be-build && npm run landing-build"
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"sass": "^1.100.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
body {
|
|
||||||
background-color: skyblue;
|
|
||||||
}
|
|
||||||
1
assets/styles/brain.css
Normal file
1
assets/styles/brain.css
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
.page{max-width:800px;width:100%;margin:0 auto}.page h2{margin:0}.page .row{display:block;padding:1rem 0}.page .row label{display:block}.page .row input{height:30px;width:300px}.page .row #post_published{width:30px;height:30px}.page .row #post_save{width:100px;height:30px;background-color:green;border:none;color:#fff}#brain-wrapper header .level-1{display:flex;justify-content:center;align-items:flex-start;position:relative;list-style-type:none}#brain-wrapper header .level-1--item{padding:1rem 2rem}#brain-wrapper header .level-1 .level-2{display:none;margin:0;padding:0}#brain-wrapper header .level-1 .level-2.open{display:block;position:absolute}#brain-wrapper header .level-1 .level-2--item{padding:1rem 0}body{background-color:#d3d3d3}
|
||||||
644
assets/styles/landing.css
Normal file
644
assets/styles/landing.css
Normal file
|
|
@ -0,0 +1,644 @@
|
||||||
|
.home {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #696969;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.home header {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.home header h1 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.home header h1 a {
|
||||||
|
display: block;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #1d1f20;
|
||||||
|
background-color: #d7b94c;
|
||||||
|
border: 2px solid #d7b94c;
|
||||||
|
padding: 2px 2px;
|
||||||
|
}
|
||||||
|
.home header h1 a:hover {
|
||||||
|
color: #d7b94c;
|
||||||
|
background-color: unset;
|
||||||
|
}
|
||||||
|
.home header nav {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.home header nav .icon.icon-menu {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 999;
|
||||||
|
display: block;
|
||||||
|
right: 2rem;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
transition: right 100ms ease;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
.home header nav .icon.icon-menu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home header nav .icon.icon-menu:before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
background-image: url("/icons/menu-grid.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
position: absolute;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
.home header nav .icon.icon-menu:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.home header nav .icon.icon-menu.open {
|
||||||
|
right: calc(33.3333333333% + 1rem);
|
||||||
|
}
|
||||||
|
.home header nav .front-menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
overflow: hidden;
|
||||||
|
position: fixed;
|
||||||
|
right: -100%;
|
||||||
|
top: 1rem;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
transition: right 200ms ease;
|
||||||
|
}
|
||||||
|
.home header nav .front-menu.open {
|
||||||
|
right: 1rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
.home header nav .front-menu {
|
||||||
|
flex-direction: row;
|
||||||
|
position: relative;
|
||||||
|
top: unset;
|
||||||
|
right: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home header nav .front-menu {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
.home header nav .front-menu li a {
|
||||||
|
display: block;
|
||||||
|
font-family: AtomicAge-Regular;
|
||||||
|
color: #d7b94c;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
text-decoration: none;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
.home header nav .front-menu li a:hover {
|
||||||
|
border-bottom: 2px solid #d7b94c;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
.home #root.v1 {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.home #root.v1 section {
|
||||||
|
margin: 0;
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
.home #root.v1 section .title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.home #root.v1 .top {
|
||||||
|
display: flex;
|
||||||
|
min-height: 100vh;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer {
|
||||||
|
display: block;
|
||||||
|
max-width: 1024px;
|
||||||
|
max-height: 1024px;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #1d1f20;
|
||||||
|
border: 2rem solid #a6a695;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
box-shadow: 0 0 5px 10px rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer .heading {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-family: Montserrat-Light;
|
||||||
|
color: #d7b94c;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
.home #root.v1 .top .computer .heading {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer .heading:before {
|
||||||
|
content: ">";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer .heading:after {
|
||||||
|
content: "|";
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
background: #1d1f20;
|
||||||
|
animation: typing 0.5s steps(16) forwards, cursor 1s infinite;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
.home #root.v1 .top .computer .heading:after {
|
||||||
|
animation: typing 0.5s steps(16) forwards, cursor 1s infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer #intro {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer #intro .heading {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer #body {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer #body .about {
|
||||||
|
opacity: 0;
|
||||||
|
animation: showText 0.1s forwards;
|
||||||
|
animation-delay: 1s;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #d7b94c;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
.home #root.v1 .top .computer #body .about {
|
||||||
|
font-size: 2rem;
|
||||||
|
animation: showText 0.1s forwards;
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer #outro {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer #outro .heading {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer #outro .heading:after {
|
||||||
|
color: #1d1f20;
|
||||||
|
animation: typing 0.5s steps(16) forwards, cursor 1s infinite;
|
||||||
|
animation-delay: 2.5s;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
.home #root.v1 .top .computer #outro .heading:after {
|
||||||
|
animation: typing 0.5s steps(16) forwards, cursor 1s infinite;
|
||||||
|
animation-delay: 2.5s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer #outro .menu {
|
||||||
|
opacity: 0;
|
||||||
|
animation: showText 0.1s forwards;
|
||||||
|
animation-delay: 3s;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1rem;
|
||||||
|
padding-top: 2rem;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
.home #root.v1 .top .computer #outro .menu {
|
||||||
|
animation-delay: 3.5s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home #root.v1 .top .computer #outro .menu a {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #d7b94c;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
.home #root.v1 .top .computer #outro .menu a {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom section {
|
||||||
|
box-shadow: 0 0 5px 4px rgba(29, 31, 32, 0.45);
|
||||||
|
margin: 4rem 0;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
background-color: #d7b94c;
|
||||||
|
padding: 2rem 0;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff .title:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 150px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-bottom: 5px solid #04392f;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff .highlights {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 2rem;
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 1rem;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff .highlights .highlight {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
align-self: stretch;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
max-width: 400px;
|
||||||
|
box-shadow: 0 0 5px 0 rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff .highlights .highlight img {
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff .highlights .highlight p {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff .highlights .highlight a {
|
||||||
|
display: block;
|
||||||
|
font-family: Orbitron-Regular;
|
||||||
|
color: #49111C;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: none;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff .highlights .highlight a:hover {
|
||||||
|
border-bottom: 5px solid #49111C;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff .highlights .highlight .icon.icon-paperclip {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff .highlights .highlight .icon.icon-paperclip:before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
background-image: url("/icons/paperclip.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
position: absolute;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
top: -10px;
|
||||||
|
left: -10px;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #cool-stuff .highlights .highlight:hover {
|
||||||
|
box-shadow: 0 0 5px 5px rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #a6a695;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work > .title {
|
||||||
|
color: #49111C;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work > .title:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 50px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-bottom: 5px solid #d7b94c;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 2rem;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 800px) {
|
||||||
|
.home #root.v1 .bottom #work .jobs {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .left, .home #root.v1 .bottom #work .jobs .right {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 800px) {
|
||||||
|
.home #root.v1 .bottom #work .jobs .left, .home #root.v1 .bottom #work .jobs .right {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .left .title, .home #root.v1 .bottom #work .jobs .right .title {
|
||||||
|
text-align: center;
|
||||||
|
color: #49111C;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .left .wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .left .job {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding: 5px;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0 0 5px 0px rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .left .job .title {
|
||||||
|
text-align: left;
|
||||||
|
color: #49111C;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .left .job:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .left .job.active {
|
||||||
|
border-left: 1rem solid #d7b94c;
|
||||||
|
box-shadow: 0 0 5px 5px rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .right .highlights {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .right .job-highlight {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .right .job-highlight ul {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .right .job-highlight.show {
|
||||||
|
display: block;
|
||||||
|
border-left: 1rem solid #d7b94c;
|
||||||
|
box-shadow: 0 0 5px 5px rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 800px) {
|
||||||
|
.home #root.v1 .bottom #work .jobs .right .job-highlight.show {
|
||||||
|
border-right: 1rem solid #d7b94c;
|
||||||
|
border-left: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #work .jobs .right .job-highlight.hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #contact {
|
||||||
|
display: block;
|
||||||
|
background-color: #1F2421;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #contact .title {
|
||||||
|
color: #FBFCFF;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #contact .title:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 75px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-bottom: 5px solid #696969;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #contact .info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #contact .info .icon.icon-email {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.home #root.v1 .bottom #contact .info .icon.icon-email:before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
background-image: url("/icons/email.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
.home #root.v1 #continue {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
color: #FBFCFF;
|
||||||
|
animation: showText 0.1s forwards, continue 0.5s steps(50) forwards;
|
||||||
|
animation-delay: 4s;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
.home #root.v1 #continue {
|
||||||
|
animation-delay: 6s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home #root.v1 #continue .icon.icon-arrow-down:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background-image: url("/icons/arrow-down-top-line.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes typing {
|
||||||
|
0% {
|
||||||
|
color: #d7b94c;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
width: 0;
|
||||||
|
color: #1d1f20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes typing2 {
|
||||||
|
0% {
|
||||||
|
color: #d7b94c;
|
||||||
|
}
|
||||||
|
99.9% {
|
||||||
|
color: #d7b94c;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
width: 0;
|
||||||
|
color: #1d1f20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes cursor {
|
||||||
|
50% {
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes showText {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes continue {
|
||||||
|
0% {
|
||||||
|
bottom: 5rem;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
bottom: 4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Regular;
|
||||||
|
src: url("/fonts/RobotoSlab-Regular.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Medium;
|
||||||
|
src: url("/fonts/RobotoSlab-Regular.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Bold;
|
||||||
|
src: url("/fonts/RobotoSlab-Bold.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Black;
|
||||||
|
src: url("/fonts/RobotoSlab-Black.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: AtomicAge-Regular;
|
||||||
|
src: url("/fonts/AtomicAge-Regular.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Regular;
|
||||||
|
src: url("/fonts/Montserrat-Regular.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Light;
|
||||||
|
src: url("/fonts/Montserrat-Light.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Italic;
|
||||||
|
src: url("/fonts/Montserrat-Italic.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Bold;
|
||||||
|
src: url("/fonts/Montserrat-Bold.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-SemiBold;
|
||||||
|
src: url("/fonts/Montserrat-SemiBold.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Orbitron-Regular;
|
||||||
|
src: url("/fonts/Orbitron-Regular.ttf") format();
|
||||||
|
}
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: AtomicAge-Regular;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h1 {
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h2 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h3 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h4 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h5 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h6 {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p, a, li, span {
|
||||||
|
font-family: RobotoSlab-Regular;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-family: Montserrat-Bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
font-family: Montserrat-Italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
u {
|
||||||
|
font-family: Montserrat-SemiBold;
|
||||||
|
}
|
||||||
|
|
||||||
|
cite, q, small {
|
||||||
|
font-family: Orbitron-Regular;
|
||||||
|
}
|
||||||
|
|
||||||
|
s {
|
||||||
|
font-family: Montserrat-SemiBold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*# sourceMappingURL=landing.css.map */
|
||||||
839
assets/styles/main.css
Normal file
839
assets/styles/main.css
Normal file
|
|
@ -0,0 +1,839 @@
|
||||||
|
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
||||||
|
/* Document
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* 1. Correct the line height in all browsers.
|
||||||
|
* 2. Prevent adjustments of font size after orientation changes in iOS.
|
||||||
|
*/
|
||||||
|
html {
|
||||||
|
line-height: 1.15; /* 1 */
|
||||||
|
-webkit-text-size-adjust: 100%; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sections
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Remove the margin in all browsers.
|
||||||
|
*/
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the `main` element consistently in IE.
|
||||||
|
*/
|
||||||
|
main {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the font size and margin on `h1` elements within `section` and
|
||||||
|
* `article` contexts in Chrome, Firefox, and Safari.
|
||||||
|
*/
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 0.67em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grouping content
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* 1. Add the correct box sizing in Firefox.
|
||||||
|
* 2. Show the overflow in Edge and IE.
|
||||||
|
*/
|
||||||
|
hr {
|
||||||
|
box-sizing: content-box; /* 1 */
|
||||||
|
height: 0; /* 1 */
|
||||||
|
overflow: visible; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
* 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
pre {
|
||||||
|
font-family: monospace, monospace; /* 1 */
|
||||||
|
font-size: 1em; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text-level semantics
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Remove the gray background on active links in IE 10.
|
||||||
|
*/
|
||||||
|
a {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Remove the bottom border in Chrome 57-
|
||||||
|
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||||
|
*/
|
||||||
|
abbr[title] {
|
||||||
|
border-bottom: none; /* 1 */
|
||||||
|
text-decoration: underline; /* 2 */
|
||||||
|
text-decoration: underline dotted; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||||
|
*/
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
* 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: monospace, monospace; /* 1 */
|
||||||
|
font-size: 1em; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font size in all browsers.
|
||||||
|
*/
|
||||||
|
small {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||||
|
* all browsers.
|
||||||
|
*/
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
font-size: 75%;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Embedded content
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Remove the border on images inside links in IE 10.
|
||||||
|
*/
|
||||||
|
img {
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forms
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* 1. Change the font styles in all browsers.
|
||||||
|
* 2. Remove the margin in Firefox and Safari.
|
||||||
|
*/
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
optgroup,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font-family: inherit; /* 1 */
|
||||||
|
font-size: 100%; /* 1 */
|
||||||
|
line-height: 1.15; /* 1 */
|
||||||
|
margin: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the overflow in IE.
|
||||||
|
* 1. Show the overflow in Edge.
|
||||||
|
*/
|
||||||
|
button,
|
||||||
|
input { /* 1 */
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||||
|
* 1. Remove the inheritance of text transform in Firefox.
|
||||||
|
*/
|
||||||
|
button,
|
||||||
|
select { /* 1 */
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
*/
|
||||||
|
button,
|
||||||
|
[type=button],
|
||||||
|
[type=reset],
|
||||||
|
[type=submit] {
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inner border and padding in Firefox.
|
||||||
|
*/
|
||||||
|
button::-moz-focus-inner,
|
||||||
|
[type=button]::-moz-focus-inner,
|
||||||
|
[type=reset]::-moz-focus-inner,
|
||||||
|
[type=submit]::-moz-focus-inner {
|
||||||
|
border-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the focus styles unset by the previous rule.
|
||||||
|
*/
|
||||||
|
button:-moz-focusring,
|
||||||
|
[type=button]:-moz-focusring,
|
||||||
|
[type=reset]:-moz-focusring,
|
||||||
|
[type=submit]:-moz-focusring {
|
||||||
|
outline: 1px dotted ButtonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the padding in Firefox.
|
||||||
|
*/
|
||||||
|
fieldset {
|
||||||
|
padding: 0.35em 0.75em 0.625em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the text wrapping in Edge and IE.
|
||||||
|
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||||
|
* 3. Remove the padding so developers are not caught out when they zero out
|
||||||
|
* `fieldset` elements in all browsers.
|
||||||
|
*/
|
||||||
|
legend {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
color: inherit; /* 2 */
|
||||||
|
display: table; /* 1 */
|
||||||
|
max-width: 100%; /* 1 */
|
||||||
|
padding: 0; /* 3 */
|
||||||
|
white-space: normal; /* 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||||
|
*/
|
||||||
|
progress {
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the default vertical scrollbar in IE 10+.
|
||||||
|
*/
|
||||||
|
textarea {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Add the correct box sizing in IE 10.
|
||||||
|
* 2. Remove the padding in IE 10.
|
||||||
|
*/
|
||||||
|
[type=checkbox],
|
||||||
|
[type=radio] {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
padding: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||||
|
*/
|
||||||
|
[type=number]::-webkit-inner-spin-button,
|
||||||
|
[type=number]::-webkit-outer-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the odd appearance in Chrome and Safari.
|
||||||
|
* 2. Correct the outline style in Safari.
|
||||||
|
*/
|
||||||
|
[type=search] {
|
||||||
|
-webkit-appearance: textfield; /* 1 */
|
||||||
|
outline-offset: -2px; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inner padding in Chrome and Safari on macOS.
|
||||||
|
*/
|
||||||
|
[type=search]::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
* 2. Change font properties to `inherit` in Safari.
|
||||||
|
*/
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
-webkit-appearance: button; /* 1 */
|
||||||
|
font: inherit; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interactive
|
||||||
|
========================================================================== */
|
||||||
|
/*
|
||||||
|
* Add the correct display in Edge, IE 10+, and Firefox.
|
||||||
|
*/
|
||||||
|
details {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the correct display in all browsers.
|
||||||
|
*/
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Misc
|
||||||
|
========================================================================== */
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 10+.
|
||||||
|
*/
|
||||||
|
template {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 10.
|
||||||
|
*/
|
||||||
|
[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Regular;
|
||||||
|
src: url("/fonts/RobotoSlab-Regular.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Medium;
|
||||||
|
src: url("/fonts/RobotoSlab-Regular.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Bold;
|
||||||
|
src: url("/fonts/RobotoSlab-Bold.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Black;
|
||||||
|
src: url("/fonts/RobotoSlab-Black.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: AtomicAge-Regular;
|
||||||
|
src: url("/fonts/AtomicAge-Regular.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Regular;
|
||||||
|
src: url("/fonts/Montserrat-Regular.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Light;
|
||||||
|
src: url("/fonts/Montserrat-Light.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Italic;
|
||||||
|
src: url("/fonts/Montserrat-Italic.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Bold;
|
||||||
|
src: url("/fonts/Montserrat-Bold.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-SemiBold;
|
||||||
|
src: url("/fonts/Montserrat-SemiBold.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: Orbitron-Regular;
|
||||||
|
src: url("/fonts/Orbitron-Regular.ttf") format();
|
||||||
|
}
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: AtomicAge-Regular;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h1 {
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h2 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h3 {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h4 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h5 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
h6 {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p, a, li, span {
|
||||||
|
font-family: RobotoSlab-Regular;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-family: Montserrat-Bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
font-family: Montserrat-Italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
u {
|
||||||
|
font-family: Montserrat-SemiBold;
|
||||||
|
}
|
||||||
|
|
||||||
|
cite, q, small {
|
||||||
|
font-family: Orbitron-Regular;
|
||||||
|
}
|
||||||
|
|
||||||
|
s {
|
||||||
|
font-family: Montserrat-SemiBold;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
p,
|
||||||
|
a,
|
||||||
|
span,
|
||||||
|
time {
|
||||||
|
color: #FBFCFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondary.layout--v1 {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
padding: 0.5rem 0.5rem;
|
||||||
|
background-color: #d7b94c;
|
||||||
|
}
|
||||||
|
.secondary.layout--v1 #root {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
.secondary.layout--v1 #root {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 25% 75%;
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.secondary.layout--v1 #root {
|
||||||
|
gap: 1rem;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
max-width: 1200px;
|
||||||
|
background-color: #1F2421;
|
||||||
|
box-shadow: 0 0 5px 10px rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
.secondary.layout--v1 #root main {
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
}
|
||||||
|
.secondary.layout--v1.menu-open, .secondary.layout--v1.photo-open {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.secondary.layout--v1.photo-open .overlay {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #171A21;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
display: block;
|
||||||
|
position: sticky;
|
||||||
|
overflow: auto;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
top: 0;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
background-color: #1F2421;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
header {
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header.open {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
header.open .top h1 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
header nav.main {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
header nav.main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header nav.main .top {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
header nav.main .top h1 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
header nav.main .top h1 a {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
top: 1rem;
|
||||||
|
left: 1rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #1d1f20;
|
||||||
|
background-color: #d7b94c;
|
||||||
|
border: 2px solid #d7b94c;
|
||||||
|
padding: 2px 2px;
|
||||||
|
}
|
||||||
|
header nav.main .top h1 a:hover {
|
||||||
|
color: #d7b94c;
|
||||||
|
background-color: unset;
|
||||||
|
}
|
||||||
|
header nav.main .top .icon.icon-menu {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
z-index: 999;
|
||||||
|
transition: right 100ms ease;
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
header nav.main .top .icon.icon-menu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header nav.main .top .icon.icon-menu:before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
background-image: url("/icons/menu-grid.svg");
|
||||||
|
background-size: 100%;
|
||||||
|
position: absolute;
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
header nav.main .top .icon.icon-menu:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
header nav.main .top .icon.icon-menu.open {
|
||||||
|
right: 325px;
|
||||||
|
}
|
||||||
|
header nav.main .top .icon.icon-menu.open:before {
|
||||||
|
background-image: url("/icons/menu-close.svg");
|
||||||
|
}
|
||||||
|
header nav.main menu {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 0;
|
||||||
|
background-color: #d7b94c;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
transition: width 100ms ease;
|
||||||
|
}
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
header nav.main menu {
|
||||||
|
position: relative;
|
||||||
|
top: unset;
|
||||||
|
right: unset;
|
||||||
|
width: 100%;
|
||||||
|
transition: unset;
|
||||||
|
background-color: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header nav.main menu.open {
|
||||||
|
width: 300px;
|
||||||
|
box-shadow: 0 0 5px 10px rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
header nav.main menu li {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
}
|
||||||
|
header nav.main menu li a {
|
||||||
|
display: block;
|
||||||
|
color: #FBFCFF;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
header nav.main menu li a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.posts .list ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.posts .list ul li {
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
.posts .list ul li a {
|
||||||
|
color: #FBFCFF;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.posts .list ul li a .post-title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photos {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.photos .albums {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
.photos .albums {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.photos .albums {
|
||||||
|
gap: 1rem;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.photos .albums .album {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.photos .albums .album a {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.photos .albums .album a img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.photos .albums .album a .title, .photos .albums .album a .date, .photos .albums .album a .overlay {
|
||||||
|
position: absolute;
|
||||||
|
visibility: visible;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.photos .albums .album a .title, .photos .albums .album a .date, .photos .albums .album a .category {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.photos .albums .album a .title {
|
||||||
|
top: 1rem;
|
||||||
|
left: 1rem;
|
||||||
|
}
|
||||||
|
.photos .albums .album a .date {
|
||||||
|
bottom: 1rem;
|
||||||
|
left: 1rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.photos .albums .album a .overlay {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.333);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.photos .albums .album a:hover .title, .photos .albums .album a:hover .date, .photos .albums .album a:hover .category, .photos .albums .album a:hover .overlay {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.photos .albums .album a:hover img {
|
||||||
|
transform: scale(1.01);
|
||||||
|
transition: transform 100ms ease-in-out;
|
||||||
|
}
|
||||||
|
.photos img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#album .title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#album .meta {
|
||||||
|
border-bottom: 5px solid #a6a695;
|
||||||
|
}
|
||||||
|
#album .photos {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
#album .photos {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#album .photos {
|
||||||
|
gap: 1rem;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
#album .photos .photo {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#album .photos .photo img {
|
||||||
|
transition: transform 100ms ease-in-out;
|
||||||
|
}
|
||||||
|
#album .photos .photo:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
#album .photos .photo:hover img {
|
||||||
|
transform: scale(1.01);
|
||||||
|
transition: transform 100ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#open-image {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
#open-image .close {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 2rem;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
#open-image img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
#open-image #details {
|
||||||
|
display: block;
|
||||||
|
height: auto;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
background-color: #a6a695;
|
||||||
|
}
|
||||||
|
#open-image #details p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#open-image #details #caption {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
#open-image #details #location, #open-image #details #date, #open-image #details #equipment {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
#open-image.open {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.posts {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.posts h2, .posts h3 {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
.posts h2:after, .posts h3:after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 75px;
|
||||||
|
height: 5px;
|
||||||
|
background-color: #a6a695;
|
||||||
|
}
|
||||||
|
.posts .list {
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-top: 5px solid #d7b94c;
|
||||||
|
}
|
||||||
|
.posts .list .post a .title {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
}
|
||||||
|
.posts .list .post a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-color: #a6a695;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.post .title {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
.post .meta {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
border-bottom: 5px solid #a6a695;
|
||||||
|
}
|
||||||
|
.post .meta .admin-actions {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.post .meta .published {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
||||||
|
.post .meta .category {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
||||||
|
.post .text p {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*# sourceMappingURL=main.css.map */
|
||||||
6
assets/styles/scss/brain.scss
Normal file
6
assets/styles/scss/brain.scss
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
@use './brain/form';
|
||||||
|
@use './brain/layout';
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: lightgrey;
|
||||||
|
}
|
||||||
36
assets/styles/scss/brain/_form.scss
Normal file
36
assets/styles/scss/brain/_form.scss
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
.page {
|
||||||
|
max-width: 800px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: block;
|
||||||
|
padding: 1rem 0;
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
height: 30px;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#post_published {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#post_save {
|
||||||
|
width: 100px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: green;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
assets/styles/scss/brain/_layout.scss
Normal file
33
assets/styles/scss/brain/_layout.scss
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
#brain-wrapper {
|
||||||
|
header {
|
||||||
|
.level-1 {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
list-style-type: none;
|
||||||
|
|
||||||
|
&--item {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level-2 {
|
||||||
|
display: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&--item {
|
||||||
|
padding: 1rem 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
57
assets/styles/scss/front/_layout.scss
Normal file
57
assets/styles/scss/front/_layout.scss
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
@use '../shared/colors' as colors;
|
||||||
|
|
||||||
|
.secondary.layout--v1 {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
padding: 0.5rem 0.5rem;
|
||||||
|
background-color: colors.$primaryYellow;
|
||||||
|
|
||||||
|
#root {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 25% 75%;
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
gap: 1rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
max-width: 1200px;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
background-color: colors.$carbonBlack;
|
||||||
|
box-shadow: 0 0 5px 10px rgba(29, 31, 32, 0.45);
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.menu-open,
|
||||||
|
&.photo-open {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.photo-open {
|
||||||
|
.overlay {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: colors.$inkBlack;
|
||||||
|
opacity: .9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
assets/styles/scss/front/_lists.scss
Normal file
24
assets/styles/scss/front/_lists.scss
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
@use '../shared/colors';
|
||||||
|
|
||||||
|
.posts {
|
||||||
|
.list {
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 1rem 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: colors.$primaryWhite;
|
||||||
|
text-decoration: none;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
.post-title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
147
assets/styles/scss/front/_menu.scss
Normal file
147
assets/styles/scss/front/_menu.scss
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
@use '../shared/colors' as colors;
|
||||||
|
|
||||||
|
header {
|
||||||
|
display: block;
|
||||||
|
position: sticky;
|
||||||
|
overflow: auto;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
top: 0;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
background-color: colors.$carbonBlack;
|
||||||
|
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
height: 500px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
.top {
|
||||||
|
h1 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nav.main {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
top: 1rem;
|
||||||
|
left: 1rem;
|
||||||
|
|
||||||
|
font-size: 1.5rem;
|
||||||
|
text-decoration: none;
|
||||||
|
color: colors.$primaryBlack;
|
||||||
|
background-color: colors.$primaryYellow;
|
||||||
|
border: 2px solid colors.$primaryYellow;
|
||||||
|
padding: 2px 2px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: colors.$primaryYellow;
|
||||||
|
background-color: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
&.icon-menu {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
z-index: 999;
|
||||||
|
transition: right 100ms ease;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
background-image: url('/icons/menu-grid.svg');
|
||||||
|
background-size: 100%;
|
||||||
|
position: absolute;
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
right: 325px;
|
||||||
|
&:before {
|
||||||
|
background-image: url('/icons/menu-close.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
menu {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 0;
|
||||||
|
background-color: colors.$primaryYellow;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
transition: width 100ms ease;
|
||||||
|
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
position: relative;
|
||||||
|
top: unset;
|
||||||
|
right: unset;
|
||||||
|
width: 100%;
|
||||||
|
transition: unset;
|
||||||
|
background-color: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
width: 300px;
|
||||||
|
box-shadow: 0 0 5px 10px rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
color: colors.$primaryWhite;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
179
assets/styles/scss/front/_photos.scss
Normal file
179
assets/styles/scss/front/_photos.scss
Normal file
|
|
@ -0,0 +1,179 @@
|
||||||
|
@use '../shared/colors' as colors;
|
||||||
|
.photos {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
.albums {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
gap: 1rem;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.album {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title, .date, .overlay {
|
||||||
|
position: absolute;
|
||||||
|
visibility: visible;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title, .date, .category {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
top: 1rem;
|
||||||
|
left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date {
|
||||||
|
bottom: 1rem;
|
||||||
|
left: 1rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.333);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.title, .date, .category, .overlay {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
transform: scale(1.01);
|
||||||
|
transition: transform 100ms ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#album {
|
||||||
|
.title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.meta {
|
||||||
|
border-bottom: 5px solid colors.$computerBorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photos {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
@media (min-width: 800px) {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-template-rows: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
gap: 1rem;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.photo {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
img {
|
||||||
|
//width: 100%;
|
||||||
|
transition: transform 100ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
img {
|
||||||
|
transform: scale(1.01);
|
||||||
|
transition: transform 100ms ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#open-image {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
.close {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 2rem;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#details {
|
||||||
|
display: block;
|
||||||
|
height: auto;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
|
||||||
|
background-color: colors.$computerBorder;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#caption {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#location, #date, #equipment {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
73
assets/styles/scss/front/_posts.scss
Normal file
73
assets/styles/scss/front/_posts.scss
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
@use '../shared/colors' as colors;
|
||||||
|
|
||||||
|
.posts {
|
||||||
|
display: block;
|
||||||
|
h2, h3 {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
width: 75px;
|
||||||
|
height: 5px;
|
||||||
|
|
||||||
|
background-color: colors.$computerBorder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.intro {
|
||||||
|
//color: colors.$primaryWhite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-top: 5px solid colors.$primaryYellow;
|
||||||
|
|
||||||
|
.post {
|
||||||
|
|
||||||
|
a {
|
||||||
|
.title {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-color: colors.$computerBorder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
|
||||||
|
border-bottom: 5px solid colors.$computerBorder;
|
||||||
|
|
||||||
|
.admin-actions {
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.published {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text p {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
15
assets/styles/scss/front/_typography.scss
Normal file
15
assets/styles/scss/front/_typography.scss
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
@use '../shared/colors' as colors;
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
p,
|
||||||
|
a,
|
||||||
|
span,
|
||||||
|
time {
|
||||||
|
color: colors.$primaryWhite;
|
||||||
|
}
|
||||||
|
|
||||||
2
assets/styles/scss/landing.scss
Normal file
2
assets/styles/scss/landing.scss
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
@use './landing/computer';
|
||||||
|
@use './shared/fonts';
|
||||||
619
assets/styles/scss/landing/_computer.scss
Normal file
619
assets/styles/scss/landing/_computer.scss
Normal file
|
|
@ -0,0 +1,619 @@
|
||||||
|
@use '../shared/colors' as colors;
|
||||||
|
|
||||||
|
.home {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: colors.$primaryGrey;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
header {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
text-decoration: none;
|
||||||
|
color: colors.$primaryBlack;
|
||||||
|
background-color: colors.$primaryYellow;
|
||||||
|
border: 2px solid colors.$primaryYellow;
|
||||||
|
padding: 2px 2px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: colors.$primaryYellow;
|
||||||
|
background-color: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
&.icon-menu {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 999;
|
||||||
|
display: block;
|
||||||
|
right: 2rem;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
transition: right 100ms ease;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
background-image: url('/icons/menu-grid.svg');
|
||||||
|
background-size: 100%;
|
||||||
|
position: absolute;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
right: calc(1/3 * 100% + 1rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.front-menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
right: -100%;
|
||||||
|
top: 1rem;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
transition: right 200ms ease;
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
flex-direction: row;
|
||||||
|
position: relative;
|
||||||
|
top: unset;
|
||||||
|
right: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
font-family: AtomicAge-Regular;
|
||||||
|
color: colors.$primaryYellow;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
text-decoration: none;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-bottom: 2px solid colors.$primaryYellow;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
&.v1 {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
section {
|
||||||
|
margin: 0;
|
||||||
|
padding: 1rem 0;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.top {
|
||||||
|
display: flex;
|
||||||
|
min-height: 100vh;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.computer {
|
||||||
|
display: block;
|
||||||
|
max-width: 1024px;
|
||||||
|
max-height: 1024px;
|
||||||
|
width: 100%;
|
||||||
|
background-color: colors.$primaryBlack;
|
||||||
|
border: 2rem solid colors.$computerBorder;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
|
||||||
|
box-shadow: 0 0 5px 10px rgba(29, 31, 32, 0.45);
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-family: Montserrat-Light;
|
||||||
|
color: colors.$primaryYellow;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 1rem;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '>';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
//background: #1d1f20;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: "|";
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
background: colors.$primaryBlack;
|
||||||
|
animation: typing 0.5s steps(16) forwards,
|
||||||
|
cursor 1s infinite;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
animation: typing 0.5s steps(16) forwards,
|
||||||
|
cursor 1s infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#intro {
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#body {
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
|
.about {
|
||||||
|
opacity: 0;
|
||||||
|
animation: showText 0.1s forwards;
|
||||||
|
animation-delay: 1s;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: colors.$primaryYellow;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
font-size: 2rem;
|
||||||
|
animation: showText 0.1s forwards;
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#outro {
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
width: 160px;
|
||||||
|
|
||||||
|
&:after{
|
||||||
|
color: colors.$primaryBlack;
|
||||||
|
animation: typing 0.5s steps(16) forwards,
|
||||||
|
cursor 1s infinite;
|
||||||
|
animation-delay: 2.5s;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
animation: typing 0.5s steps(16) forwards,
|
||||||
|
cursor 1s infinite;
|
||||||
|
animation-delay: 2.5s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
opacity: 0;
|
||||||
|
animation: showText 0.1s forwards;
|
||||||
|
animation-delay: 3s;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1rem;
|
||||||
|
padding-top: 2rem;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
animation-delay: 3.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: colors.$primaryYellow;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
section {
|
||||||
|
box-shadow: 0 0 5px 4px rgba(29, 31, 32, 0.45);
|
||||||
|
margin: 4rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cool-stuff{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
background-color: colors.$primaryYellow;
|
||||||
|
padding: 2rem 0;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 150px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-bottom: 5px solid colors.$primaryGreen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlights {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 2rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 1rem;
|
||||||
|
|
||||||
|
.highlight {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
align-self: stretch;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
max-width: 400px;
|
||||||
|
|
||||||
|
box-shadow: 0 0 5px 0 rgba(29, 31, 32, 0.45);
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
font-family: Orbitron-Regular;
|
||||||
|
color: colors.$primaryRed;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: none;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-bottom: 5px solid colors.$primaryRed;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
&.icon-paperclip {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
background-image: url('/icons/paperclip.svg');
|
||||||
|
background-size: 100%;
|
||||||
|
position: absolute;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
top: -10px;
|
||||||
|
left: -10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 0 5px 5px rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#work {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: colors.$computerBorder;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
|
||||||
|
> .title {
|
||||||
|
color: colors.$primaryRed;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 50px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-bottom: 5px solid colors.$primaryYellow;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.jobs {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 2rem;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
@media screen and (min-width: 800px) {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left, .right {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
@media screen and (min-width: 800px) {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
text-align: center;
|
||||||
|
color: colors.$primaryRed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
.wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding: 5px;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0 0 5px 0px rgba(29, 31, 32, 0.45);
|
||||||
|
|
||||||
|
.title {
|
||||||
|
text-align: left;
|
||||||
|
color: colors.$primaryRed;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-left: 1rem solid colors.$primaryYellow;
|
||||||
|
box-shadow: 0 0 5px 5px rgba(29, 31, 32, 0.45);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
.highlights {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-highlight {
|
||||||
|
//width: 100%;
|
||||||
|
//height: 100%;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding: 0;
|
||||||
|
//margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.show {
|
||||||
|
display: block;
|
||||||
|
border-left: 1rem solid colors.$primaryYellow;
|
||||||
|
box-shadow: 0 0 5px 5px rgba(29, 31, 32, 0.45);
|
||||||
|
|
||||||
|
@media screen and (min-width: 800px) {
|
||||||
|
border-right: 1rem solid colors.$primaryYellow;
|
||||||
|
border-left: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#contact {
|
||||||
|
display: block;
|
||||||
|
background-color: colors.$carbonBlack;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: colors.$primaryWhite;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 75px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border-bottom: 5px solid colors.$primaryGrey;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 1rem 0;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
&.icon-email {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
background-image: url('/icons/email.svg');
|
||||||
|
background-size: 100%;
|
||||||
|
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#continue {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
color: colors.$primaryWhite;
|
||||||
|
animation: showText 0.1s forwards,
|
||||||
|
continue 0.5s steps(50) forwards;
|
||||||
|
|
||||||
|
animation-delay: 4s;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
animation-delay: 6s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
&.icon-arrow-down {
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
|
||||||
|
background-image: url('/icons/arrow-down-top-line.svg');
|
||||||
|
background-size: 100%;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes typing {
|
||||||
|
0% {
|
||||||
|
color: colors.$primaryYellow;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
width: 0;
|
||||||
|
color: colors.$primaryBlack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes typing2 {
|
||||||
|
0% {
|
||||||
|
color: colors.$primaryYellow;
|
||||||
|
}
|
||||||
|
99.9% {
|
||||||
|
color: colors.$primaryYellow;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
width: 0;
|
||||||
|
color: colors.$primaryBlack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes cursor {
|
||||||
|
50% { color: transparent }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes showText {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes continue {
|
||||||
|
0% {
|
||||||
|
bottom: 5rem;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
bottom: 4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
assets/styles/scss/main.scss
Normal file
9
assets/styles/scss/main.scss
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
@use './shared/normalize';
|
||||||
|
@use './shared/fonts';
|
||||||
|
@use './front/typography';
|
||||||
|
@use './front/layout';
|
||||||
|
@use './front/menu';
|
||||||
|
|
||||||
|
@use './front/lists';
|
||||||
|
@use './front/photos';
|
||||||
|
@use './front/posts';
|
||||||
18
assets/styles/scss/shared/_colors.scss
Normal file
18
assets/styles/scss/shared/_colors.scss
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
$primaryRed: #49111C;
|
||||||
|
$crimson: #9B1D20;
|
||||||
|
$primaryYellow: #d7b94c;
|
||||||
|
$primaryGreen: #04392f;
|
||||||
|
$primaryBlack: #1d1f20;
|
||||||
|
$primaryWhite: #FBFCFF;
|
||||||
|
$primaryGrey: #696969;
|
||||||
|
$primaryLightGrey: #a8a8a8;
|
||||||
|
|
||||||
|
$green: #0E6E0C;
|
||||||
|
|
||||||
|
//Landing
|
||||||
|
$computerBorder: #a6a695;
|
||||||
|
|
||||||
|
$evergreen: $primaryGreen;
|
||||||
|
$inkBlack: #171A21;
|
||||||
|
$fern: #3F784C;
|
||||||
|
$carbonBlack: #1F2421;
|
||||||
135
assets/styles/scss/shared/_fonts.scss
Normal file
135
assets/styles/scss/shared/_fonts.scss
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
//headings
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Regular;
|
||||||
|
src: url('/fonts/RobotoSlab-Regular.ttf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Medium;
|
||||||
|
src: url('/fonts/RobotoSlab-Regular.ttf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Bold;
|
||||||
|
src: url('/fonts/RobotoSlab-Bold.ttf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: RobotoSlab-Black;
|
||||||
|
src: url('/fonts/RobotoSlab-Black.ttf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: AtomicAge-Regular;
|
||||||
|
src: url('/fonts/AtomicAge-Regular.ttf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
//non-headings
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Regular;
|
||||||
|
src: url('/fonts/Montserrat-Regular.ttf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Light;
|
||||||
|
src: url('/fonts/Montserrat-Light.ttf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Italic;
|
||||||
|
src: url('/fonts/Montserrat-Italic.ttf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-Bold;
|
||||||
|
src: url('/fonts/Montserrat-Bold.ttf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Montserrat-SemiBold;
|
||||||
|
src: url('/fonts/Montserrat-SemiBold.ttf') format('opentype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: Orbitron-Regular;
|
||||||
|
src: url('/fonts/Orbitron-Regular.ttf') format();
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: AtomicAge-Regular;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
|
||||||
|
font-size: 2rem;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1rem;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 1rem;
|
||||||
|
|
||||||
|
@media screen and (min-width: 600px) {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p, a, li, span {
|
||||||
|
font-family: RobotoSlab-Regular;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-family: Montserrat-Bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
em {
|
||||||
|
font-family: Montserrat-Italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
u {
|
||||||
|
font-family: Montserrat-SemiBold;
|
||||||
|
}
|
||||||
|
|
||||||
|
cite, q, small {
|
||||||
|
font-family: Orbitron-Regular;
|
||||||
|
}
|
||||||
|
|
||||||
|
s {
|
||||||
|
font-family: Montserrat-SemiBold;
|
||||||
|
}
|
||||||
349
assets/styles/scss/shared/_normalize.scss
Normal file
349
assets/styles/scss/shared/_normalize.scss
Normal file
|
|
@ -0,0 +1,349 @@
|
||||||
|
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
||||||
|
|
||||||
|
/* Document
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the line height in all browsers.
|
||||||
|
* 2. Prevent adjustments of font size after orientation changes in iOS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
html {
|
||||||
|
line-height: 1.15; /* 1 */
|
||||||
|
-webkit-text-size-adjust: 100%; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sections
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the margin in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the `main` element consistently in IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the font size and margin on `h1` elements within `section` and
|
||||||
|
* `article` contexts in Chrome, Firefox, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 0.67em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grouping content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Add the correct box sizing in Firefox.
|
||||||
|
* 2. Show the overflow in Edge and IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
hr {
|
||||||
|
box-sizing: content-box; /* 1 */
|
||||||
|
height: 0; /* 1 */
|
||||||
|
overflow: visible; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
* 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pre {
|
||||||
|
font-family: monospace, monospace; /* 1 */
|
||||||
|
font-size: 1em; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text-level semantics
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the gray background on active links in IE 10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
a {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Remove the bottom border in Chrome 57-
|
||||||
|
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
border-bottom: none; /* 1 */
|
||||||
|
text-decoration: underline; /* 2 */
|
||||||
|
text-decoration: underline dotted; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
* 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: monospace, monospace; /* 1 */
|
||||||
|
font-size: 1em; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font size in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||||
|
* all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
font-size: 75%;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Embedded content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the border on images inside links in IE 10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forms
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Change the font styles in all browsers.
|
||||||
|
* 2. Remove the margin in Firefox and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
optgroup,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font-family: inherit; /* 1 */
|
||||||
|
font-size: 100%; /* 1 */
|
||||||
|
line-height: 1.15; /* 1 */
|
||||||
|
margin: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the overflow in IE.
|
||||||
|
* 1. Show the overflow in Edge.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input { /* 1 */
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||||
|
* 1. Remove the inheritance of text transform in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
select { /* 1 */
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
[type="button"],
|
||||||
|
[type="reset"],
|
||||||
|
[type="submit"] {
|
||||||
|
-webkit-appearance: button;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inner border and padding in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button::-moz-focus-inner,
|
||||||
|
[type="button"]::-moz-focus-inner,
|
||||||
|
[type="reset"]::-moz-focus-inner,
|
||||||
|
[type="submit"]::-moz-focus-inner {
|
||||||
|
border-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the focus styles unset by the previous rule.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button:-moz-focusring,
|
||||||
|
[type="button"]:-moz-focusring,
|
||||||
|
[type="reset"]:-moz-focusring,
|
||||||
|
[type="submit"]:-moz-focusring {
|
||||||
|
outline: 1px dotted ButtonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the padding in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
padding: 0.35em 0.75em 0.625em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the text wrapping in Edge and IE.
|
||||||
|
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||||
|
* 3. Remove the padding so developers are not caught out when they zero out
|
||||||
|
* `fieldset` elements in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
legend {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
color: inherit; /* 2 */
|
||||||
|
display: table; /* 1 */
|
||||||
|
max-width: 100%; /* 1 */
|
||||||
|
padding: 0; /* 3 */
|
||||||
|
white-space: normal; /* 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||||
|
*/
|
||||||
|
|
||||||
|
progress {
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the default vertical scrollbar in IE 10+.
|
||||||
|
*/
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Add the correct box sizing in IE 10.
|
||||||
|
* 2. Remove the padding in IE 10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type="checkbox"],
|
||||||
|
[type="radio"] {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
padding: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type="number"]::-webkit-inner-spin-button,
|
||||||
|
[type="number"]::-webkit-outer-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the odd appearance in Chrome and Safari.
|
||||||
|
* 2. Correct the outline style in Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type="search"] {
|
||||||
|
-webkit-appearance: textfield; /* 1 */
|
||||||
|
outline-offset: -2px; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inner padding in Chrome and Safari on macOS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type="search"]::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
* 2. Change font properties to `inherit` in Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
-webkit-appearance: button; /* 1 */
|
||||||
|
font: inherit; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interactive
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the correct display in Edge, IE 10+, and Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
details {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the correct display in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Misc
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 10+.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
"symfony/string": "8.0.*",
|
"symfony/string": "8.0.*",
|
||||||
"symfony/translation": "8.0.*",
|
"symfony/translation": "8.0.*",
|
||||||
"symfony/twig-bundle": "8.0.*",
|
"symfony/twig-bundle": "8.0.*",
|
||||||
|
"symfony/ux-autocomplete": "^3.0",
|
||||||
"symfony/ux-turbo": "^3.0",
|
"symfony/ux-turbo": "^3.0",
|
||||||
"symfony/validator": "8.0.*",
|
"symfony/validator": "8.0.*",
|
||||||
"symfony/web-link": "8.0.*",
|
"symfony/web-link": "8.0.*",
|
||||||
|
|
|
||||||
4743
composer.lock
generated
4743
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -13,4 +13,5 @@ return [
|
||||||
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
|
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
|
||||||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||||
|
Symfony\UX\Autocomplete\AutocompleteBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,11 @@ security:
|
||||||
|
|
||||||
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
|
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
|
||||||
providers:
|
providers:
|
||||||
users_in_memory: { memory: null }
|
# used to reload user from session & other features (e.g. switch_user)
|
||||||
|
app_user_provider:
|
||||||
|
entity:
|
||||||
|
class: App\Entity\User
|
||||||
|
property: username
|
||||||
|
|
||||||
firewalls:
|
firewalls:
|
||||||
dev:
|
dev:
|
||||||
|
|
@ -14,7 +18,15 @@ security:
|
||||||
security: false
|
security: false
|
||||||
main:
|
main:
|
||||||
lazy: true
|
lazy: true
|
||||||
provider: users_in_memory
|
provider: app_user_provider
|
||||||
|
form_login:
|
||||||
|
login_path: brain_login
|
||||||
|
check_path: brain_login
|
||||||
|
enable_csrf: true
|
||||||
|
logout:
|
||||||
|
path: brain_logout
|
||||||
|
# where to redirect after logout
|
||||||
|
# target: app_any_route
|
||||||
|
|
||||||
# Activate different ways to authenticate:
|
# Activate different ways to authenticate:
|
||||||
# https://symfony.com/doc/current/security.html#the-firewall
|
# https://symfony.com/doc/current/security.html#the-firewall
|
||||||
|
|
@ -24,7 +36,7 @@ security:
|
||||||
|
|
||||||
# Note: Only the *first* matching rule is applied
|
# Note: Only the *first* matching rule is applied
|
||||||
access_control:
|
access_control:
|
||||||
# - { path: ^/admin, roles: ROLE_ADMIN }
|
- { path: ^/brain, roles: ROLE_ADMIN }
|
||||||
# - { path: ^/profile, roles: ROLE_USER }
|
# - { path: ^/profile, roles: ROLE_USER }
|
||||||
|
|
||||||
when@test:
|
when@test:
|
||||||
|
|
|
||||||
3
config/routes/ux_autocomplete.yaml
Normal file
3
config/routes/ux_autocomplete.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
ux_autocomplete:
|
||||||
|
resource: '@AutocompleteBundle/config/routes.php'
|
||||||
|
prefix: '/autocomplete'
|
||||||
|
|
@ -21,3 +21,6 @@ services:
|
||||||
|
|
||||||
# add more service definitions when explicit configuration is needed
|
# add more service definitions when explicit configuration is needed
|
||||||
# please note that last definitions always *replace* previous ones
|
# please note that last definitions always *replace* previous ones
|
||||||
|
App\Service\PhotoUploader:
|
||||||
|
arguments:
|
||||||
|
$targetDirectory: '%'
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,16 @@
|
||||||
* The "importmap:require" command can be used to add new entries to this file.
|
* The "importmap:require" command can be used to add new entries to this file.
|
||||||
*/
|
*/
|
||||||
return [
|
return [
|
||||||
'app' => [
|
'main' => [
|
||||||
'path' => './assets/app.js',
|
'path' => './assets/main.js',
|
||||||
|
'entrypoint' => true,
|
||||||
|
],
|
||||||
|
'brain' => [
|
||||||
|
'path' => './assets/brain.js',
|
||||||
|
'entrypoint' => true,
|
||||||
|
],
|
||||||
|
'landing' => [
|
||||||
|
'path' => './assets/landing.js',
|
||||||
'entrypoint' => true,
|
'entrypoint' => true,
|
||||||
],
|
],
|
||||||
'@hotwired/stimulus' => [
|
'@hotwired/stimulus' => [
|
||||||
|
|
@ -25,4 +33,29 @@ return [
|
||||||
'@hotwired/turbo' => [
|
'@hotwired/turbo' => [
|
||||||
'version' => '8.0.23',
|
'version' => '8.0.23',
|
||||||
],
|
],
|
||||||
|
'tom-select' => [
|
||||||
|
'version' => '2.6.1',
|
||||||
|
],
|
||||||
|
'@orchidjs/sifter' => [
|
||||||
|
'version' => '1.1.0',
|
||||||
|
],
|
||||||
|
'@orchidjs/unicode-variants' => [
|
||||||
|
'version' => '1.1.2',
|
||||||
|
],
|
||||||
|
'tom-select/dist/css/tom-select.default.min.css' => [
|
||||||
|
'version' => '2.6.1',
|
||||||
|
'type' => 'css',
|
||||||
|
],
|
||||||
|
'tom-select/dist/css/tom-select.default.css' => [
|
||||||
|
'version' => '2.6.1',
|
||||||
|
'type' => 'css',
|
||||||
|
],
|
||||||
|
'tom-select/dist/css/tom-select.bootstrap4.css' => [
|
||||||
|
'version' => '2.6.1',
|
||||||
|
'type' => 'css',
|
||||||
|
],
|
||||||
|
'tom-select/dist/css/tom-select.bootstrap5.css' => [
|
||||||
|
'version' => '2.6.1',
|
||||||
|
'type' => 'css',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
|
||||||
33
migrations/Version20260522200819.php
Normal file
33
migrations/Version20260522200819.php
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20260522200819 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE page (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, title VARCHAR(255) NOT NULL, text TEXT NOT NULL, url VARCHAR(255) NOT NULL, PRIMARY KEY (id))');
|
||||||
|
$this->addSql('CREATE TABLE post (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, title VARCHAR(255) NOT NULL, date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, text TEXT NOT NULL, url VARCHAR(255) NOT NULL, PRIMARY KEY (id))');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE page');
|
||||||
|
$this->addSql('DROP TABLE post');
|
||||||
|
}
|
||||||
|
}
|
||||||
33
migrations/Version20260522202515.php
Normal file
33
migrations/Version20260522202515.php
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20260522202515 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE page ADD published BOOLEAN NOT NULL');
|
||||||
|
$this->addSql('ALTER TABLE post ADD published BOOLEAN NOT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE page DROP published');
|
||||||
|
$this->addSql('ALTER TABLE post DROP published');
|
||||||
|
}
|
||||||
|
}
|
||||||
47
migrations/Version20260522205620.php
Normal file
47
migrations/Version20260522205620.php
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20260522205620 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE category (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, title VARCHAR(255) NOT NULL, PRIMARY KEY (id))');
|
||||||
|
$this->addSql('CREATE TABLE post_tag (post_id INT NOT NULL, tag_id INT NOT NULL, PRIMARY KEY (post_id, tag_id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_5ACE3AF04B89032C ON post_tag (post_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_5ACE3AF0BAD26311 ON post_tag (tag_id)');
|
||||||
|
$this->addSql('CREATE TABLE tag (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, title VARCHAR(255) NOT NULL, PRIMARY KEY (id))');
|
||||||
|
$this->addSql('ALTER TABLE post_tag ADD CONSTRAINT FK_5ACE3AF04B89032C FOREIGN KEY (post_id) REFERENCES post (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER TABLE post_tag ADD CONSTRAINT FK_5ACE3AF0BAD26311 FOREIGN KEY (tag_id) REFERENCES tag (id) ON DELETE CASCADE');
|
||||||
|
$this->addSql('ALTER TABLE post ADD category_id INT DEFAULT NULL');
|
||||||
|
$this->addSql('ALTER TABLE post ADD CONSTRAINT FK_5A8A6C8D12469DE2 FOREIGN KEY (category_id) REFERENCES category (id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_5A8A6C8D12469DE2 ON post (category_id)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE post_tag DROP CONSTRAINT FK_5ACE3AF04B89032C');
|
||||||
|
$this->addSql('ALTER TABLE post_tag DROP CONSTRAINT FK_5ACE3AF0BAD26311');
|
||||||
|
$this->addSql('DROP TABLE category');
|
||||||
|
$this->addSql('DROP TABLE post_tag');
|
||||||
|
$this->addSql('DROP TABLE tag');
|
||||||
|
$this->addSql('ALTER TABLE post DROP CONSTRAINT FK_5A8A6C8D12469DE2');
|
||||||
|
$this->addSql('DROP INDEX IDX_5A8A6C8D12469DE2');
|
||||||
|
$this->addSql('ALTER TABLE post DROP category_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
39
migrations/Version20260601003707.php
Normal file
39
migrations/Version20260601003707.php
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20260601003707 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE photo (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, file VARCHAR(255) NOT NULL, equipment VARCHAR(255) NOT NULL, location VARCHAR(255) NOT NULL, caption VARCHAR(255) NOT NULL, date DATE NOT NULL, photos_id INT DEFAULT NULL, PRIMARY KEY (id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_14B78418301EC62 ON photo (photos_id)');
|
||||||
|
$this->addSql('CREATE TABLE photos (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, title VARCHAR(255) NOT NULL, date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, category_id INT DEFAULT NULL, PRIMARY KEY (id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_876E0D912469DE2 ON photos (category_id)');
|
||||||
|
$this->addSql('ALTER TABLE photo ADD CONSTRAINT FK_14B78418301EC62 FOREIGN KEY (photos_id) REFERENCES photos (id)');
|
||||||
|
$this->addSql('ALTER TABLE photos ADD CONSTRAINT FK_876E0D912469DE2 FOREIGN KEY (category_id) REFERENCES category (id)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE photo DROP CONSTRAINT FK_14B78418301EC62');
|
||||||
|
$this->addSql('ALTER TABLE photos DROP CONSTRAINT FK_876E0D912469DE2');
|
||||||
|
$this->addSql('DROP TABLE photo');
|
||||||
|
$this->addSql('DROP TABLE photos');
|
||||||
|
}
|
||||||
|
}
|
||||||
31
migrations/Version20260601011643.php
Normal file
31
migrations/Version20260601011643.php
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20260601011643 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE photo ADD alt_text VARCHAR(255) NOT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE photo DROP alt_text');
|
||||||
|
}
|
||||||
|
}
|
||||||
33
migrations/Version20260601013417.php
Normal file
33
migrations/Version20260601013417.php
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20260601013417 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE photos ADD text TEXT NOT NULL');
|
||||||
|
$this->addSql('ALTER TABLE photos ADD url VARCHAR(255) NOT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE photos DROP text');
|
||||||
|
$this->addSql('ALTER TABLE photos DROP url');
|
||||||
|
}
|
||||||
|
}
|
||||||
31
migrations/Version20260601201050.php
Normal file
31
migrations/Version20260601201050.php
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20260601201050 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE photos ADD thumbnail VARCHAR(255) NOT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('ALTER TABLE photos DROP thumbnail');
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/fonts/AtomicAge-Regular.ttf
Normal file
BIN
public/fonts/AtomicAge-Regular.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-Black.ttf
Normal file
BIN
public/fonts/Montserrat-Black.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-BlackItalic.ttf
Normal file
BIN
public/fonts/Montserrat-BlackItalic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-Bold.ttf
Normal file
BIN
public/fonts/Montserrat-Bold.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-BoldItalic.ttf
Normal file
BIN
public/fonts/Montserrat-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-ExtraBold.ttf
Normal file
BIN
public/fonts/Montserrat-ExtraBold.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-ExtraBoldItalic.ttf
Normal file
BIN
public/fonts/Montserrat-ExtraBoldItalic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-ExtraLight.ttf
Normal file
BIN
public/fonts/Montserrat-ExtraLight.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-ExtraLightItalic.ttf
Normal file
BIN
public/fonts/Montserrat-ExtraLightItalic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-Italic.ttf
Normal file
BIN
public/fonts/Montserrat-Italic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-Light.ttf
Normal file
BIN
public/fonts/Montserrat-Light.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-LightItalic.ttf
Normal file
BIN
public/fonts/Montserrat-LightItalic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-Medium.ttf
Normal file
BIN
public/fonts/Montserrat-Medium.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-MediumItalic.ttf
Normal file
BIN
public/fonts/Montserrat-MediumItalic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-Regular.ttf
Normal file
BIN
public/fonts/Montserrat-Regular.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-SemiBold.ttf
Normal file
BIN
public/fonts/Montserrat-SemiBold.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-SemiBoldItalic.ttf
Normal file
BIN
public/fonts/Montserrat-SemiBoldItalic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-Thin.ttf
Normal file
BIN
public/fonts/Montserrat-Thin.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Montserrat-ThinItalic.ttf
Normal file
BIN
public/fonts/Montserrat-ThinItalic.ttf
Normal file
Binary file not shown.
BIN
public/fonts/Orbitron-Regular.ttf
Normal file
BIN
public/fonts/Orbitron-Regular.ttf
Normal file
Binary file not shown.
BIN
public/fonts/RobotoSlab-Black.ttf
Normal file
BIN
public/fonts/RobotoSlab-Black.ttf
Normal file
Binary file not shown.
BIN
public/fonts/RobotoSlab-Bold.ttf
Normal file
BIN
public/fonts/RobotoSlab-Bold.ttf
Normal file
Binary file not shown.
BIN
public/fonts/RobotoSlab-ExtraBold.ttf
Normal file
BIN
public/fonts/RobotoSlab-ExtraBold.ttf
Normal file
Binary file not shown.
BIN
public/fonts/RobotoSlab-ExtraLight.ttf
Normal file
BIN
public/fonts/RobotoSlab-ExtraLight.ttf
Normal file
Binary file not shown.
BIN
public/fonts/RobotoSlab-Light.ttf
Normal file
BIN
public/fonts/RobotoSlab-Light.ttf
Normal file
Binary file not shown.
BIN
public/fonts/RobotoSlab-Medium.ttf
Normal file
BIN
public/fonts/RobotoSlab-Medium.ttf
Normal file
Binary file not shown.
BIN
public/fonts/RobotoSlab-Regular.ttf
Normal file
BIN
public/fonts/RobotoSlab-Regular.ttf
Normal file
Binary file not shown.
BIN
public/fonts/RobotoSlab-SemiBold.ttf
Normal file
BIN
public/fonts/RobotoSlab-SemiBold.ttf
Normal file
Binary file not shown.
BIN
public/fonts/RobotoSlab-Thin.ttf
Normal file
BIN
public/fonts/RobotoSlab-Thin.ttf
Normal file
Binary file not shown.
4
public/icons/arrow-down-top-line.svg
Normal file
4
public/icons/arrow-down-top-line.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M8 16L12 20M12 20L16 16M12 20V8M4 4H20" stroke="#d7b94c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 362 B |
4
public/icons/arrow-right.svg
Normal file
4
public/icons/arrow-right.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4 4V20M8 12H20M20 12L16 8M20 12L16 16" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 362 B |
4
public/icons/email.svg
Normal file
4
public/icons/email.svg
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg fill="#d7b94c" width="800px" height="800px" viewBox="0 0 1920 1920" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill="#d7b94c" d="M1920 428.266v1189.54l-464.16-580.146-88.203 70.585 468.679 585.904H83.684l468.679-585.904-88.202-70.585L0 1617.805V428.265l959.944 832.441L1920 428.266ZM1919.932 226v52.627l-959.943 832.44L.045 278.628V226h1919.887Z" fill-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 505 B |
1
public/icons/menu-close.svg
Normal file
1
public/icons/menu-close.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg viewBox="0 -0.5 8 8" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#d7b94c" stroke="#d7b94c"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <title>close_mini [#d7b94c]</title> <desc>Created with Sketch.</desc> <defs> </defs> <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g id="Dribbble-Light-Preview" transform="translate(-385.000000, -206.000000)" fill="#d7b94c"> <g id="icons" transform="translate(56.000000, 160.000000)"> <polygon id="close_mini-[#d7b94c]" points="334.6 49.5 337 51.6 335.4 53 333 50.9 330.6 53 329 51.6 331.4 49.5 329 47.4 330.6 46 333 48.1 335.4 46 337 47.4"> </polygon> </g> </g> </g> </g></svg>
|
||||||
|
After Width: | Height: | Size: 819 B |
13
public/icons/menu-grid.svg
Normal file
13
public/icons/menu-grid.svg
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
// 16pxls (c) by Paul mackenzie <paul@whatspauldoing.com>
|
||||||
|
//
|
||||||
|
// 16pxls is licensed under a
|
||||||
|
// Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the license along with this
|
||||||
|
// work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<svg fill="#d7b94c" width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 0h4v4H0V0zm0 6h4v4H0V6zm0 6h4v4H0v-4zM6 0h4v4H6V0zm0 6h4v4H6V6zm0 6h4v4H6v-4zm6-12h4v4h-4V0zm0 6h4v4h-4V6zm0 6h4v4h-4v-4z" fill-rule="evenodd"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 640 B |
18
public/icons/paperclip.svg
Normal file
18
public/icons/paperclip.svg
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg fill="#696969" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
viewBox="0 0 512 512" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M480.466,51.283c-20.334-20.336-47.371-31.534-76.129-31.534s-55.795,11.2-76.13,31.534L94.985,284.505
|
||||||
|
c-15.06,15.059-23.353,35.083-23.353,56.38s8.293,41.321,23.353,56.38c31.089,31.087,81.674,31.088,112.76,0L412.23,192.781
|
||||||
|
l-23.614-23.614L184.132,373.65c-18.067,18.067-47.465,18.067-65.533,0c-8.752-8.752-13.572-20.389-13.572-32.766
|
||||||
|
c0-12.378,4.82-24.015,13.572-32.767l233.22-233.22c14.028-14.027,32.677-21.753,52.517-21.753
|
||||||
|
c19.837,0,38.487,7.725,52.515,21.753c14.028,14.028,21.753,32.677,21.753,52.515s-7.724,38.488-21.753,52.515L207.795,428.985
|
||||||
|
c-39.847,39.846-104.684,39.845-144.53,0c-19.303-19.303-29.933-44.967-29.933-72.264c0-27.299,10.631-52.963,29.933-72.266
|
||||||
|
l220.319-220.32L259.97,40.522L39.651,260.842c-52.868,52.868-52.868,138.891,0,191.758
|
||||||
|
c26.434,26.435,61.156,39.652,95.879,39.652c34.722,0,69.445-13.217,95.878-39.652l249.057-249.057
|
||||||
|
C500.801,183.208,512,156.171,512,127.413S500.8,71.617,480.466,51.283z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
18
src/Controller/Brain/BrainController.php
Normal file
18
src/Controller/Brain/BrainController.php
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Brain;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
final class BrainController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/brain', name: 'brain_home')]
|
||||||
|
public function index(): Response
|
||||||
|
{
|
||||||
|
return $this->render('brain/home/index.html.twig', [
|
||||||
|
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
95
src/Controller/Brain/BrainPageController.php
Normal file
95
src/Controller/Brain/BrainPageController.php
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Brain;
|
||||||
|
|
||||||
|
use App\Entity\Page;
|
||||||
|
use App\Form\PageType;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
final class BrainPageController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/brain/page/list', name: 'brain_page_list')]
|
||||||
|
public function index(EntityManagerInterface $entityManager): Response
|
||||||
|
{
|
||||||
|
$pages = $entityManager->getRepository(Page::class)->findAll();
|
||||||
|
|
||||||
|
return $this->render('brain/page/index.html.twig', [
|
||||||
|
'pages' => $pages
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/brain/page/new', name: 'brain_page_new')]
|
||||||
|
public function new(EntityManagerInterface $entityManager, Request $request): Response
|
||||||
|
{
|
||||||
|
|
||||||
|
$form = $this->createForm(PageType::class);
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted()) {
|
||||||
|
$data = $form->getData();
|
||||||
|
$page = new Page();
|
||||||
|
|
||||||
|
$page->setTitle($data->getTitle());
|
||||||
|
$page->setText($data->getText());
|
||||||
|
$page->setUrl($data->getUrl());
|
||||||
|
|
||||||
|
if ($data->isPublished()) {
|
||||||
|
$page->setPublished(true);
|
||||||
|
} else {
|
||||||
|
$page->setPublished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$entityManager->persist($page);
|
||||||
|
|
||||||
|
$entityManager->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('brain_page_list');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('brain/page/create.html.twig', [
|
||||||
|
'action' => 'New',
|
||||||
|
'form' => $form
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/brain/page/edit/{id}', name: 'brain_page_edit')]
|
||||||
|
public function edit(EntityManagerInterface $entityManager, string $id, Request $request): Response
|
||||||
|
{
|
||||||
|
|
||||||
|
$page = $entityManager->getRepository(Page::class)->findOneBy(['id' => $id]);
|
||||||
|
|
||||||
|
$form = $this->createForm(PageType::class, $page);
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted()) {
|
||||||
|
$data = $form->getData();
|
||||||
|
|
||||||
|
$page->setTitle($data->getTitle());
|
||||||
|
$page->setText($data->getText());
|
||||||
|
$page->setUrl($data->getUrl());
|
||||||
|
|
||||||
|
if ($data->isPublished()) {
|
||||||
|
$page->setPublished(true);
|
||||||
|
} else {
|
||||||
|
$page->setPublished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$entityManager->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('brain_page_list');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('brain/page/create.html.twig', [
|
||||||
|
'action' => 'Edit',
|
||||||
|
'form' => $form
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
140
src/Controller/Brain/BrainPhotosController.php
Normal file
140
src/Controller/Brain/BrainPhotosController.php
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Brain;
|
||||||
|
|
||||||
|
use App\Entity\Category;
|
||||||
|
use App\Entity\Photos;
|
||||||
|
use App\Form\PhotosType;
|
||||||
|
use App\Service\PhotoUploader;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
final class BrainPhotosController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/brain/photos/list', name: 'brain_photos_list')]
|
||||||
|
public function index(EntityManagerInterface $entityManager): Response
|
||||||
|
{
|
||||||
|
$photos = $entityManager->getRepository(Photos::class)->findAllOrderByLatest();
|
||||||
|
|
||||||
|
return $this->render('brain/photos/index.html.twig', [
|
||||||
|
'photos' => $photos
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/brain/photos/new', name: 'brain_photos_new')]
|
||||||
|
public function new(EntityManagerInterface $entityManager, Request $request, PhotoUploader $photoUploader): Response
|
||||||
|
{
|
||||||
|
$form = $this->createForm(PhotosType::class);
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted()) {
|
||||||
|
$data = $form->getData();
|
||||||
|
$photos = new Photos();
|
||||||
|
$fileNames = [];
|
||||||
|
|
||||||
|
$photos->setTitle($data->getTitle());
|
||||||
|
$photos->setDate($data->getDate());
|
||||||
|
$photos->setText($data->getText());
|
||||||
|
$photos->setUrl($data->getUrl());
|
||||||
|
|
||||||
|
$tax = $request->request->all('photos');
|
||||||
|
|
||||||
|
if ($data->getCategory() == null) {
|
||||||
|
$cat = $tax['category'];
|
||||||
|
|
||||||
|
if ($cat !== null) {
|
||||||
|
$categoryToAdd = new Category()->setTitle($cat);
|
||||||
|
$photos->setCategory($categoryToAdd);
|
||||||
|
|
||||||
|
$entityManager->persist($categoryToAdd);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$photos->setCategory($data->getCategory());
|
||||||
|
}
|
||||||
|
|
||||||
|
$thumbnail = $request->files->get('photos')['thumbnail'];
|
||||||
|
|
||||||
|
$fileName = $photoUploader->upload($thumbnail, $photos->getTitle());
|
||||||
|
$photos->setThumbnail($fileName);
|
||||||
|
|
||||||
|
$uploadedPhotos = $request->files->get('photos')['uploads'];
|
||||||
|
|
||||||
|
foreach ($uploadedPhotos as $upload) {
|
||||||
|
$filenames[] = $photoUploader->upload($upload['file'], $photos->getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data->getUploads() as $index => $photo) {
|
||||||
|
$photo->setFile($filenames[$index]);
|
||||||
|
$photos->addUpload($photo);
|
||||||
|
}
|
||||||
|
|
||||||
|
$entityManager->persist($photos);
|
||||||
|
|
||||||
|
$entityManager->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('brain_photos_list');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('brain/photos/create.html.twig', [
|
||||||
|
'action' => 'New',
|
||||||
|
'form' => $form
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/brain/photos/edit/{id}', name: 'brain_photos_edit')]
|
||||||
|
public function edit(EntityManagerInterface $entityManager, string $id, Request $request, PhotoUploader $photoUploader): Response
|
||||||
|
{
|
||||||
|
|
||||||
|
$photos = $entityManager->getRepository(Photos::class)->findOneBy(['id' => $id]);
|
||||||
|
|
||||||
|
$form = $this->createForm(PhotosType::class, $photos);
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
/* TODO handle editing! */
|
||||||
|
/*if (!$form->isSubmitted() && $photos->getUploads()) {
|
||||||
|
$dirName = 'uploads/' . strtolower(str_replace(' ', '_', $photos->getTitle()));
|
||||||
|
$form->setData(['uploads' => $dirName . '/' . $photos->getUploads()[0]->getFile()]);
|
||||||
|
} */
|
||||||
|
|
||||||
|
if ($form->isSubmitted()) {
|
||||||
|
$data = $form->getData();
|
||||||
|
$photos = new Photos();
|
||||||
|
$fileNames = [];
|
||||||
|
|
||||||
|
$photos->setTitle($data->getTitle());
|
||||||
|
|
||||||
|
$uploadedPhotos = $request->files->get('photos')['uploads'];
|
||||||
|
|
||||||
|
foreach ($uploadedPhotos as $upload) {
|
||||||
|
$filenames[] = $photoUploader->upload($upload['file'], $photos->getTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data->getUploads() as $index => $photo) {
|
||||||
|
$photo->setFile($filenames[$index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//$entityManager->persist($data);
|
||||||
|
|
||||||
|
$entityManager->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('brain_photos_list');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('brain/photos/create.html.twig', [
|
||||||
|
'action' => 'Edit',
|
||||||
|
'form' => $form
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handleFilenameToFileConversion(string $directory, array $uploads)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
138
src/Controller/Brain/BrainPostController.php
Normal file
138
src/Controller/Brain/BrainPostController.php
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\Brain;
|
||||||
|
|
||||||
|
use App\Entity\Category;
|
||||||
|
use App\Entity\Tag;
|
||||||
|
use App\Form\PostType;
|
||||||
|
use App\Entity\Post;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
final class BrainPostController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/brain/post/list', name: 'brain_post_list')]
|
||||||
|
public function index(EntityManagerInterface $entityManager): Response
|
||||||
|
{
|
||||||
|
$posts = $entityManager->getRepository(Post::class)->findAllOrderByLatest();
|
||||||
|
|
||||||
|
return $this->render('brain/post/index.html.twig', [
|
||||||
|
'posts' => $posts
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/brain/post/new', name: 'brain_post_new')]
|
||||||
|
public function new(EntityManagerInterface $entityManager, Request $request): Response
|
||||||
|
{
|
||||||
|
$form = $this->createForm(PostType::class);
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted()) {
|
||||||
|
$data = $form->getData();
|
||||||
|
$post = new Post();
|
||||||
|
|
||||||
|
$post->setTitle($data->getTitle());
|
||||||
|
$post->setDate($data->getDate());
|
||||||
|
$post->setText($data->getText());
|
||||||
|
$post->setUrl($data->getUrl());
|
||||||
|
|
||||||
|
foreach ($data->getTags() as $tag) {
|
||||||
|
$post->addTag($tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($data->isPublished()) {
|
||||||
|
$post->setPublished(true);
|
||||||
|
} else {
|
||||||
|
$post->SetPublished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tax = $request->request->all('post');
|
||||||
|
|
||||||
|
if ($data->getCategory() == null) {
|
||||||
|
$cat = $tax['category'];
|
||||||
|
|
||||||
|
if ($cat !== null) {
|
||||||
|
$categoryToAdd = new Category()->setTitle($cat);
|
||||||
|
$post->setCategory($categoryToAdd);
|
||||||
|
|
||||||
|
$entityManager->persist($categoryToAdd);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$post->setCategory($data->getCategory());
|
||||||
|
}
|
||||||
|
|
||||||
|
$entityManager->persist($post);
|
||||||
|
|
||||||
|
$entityManager->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('brain_post_list');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('brain/post/create.html.twig', [
|
||||||
|
'action' => 'new',
|
||||||
|
'form' => $form,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/brain/post/edit/{id}', name: 'brain_post_edit')]
|
||||||
|
public function edit(EntityManagerInterface $entityManager, string $id, Request $request): Response
|
||||||
|
{
|
||||||
|
$post = $entityManager->getRepository(Post::class)->findOneBy(['id' => $id]);
|
||||||
|
|
||||||
|
$form = $this->createForm(PostType::class, $post);
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted()) {
|
||||||
|
$data = $form->getData();
|
||||||
|
//$post = new Post();
|
||||||
|
|
||||||
|
|
||||||
|
$post->setTitle($data->getTitle());
|
||||||
|
$post->setDate($data->getDate());
|
||||||
|
$post->setText($data->getText());
|
||||||
|
$post->setUrl($data->getUrl());
|
||||||
|
|
||||||
|
foreach ($data->getTags() as $tag) {
|
||||||
|
$post->addTag($tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($data->isPublished()) {
|
||||||
|
$post->setPublished(true);
|
||||||
|
} else {
|
||||||
|
$post->SetPublished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tax = $request->request->all('post');
|
||||||
|
|
||||||
|
if ($data->getCategory() == null) {
|
||||||
|
$cat = $tax['category'];
|
||||||
|
|
||||||
|
if ($cat !== null) {
|
||||||
|
$categoryToAdd = new Category()->setTitle($cat);
|
||||||
|
$post->setCategory($categoryToAdd);
|
||||||
|
|
||||||
|
$entityManager->persist($categoryToAdd);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$post->setCategory($data->getCategory());
|
||||||
|
}
|
||||||
|
|
||||||
|
$entityManager->flush();
|
||||||
|
|
||||||
|
return $this->redirectToRoute('brain_post_list');
|
||||||
|
}
|
||||||
|
return $this->render('brain/post/create.html.twig', [
|
||||||
|
'action' => 'edit',
|
||||||
|
'form' => $form
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/Controller/FrontEnd/CategoryController.php
Normal file
47
src/Controller/FrontEnd/CategoryController.php
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\FrontEnd;
|
||||||
|
|
||||||
|
use App\Entity\Category;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
final class CategoryController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/categories', name: 'front_end_category_list', priority: 1)]
|
||||||
|
public function index(EntityManagerInterface $entityManager): Response
|
||||||
|
{
|
||||||
|
$categories = $entityManager->getRepository(Category::class)->findAll();
|
||||||
|
|
||||||
|
$categoriesDisplay = [];
|
||||||
|
|
||||||
|
foreach ($categories as $index => $category) {
|
||||||
|
$categoriesDisplay[] = [
|
||||||
|
'title' => $category->getTitle(),
|
||||||
|
'urlSafeTitle' => strtolower(str_replace(' ', '-', $category->getTitle())),
|
||||||
|
'count' => $category->getCount(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('front/category/index.html.twig', [
|
||||||
|
'categories' => $categoriesDisplay
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/categories/{categoryTitle}', name: 'front_end_category_detail')]
|
||||||
|
public function detail(EntityManagerInterface $entityManager, string $categoryTitle): Response
|
||||||
|
{
|
||||||
|
$formattedTitle = ucwords(str_replace('-', ' ', $categoryTitle));
|
||||||
|
$category = $entityManager->getRepository(Category::class)->findOneBy(['title' => $formattedTitle]);
|
||||||
|
return $this->render('front/category/detail.html.twig', [
|
||||||
|
'title' => $category->getTitle(),
|
||||||
|
'posts' => $category->getPosts(),
|
||||||
|
'photos' => $category->getPhotos(),
|
||||||
|
'count' => $category->getCount()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/Controller/FrontEnd/FrontController.php
Normal file
25
src/Controller/FrontEnd/FrontController.php
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\FrontEnd;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
final class FrontController extends AbstractController
|
||||||
|
{
|
||||||
|
/**TODO Update so this is it's own type so i don't have to hardcode anything */
|
||||||
|
#[Route('/', name: 'front_end_home')]
|
||||||
|
public function index(): Response
|
||||||
|
{
|
||||||
|
return $this->render('front/home/index.html.twig', [
|
||||||
|
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/secret/styleguide', name: 'front_end_styleguide')]
|
||||||
|
public function styleGuide(): Response
|
||||||
|
{
|
||||||
|
return $this->render('front/styleguide/styleguide.html.twig',[]);
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/Controller/FrontEnd/PageController.php
Normal file
24
src/Controller/FrontEnd/PageController.php
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\FrontEnd;
|
||||||
|
|
||||||
|
use App\Entity\Page;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
final class PageController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/{url:page}', name: 'front_end_page')]
|
||||||
|
public function index(Page $page): Response
|
||||||
|
{
|
||||||
|
if ($page->isPublished()) {
|
||||||
|
return $this->render('front/page/index.html.twig', [
|
||||||
|
'page' => $page
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response('<h1>Page not found</h1>');
|
||||||
|
}
|
||||||
|
}
|
||||||
69
src/Controller/FrontEnd/PhotosController.php
Normal file
69
src/Controller/FrontEnd/PhotosController.php
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\FrontEnd;
|
||||||
|
|
||||||
|
use App\Entity\Photos;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
|
final class PhotosController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/photos', name: 'front_end_photos_list', priority: 1)]
|
||||||
|
public function index(EntityManagerInterface $entityManager): Response
|
||||||
|
{
|
||||||
|
$photos = $entityManager->getRepository(Photos::class)->findAllOrderByLatest();
|
||||||
|
|
||||||
|
$albums = [];
|
||||||
|
|
||||||
|
foreach ($photos as $index => $photo) {
|
||||||
|
$albums[] = [
|
||||||
|
'title' => $photo->getTitle(),
|
||||||
|
'date' => $photo->getDate(),
|
||||||
|
'category' => $photo->getCategory()->getTitle(),
|
||||||
|
'thumbnail' => 'photos/' . strtolower(str_replace(' ', '_', $photo->getTitle())) . '/' . $photo->getThumbnail(),
|
||||||
|
'url' => $photo->getUrl(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('front/photos/index.html.twig', [
|
||||||
|
'photos' => $albums
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/photos/{url:photos}', name: 'front_end_photos_detail')]
|
||||||
|
public function detail(Photos $photos): Response
|
||||||
|
{
|
||||||
|
$album = [];
|
||||||
|
$uploads = $photos->getUploads();
|
||||||
|
|
||||||
|
$album = [
|
||||||
|
'title' => $photos->getTitle(),
|
||||||
|
'category' => $photos->getCategory()->getTitle(),
|
||||||
|
'urlSafeCategory' => $photos->getCategory()->getUrlSafeTitle(),
|
||||||
|
'text' => $photos->getText(),
|
||||||
|
'date' => $photos->getDate()
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($uploads as $index => $upload) {
|
||||||
|
$filePath = 'photos/' . strtolower(str_replace(' ', '_', $album['title'])) . '/' . $upload->getFile();
|
||||||
|
|
||||||
|
$album['uploads'][] = [
|
||||||
|
'file' => $filePath,
|
||||||
|
'alt' => $upload->getAltText(),
|
||||||
|
'equipment' => $upload->getEquipment(),
|
||||||
|
'caption' => $upload->getCaption(),
|
||||||
|
'location' => $upload->getLocation(),
|
||||||
|
'date' => $upload->getDate()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('front/photos/detail.html.twig', [
|
||||||
|
'photos' => $album
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
50
src/Controller/FrontEnd/PostController.php
Normal file
50
src/Controller/FrontEnd/PostController.php
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller\FrontEnd;
|
||||||
|
|
||||||
|
use App\Entity\Post;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
final class PostController extends AbstractController
|
||||||
|
{
|
||||||
|
/**TODO Update so this is it's own type so i don't have to hardcode anything */
|
||||||
|
#[Route('/words', name: 'front_end_post_list', priority: 1)]
|
||||||
|
public function index(EntityManagerInterface $entityManager): Response
|
||||||
|
{
|
||||||
|
$posts = $entityManager->getRepository(Post::class)->findAllOrderByLatest();
|
||||||
|
|
||||||
|
$formattedPosts = [];
|
||||||
|
|
||||||
|
foreach ($posts as $index => $post) {
|
||||||
|
$formattedPosts [] = [
|
||||||
|
'title' => $post->getTitle(),
|
||||||
|
'category' => $post->getCategory()->getTitle(),
|
||||||
|
'urlSafeCategory' => $post->getCategory()->getUrlSafeTitle(),
|
||||||
|
'date' => $post->getDate(),
|
||||||
|
'url' => $post->getUrl()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('front/post/index.html.twig', [
|
||||||
|
'posts' => $formattedPosts
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/words/{url:post}', name: 'front_end_post_detail')]
|
||||||
|
public function post(Post $post): Response
|
||||||
|
{
|
||||||
|
if ($post->isPublished()) {
|
||||||
|
return $this->render('front/post/detail.html.twig', [
|
||||||
|
'post' => $post,
|
||||||
|
'urlSafeCategory' => $post->getCategory()->getUrlSafeTitle()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response('<h1>Page not found</h1>');
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/Controller/RegistrationController.php
Normal file
42
src/Controller/RegistrationController.php
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\Form\RegistrationFormType;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
class RegistrationController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/letmein/register', name: 'app_register')]
|
||||||
|
public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, EntityManagerInterface $entityManager): Response
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$form = $this->createForm(RegistrationFormType::class, $user);
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
/** @var string $plainPassword */
|
||||||
|
$plainPassword = $form->get('plainPassword')->getData();
|
||||||
|
|
||||||
|
// encode the plain password
|
||||||
|
$user->setPassword($userPasswordHasher->hashPassword($user, $plainPassword));
|
||||||
|
|
||||||
|
$entityManager->persist($user);
|
||||||
|
$entityManager->flush();
|
||||||
|
|
||||||
|
// do anything else you need here, like send an email
|
||||||
|
|
||||||
|
return $this->redirectToRoute('brain_home');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('registration/register.html.twig', [
|
||||||
|
'registrationForm' => $form,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/Controller/SecurityController.php
Normal file
32
src/Controller/SecurityController.php
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||||
|
|
||||||
|
class SecurityController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route(path: '/letmein', name: 'brain_login', priority: 1)]
|
||||||
|
public function login(AuthenticationUtils $authenticationUtils): Response
|
||||||
|
{
|
||||||
|
// get the login error if there is one
|
||||||
|
$error = $authenticationUtils->getLastAuthenticationError();
|
||||||
|
|
||||||
|
// last username entered by the user
|
||||||
|
$lastUsername = $authenticationUtils->getLastUsername();
|
||||||
|
|
||||||
|
return $this->render('security/login.html.twig', [
|
||||||
|
'last_username' => $lastUsername,
|
||||||
|
'error' => $error,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route(path: '/letmeout', name: 'brain_logout', priority: 1)]
|
||||||
|
public function logout(): void
|
||||||
|
{
|
||||||
|
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
|
||||||
|
}
|
||||||
|
}
|
||||||
130
src/Entity/Category.php
Normal file
130
src/Entity/Category.php
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\CategoryRepository;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: CategoryRepository::class)]
|
||||||
|
class Category
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $title = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, Post>
|
||||||
|
*/
|
||||||
|
#[ORM\OneToMany(targetEntity: Post::class, mappedBy: 'category')]
|
||||||
|
private Collection $posts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, Photos>
|
||||||
|
*/
|
||||||
|
#[ORM\OneToMany(targetEntity: Photos::class, mappedBy: 'category')]
|
||||||
|
private Collection $photos;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->posts = new ArrayCollection();
|
||||||
|
$this->photos = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle(): ?string
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTitle(string $title): static
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Post>
|
||||||
|
*/
|
||||||
|
public function getPosts(): Collection
|
||||||
|
{
|
||||||
|
return $this->posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addPost(Post $post): static
|
||||||
|
{
|
||||||
|
if (!$this->posts->contains($post)) {
|
||||||
|
$this->posts->add($post);
|
||||||
|
$post->setCategory($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removePost(Post $post): static
|
||||||
|
{
|
||||||
|
if ($this->posts->removeElement($post)) {
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($post->getCategory() === $this) {
|
||||||
|
$post->setCategory(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Photos>
|
||||||
|
*/
|
||||||
|
public function getPhotos(): Collection
|
||||||
|
{
|
||||||
|
return $this->photos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addPhoto(Photos $photo): static
|
||||||
|
{
|
||||||
|
if (!$this->photos->contains($photo)) {
|
||||||
|
$this->photos->add($photo);
|
||||||
|
$photo->setCategory($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removePhoto(Photos $photo): static
|
||||||
|
{
|
||||||
|
if ($this->photos->removeElement($photo)) {
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($photo->getCategory() === $this) {
|
||||||
|
$photo->setCategory(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCount() : int
|
||||||
|
{
|
||||||
|
return $this->posts->count() + $this->photos->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUrlSafeTitle() : string
|
||||||
|
{
|
||||||
|
return strtolower(str_replace(' ', '-', $this->title));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDisplaySafeTitle(string $urlSafeTitle) : string
|
||||||
|
{
|
||||||
|
return ucwords(str_replace('-', ' ', $urlSafeTitle));
|
||||||
|
}
|
||||||
|
}
|
||||||
81
src/Entity/Page.php
Normal file
81
src/Entity/Page.php
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\PageRepository;
|
||||||
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: PageRepository::class)]
|
||||||
|
class Page
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $title = null;
|
||||||
|
|
||||||
|
#[ORM\Column(type: Types::TEXT)]
|
||||||
|
private ?string $text = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $url = null;
|
||||||
|
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?bool $published = null;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle(): ?string
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTitle(string $title): static
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getText(): ?string
|
||||||
|
{
|
||||||
|
return $this->text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setText(string $text): static
|
||||||
|
{
|
||||||
|
$this->text = $text;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUrl(): ?string
|
||||||
|
{
|
||||||
|
return $this->url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUrl(string $url): static
|
||||||
|
{
|
||||||
|
$this->url = $url;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isPublished(): ?bool
|
||||||
|
{
|
||||||
|
return $this->published;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPublished(bool $published): static
|
||||||
|
{
|
||||||
|
$this->published = $published;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
126
src/Entity/Photo.php
Normal file
126
src/Entity/Photo.php
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\PhotoRepository;
|
||||||
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: PhotoRepository::class)]
|
||||||
|
class Photo
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $file = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $equipment = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $location = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $caption = null;
|
||||||
|
|
||||||
|
#[ORM\Column(type: Types::DATE_MUTABLE)]
|
||||||
|
private ?\DateTime $date = null;
|
||||||
|
|
||||||
|
#[ORM\ManyToOne(inversedBy: 'uploads')]
|
||||||
|
private ?Photos $photos = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $alt_text = null;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFile(): ?string
|
||||||
|
{
|
||||||
|
return $this->file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFile(string $file): static
|
||||||
|
{
|
||||||
|
$this->file = $file;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEquipment(): ?string
|
||||||
|
{
|
||||||
|
return $this->equipment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setEquipment(string $equipment): static
|
||||||
|
{
|
||||||
|
$this->equipment = $equipment;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLocation(): ?string
|
||||||
|
{
|
||||||
|
return $this->location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLocation(string $location): static
|
||||||
|
{
|
||||||
|
$this->location = $location;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCaption(): ?string
|
||||||
|
{
|
||||||
|
return $this->caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCaption(string $caption): static
|
||||||
|
{
|
||||||
|
$this->caption = $caption;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDate(): ?\DateTime
|
||||||
|
{
|
||||||
|
return $this->date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDate(\DateTime $date): static
|
||||||
|
{
|
||||||
|
$this->date = $date;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPhotos(): ?Photos
|
||||||
|
{
|
||||||
|
return $this->photos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPhotos(?Photos $photos): static
|
||||||
|
{
|
||||||
|
$this->photos = $photos;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAltText(): ?string
|
||||||
|
{
|
||||||
|
return $this->alt_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAltText(string $alt_text): static
|
||||||
|
{
|
||||||
|
$this->alt_text = $alt_text;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
154
src/Entity/Photos.php
Normal file
154
src/Entity/Photos.php
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\PhotosRepository;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: PhotosRepository::class)]
|
||||||
|
class Photos
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $title = null;
|
||||||
|
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?\DateTime $date = null;
|
||||||
|
|
||||||
|
#[ORM\ManyToOne(inversedBy: 'photos')]
|
||||||
|
private ?Category $category = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, Photo>
|
||||||
|
*/
|
||||||
|
#[ORM\OneToMany(targetEntity: Photo::class, mappedBy: 'photos', cascade: ['persist'])]
|
||||||
|
private Collection $uploads;
|
||||||
|
|
||||||
|
#[ORM\Column(type: Types::TEXT)]
|
||||||
|
private ?string $text = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $url = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $thumbnail = null;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->uploads = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle(): ?string
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTitle(string $title): static
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDate(): ?\DateTime
|
||||||
|
{
|
||||||
|
return $this->date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDate(\DateTime $date): static
|
||||||
|
{
|
||||||
|
$this->date = $date;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCategory(): ?Category
|
||||||
|
{
|
||||||
|
return $this->category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCategory(?Category $category): static
|
||||||
|
{
|
||||||
|
$this->category = $category;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Photo>
|
||||||
|
*/
|
||||||
|
public function getUploads(): Collection
|
||||||
|
{
|
||||||
|
return $this->uploads;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addUpload(Photo $upload): static
|
||||||
|
{
|
||||||
|
if (!$this->uploads->contains($upload)) {
|
||||||
|
$this->uploads->add($upload);
|
||||||
|
$upload->setPhotos($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeUpload(Photo $upload): static
|
||||||
|
{
|
||||||
|
if ($this->uploads->removeElement($upload)) {
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($upload->getPhotos() === $this) {
|
||||||
|
$upload->setPhotos(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getText(): ?string
|
||||||
|
{
|
||||||
|
return $this->text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setText(string $text): static
|
||||||
|
{
|
||||||
|
$this->text = $text;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUrl(): ?string
|
||||||
|
{
|
||||||
|
return $this->url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUrl(string $url): static
|
||||||
|
{
|
||||||
|
$this->url = $url;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getThumbnail(): ?string
|
||||||
|
{
|
||||||
|
return $this->thumbnail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setThumbnail(string $thumbnail): static
|
||||||
|
{
|
||||||
|
$this->thumbnail = $thumbnail;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
148
src/Entity/Post.php
Normal file
148
src/Entity/Post.php
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\PostRepository;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: PostRepository::class)]
|
||||||
|
class Post
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $title = null;
|
||||||
|
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?\DateTime $date = null;
|
||||||
|
|
||||||
|
#[ORM\Column(type: Types::TEXT)]
|
||||||
|
private ?string $text = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $url = null;
|
||||||
|
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?bool $published = null;
|
||||||
|
|
||||||
|
#[ORM\ManyToOne(inversedBy: 'posts')]
|
||||||
|
private ?Category $category = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, Tag>
|
||||||
|
*/
|
||||||
|
#[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'posts')]
|
||||||
|
private Collection $tags;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->tags = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle(): ?string
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTitle(string $title): static
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDate(): ?\DateTime
|
||||||
|
{
|
||||||
|
return $this->date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDate(\DateTime $date): static
|
||||||
|
{
|
||||||
|
$this->date = $date;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getText(): ?string
|
||||||
|
{
|
||||||
|
return $this->text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setText(string $text): static
|
||||||
|
{
|
||||||
|
$this->text = $text;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUrl(): ?string
|
||||||
|
{
|
||||||
|
return $this->url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUrl(string $url): static
|
||||||
|
{
|
||||||
|
$this->url = $url;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isPublished(): ?bool
|
||||||
|
{
|
||||||
|
return $this->published;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPublished(bool $published): static
|
||||||
|
{
|
||||||
|
$this->published = $published;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCategory(): ?Category
|
||||||
|
{
|
||||||
|
return $this->category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCategory(?Category $category): static
|
||||||
|
{
|
||||||
|
$this->category = $category;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Tag>
|
||||||
|
*/
|
||||||
|
public function getTags(): Collection
|
||||||
|
{
|
||||||
|
return $this->tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addTag(Tag $tag): static
|
||||||
|
{
|
||||||
|
if (!$this->tags->contains($tag)) {
|
||||||
|
$this->tags->add($tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeTag(Tag $tag): static
|
||||||
|
{
|
||||||
|
$this->tags->removeElement($tag);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
75
src/Entity/Tag.php
Normal file
75
src/Entity/Tag.php
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\TagRepository;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: TagRepository::class)]
|
||||||
|
class Tag
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $title = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, Post>
|
||||||
|
*/
|
||||||
|
#[ORM\ManyToMany(targetEntity: Post::class, mappedBy: 'tags')]
|
||||||
|
private Collection $posts;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->posts = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle(): ?string
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTitle(string $title): static
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Post>
|
||||||
|
*/
|
||||||
|
public function getPosts(): Collection
|
||||||
|
{
|
||||||
|
return $this->posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addPost(Post $post): static
|
||||||
|
{
|
||||||
|
if (!$this->posts->contains($post)) {
|
||||||
|
$this->posts->add($post);
|
||||||
|
$post->addTag($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removePost(Post $post): static
|
||||||
|
{
|
||||||
|
if ($this->posts->removeElement($post)) {
|
||||||
|
$post->removeTag($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
112
src/Entity/User.php
Normal file
112
src/Entity/User.php
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Repository\UserRepository;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: UserRepository::class)]
|
||||||
|
#[ORM\Table(name: '`user`')]
|
||||||
|
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_USERNAME', fields: ['username'])]
|
||||||
|
#[UniqueEntity(fields: ['username'], message: 'There is already an account with this username')]
|
||||||
|
class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 180)]
|
||||||
|
private ?string $username = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var list<string> The user roles
|
||||||
|
*/
|
||||||
|
#[ORM\Column]
|
||||||
|
private array $roles = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string The hashed password
|
||||||
|
*/
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?string $password = null;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUsername(): ?string
|
||||||
|
{
|
||||||
|
return $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUsername(string $username): static
|
||||||
|
{
|
||||||
|
$this->username = $username;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A visual identifier that represents this user.
|
||||||
|
*
|
||||||
|
* @see UserInterface
|
||||||
|
*/
|
||||||
|
public function getUserIdentifier(): string
|
||||||
|
{
|
||||||
|
return (string) $this->username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserInterface
|
||||||
|
*/
|
||||||
|
public function getRoles(): array
|
||||||
|
{
|
||||||
|
$roles = $this->roles;
|
||||||
|
// guarantee every user at least has ROLE_USER
|
||||||
|
$roles[] = 'ROLE_USER';
|
||||||
|
$roles[] = 'ROLE_ADMIN';
|
||||||
|
|
||||||
|
return array_unique($roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param list<string> $roles
|
||||||
|
*/
|
||||||
|
public function setRoles(array $roles): static
|
||||||
|
{
|
||||||
|
$this->roles = $roles;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see PasswordAuthenticatedUserInterface
|
||||||
|
*/
|
||||||
|
public function getPassword(): ?string
|
||||||
|
{
|
||||||
|
return $this->password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPassword(string $password): static
|
||||||
|
{
|
||||||
|
$this->password = $password;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure the session doesn't contain actual password hashes by CRC32C-hashing them, as supported since Symfony 7.3.
|
||||||
|
*/
|
||||||
|
public function __serialize(): array
|
||||||
|
{
|
||||||
|
$data = (array) $this;
|
||||||
|
$data["\0".self::class."\0password"] = hash('crc32c', $this->password);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/Form/CategoryAutocompleteField.php
Normal file
34
src/Form/CategoryAutocompleteField.php
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Entity\Category;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\UX\Autocomplete\Form\AsEntityAutocompleteField;
|
||||||
|
use Symfony\UX\Autocomplete\Form\BaseEntityAutocompleteType;
|
||||||
|
|
||||||
|
|
||||||
|
#[AsEntityAutocompleteField]
|
||||||
|
class CategoryAutocompleteField extends AbstractType
|
||||||
|
{
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'class' => Category::class,
|
||||||
|
'searchable_fields' => ['title'],
|
||||||
|
'label' => 'Category',
|
||||||
|
'choice_label' => 'title',
|
||||||
|
'multiple' => false,
|
||||||
|
'tom_select_options' => [
|
||||||
|
'create' => true,
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent(): string
|
||||||
|
{
|
||||||
|
return BaseEntityAutocompleteType::class;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/Form/DataTransformer/UploadDataTransformer.php
Normal file
45
src/Form/DataTransformer/UploadDataTransformer.php
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form\DataTransformer;
|
||||||
|
|
||||||
|
use App\Entity\Photo;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Component\Form\DataTransformerInterface;
|
||||||
|
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||||
|
use Symfony\Component\HttpFoundation\File\File;
|
||||||
|
|
||||||
|
class UploadDataTransformer implements DataTransformerInterface
|
||||||
|
{
|
||||||
|
public function __construct(private EntityManagerInterface $entityManager) {}
|
||||||
|
|
||||||
|
public function transform($photo) : string
|
||||||
|
{
|
||||||
|
if ($photo === null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $photo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reverseTransform($filename): ?File
|
||||||
|
{
|
||||||
|
if (!$filename) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$photo = $this->entityManager->getRepository(Photo::class)->findOneBy(['file' => $filename]);
|
||||||
|
|
||||||
|
$directoryName = $photo->getPhotos()->getTitle();
|
||||||
|
|
||||||
|
$directoryName = 'photos/' . strtolower(str_replace(' ', '_', $directoryName));
|
||||||
|
|
||||||
|
$file = new File($directoryName . '/' . $filename);
|
||||||
|
|
||||||
|
if ($file === null) {
|
||||||
|
throw new TransformationFailedException(sprintf('Photo with the filename "%s" does not exist!', $filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue