Compare commits
48 Commits
gitea-work
...
main
Author | SHA1 | Date |
---|---|---|
suroh | 720f2051cc | |
suroh | bc8039cc8c | |
suroh | 60072228ed | |
suroh | c525ed335e | |
suroh | d3fea6cff3 | |
suroh | f0bf48134c | |
suroh | 437ef394e7 | |
suroh | 26792fcfdf | |
suroh | f8d3e030ef | |
suroh | 9e34a12b25 | |
suroh | 5fd7fb4c07 | |
suroh | 459d283178 | |
suroh | 9055bf392f | |
suroh | dff1fa475b | |
suroh | 8e99275fcc | |
suroh | 3add951354 | |
suroh | 7245cf2c43 | |
suroh | 300c1a49d3 | |
suroh | 746c8dbecc | |
suroh | 57ffff78c6 | |
suroh | 7eb8dec838 | |
suroh | 7fe72ad9b6 | |
suroh | b4a0866cd9 | |
suroh | 963a3d5cdd | |
suroh | 10d66857e4 | |
suroh | 76f49fe30b | |
suroh | 513b4f2f67 | |
suroh | e3c8560e68 | |
suroh | e8b0b9a512 | |
suroh | 7ac8f5172f | |
suroh | 5ebb518142 | |
suroh | f1ae87f7ae | |
suroh | b07a888344 | |
suroh | 43c9a340f5 | |
suroh | 9d250bb385 | |
suroh | fbb4ea33a2 | |
suroh | be7c0a7084 | |
suroh | aeac2cb2f8 | |
suroh | 10e3ce5939 | |
suroh | c468c0fd17 | |
suroh | 057c3a48d3 | |
suroh | 3b6ee68a11 | |
suroh | 2246620a2e | |
suroh | 52091371b3 | |
suroh | d175287320 | |
suroh | 313e234a63 | |
suroh | 616f2f9dce | |
suroh | 5e4e4bf4b8 |
|
@ -46,7 +46,7 @@ module.exports = (config) => {
|
||||||
let sorted = []
|
let sorted = []
|
||||||
let unsorted = []
|
let unsorted = []
|
||||||
|
|
||||||
let pages = collection.getFilteredByGlob(`src/_content/work/${cat}/*.md`)
|
let pages = collection.getFilteredByGlob(`_content/${cat}/*.md`)
|
||||||
|
|
||||||
for (let page of pages) {
|
for (let page of pages) {
|
||||||
if (page.data.sort) {
|
if (page.data.sort) {
|
||||||
|
@ -66,7 +66,6 @@ module.exports = (config) => {
|
||||||
|
|
||||||
let _p = collection.getFilteredByGlob('_content/*.md')
|
let _p = collection.getFilteredByGlob('_content/*.md')
|
||||||
let pages = {}
|
let pages = {}
|
||||||
// _cat = { ..._cat, ...pages }
|
|
||||||
|
|
||||||
_p.forEach(p => {
|
_p.forEach(p => {
|
||||||
if (p.data.title != 'index') {
|
if (p.data.title != 'index') {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: work.suroh.tk deploy
|
name: 11ty build and deploy for work.suroh.tk
|
||||||
run-name: ${{ github.action_repository }} is being built and deployed
|
run-name: 11ty build and deploy for work.suroh.tk
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
@ -7,15 +7,30 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
build-deploy:
|
build-deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
volumes:
|
||||||
|
- /www
|
||||||
steps:
|
steps:
|
||||||
- name: Clone code to runner
|
- name: Clone code to runner
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Move to directory
|
- name: Move to directory
|
||||||
run: cd ${{ github.workspace }}
|
run: cd ${{ gitea.workspace }}
|
||||||
|
|
||||||
- name: Building dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm i
|
||||||
|
|
||||||
- name: Check deployment directory
|
- name: Build 11ty site
|
||||||
run: ls -lh /var/www/
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Check folders
|
||||||
|
run: ls -lh /
|
||||||
|
|
||||||
|
- name: Create folder if needed
|
||||||
|
run: if [ ! -d /www/${{ gitea.event.repository.name }} ]; then mkdir /www/${{ gitea.event.repository.name }}; fi
|
||||||
|
|
||||||
|
- name: Copy built website
|
||||||
|
run: cp -r _site/. /www/${{ gitea.event.repository.name }}
|
||||||
|
|
||||||
|
- name: Fix ownership
|
||||||
|
run: chown -R www-data:www-data /www/${{ gitea.event.repository.name }}
|
||||||
|
|
160
_content/cv.md
160
_content/cv.md
|
@ -6,157 +6,163 @@ category: root
|
||||||
|
|
||||||
## Max Franklin
|
## Max Franklin
|
||||||
|
|
||||||
_mx[at]suroh.tk_<br>
|
_mx[at]suroh.tk_\
|
||||||
_+33 (0) 7 66 14 33 99_<br>
|
_+33 (0) 7 66 14 33 99_\
|
||||||
_[@suroh@post.lurk.org](https://post.lurk.org/@suroh)_
|
_[@suroh@post.lurk.org](https://post.lurk.org/@suroh)_
|
||||||
|
|
||||||
### Education
|
### Education
|
||||||
|
|
||||||
_Piet Zwart Institute_<br>
|
_Piet Zwart Institute_\
|
||||||
2016 - 2018 // Rotterdam, NL<br>
|
2016 - 2018 // Rotterdam, NL\
|
||||||
Master's in Media Design : Experimental Publishing
|
Master's in Media Design : Experimental Publishing
|
||||||
|
|
||||||
_Conservatorium of Sydney (University of Sydney)_<br>
|
_Conservatorium of Sydney (University of Sydney)_\
|
||||||
2009 // Sydney, AU<br>
|
2009 // Sydney, AU\
|
||||||
Bachelor Jazz Performance (Saxophone) & Creative Sound Engineering
|
Bachelor Jazz Performance (Saxophone) & Creative Sound Engineering
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
Arturia\
|
||||||
|
2024 - Current // Grenoble, FR\
|
||||||
|
Fullstack developer
|
||||||
|
|
||||||
### Teaching
|
### Teaching
|
||||||
|
|
||||||
_Willem de Kooning Academie_<br>
|
_Willem de Kooning Academie_\
|
||||||
2020 - 2023 // Rotterdam, NL<br>
|
2020 - 2023 // Rotterdam, NL\
|
||||||
Tutor within the Graphic Design Major
|
Tutor within the Graphic Design Major
|
||||||
|
|
||||||
_Paris College of Art_<br>
|
_Paris College of Art_\
|
||||||
2014 - 2022 // Paris, FR<br>
|
2014 - 2022 // Paris, FR\
|
||||||
Faculty Member within the Communication Design department
|
Faculty Member within the Communication Design department
|
||||||
|
|
||||||
_LISAA Graphic Design_<br>
|
_LISAA Graphic Design_\
|
||||||
2020 - 2021 // Paris, FR<br>
|
2020 - 2021 // Paris, FR\
|
||||||
Faculty Member within the Graphic Design department
|
Faculty Member within the Graphic Design department
|
||||||
|
|
||||||
_École Européenne des Métiers de l'Internet_<br>
|
_École Européenne des Métiers de l'Internet_\
|
||||||
2018 - 2019 // Paris, FR<br>
|
2018 - 2019 // Paris, FR\
|
||||||
Faculty Member within the Graphic Design department
|
Faculty Member within the Graphic Design department
|
||||||
|
|
||||||
### Freelance
|
### Freelance
|
||||||
|
|
||||||
_Meredith Monk : Rooms for Listening & Looking_<br>
|
_Meredith Monk : Rooms for Listening & Looking_\
|
||||||
Oude Kerk<br>
|
Oude Kerk\
|
||||||
2023 // Amsterdam, NL<br>
|
2023 // Amsterdam, NL\
|
||||||
Development of application to showcase video and audio work
|
Development of application to showcase video and audio work
|
||||||
|
|
||||||
_Fondation Meyer_<br>
|
_Fondation Meyer_\
|
||||||
2022 // Paris, FR<br>
|
2022 // Paris, FR\
|
||||||
Website development
|
Website development
|
||||||
|
|
||||||
_Green-Shoots_<br>
|
_Green-Shoots_\
|
||||||
NOOR Images<br>
|
NOOR Images\
|
||||||
2022 // Paris, FR<br>
|
2022 // Paris, FR\
|
||||||
Website development
|
Website development
|
||||||
|
|
||||||
_World Press Photo_<br>
|
_World Press Photo_\
|
||||||
2021 // Paris, FR<br>
|
2021 // Paris, FR\
|
||||||
Website development for online exhibition
|
Website development for online exhibition
|
||||||
|
|
||||||
_Performance Lab Workshop Series_<br>
|
_Performance Lab Workshop Series_\
|
||||||
2019 // Rotterdam, NL<br>
|
2019 // Rotterdam, NL\
|
||||||
Website design & development
|
Website design & development
|
||||||
|
|
||||||
### Sound
|
### Sound
|
||||||
|
|
||||||
#### Performances
|
#### Performances
|
||||||
_alternative echelons_<br>
|
_alternative echelons_\
|
||||||
2020 // UBIK, Rotterdam, NL<br>
|
2020 // UBIK, Rotterdam, NL\
|
||||||
|
|
||||||
_Design Days Finnisage_<br>
|
_Design Days Finnisage_\
|
||||||
Espace 15<br>
|
Espace 15\
|
||||||
2019 // Paris, FR
|
2019 // Paris, FR
|
||||||
|
|
||||||
_Read My Lips: No New Taxes_<br>
|
_Read My Lips: No New Taxes_\
|
||||||
Galerie Lecq<br>
|
Galerie Lecq\
|
||||||
2019 // Rotterdam, NL
|
2019 // Rotterdam, NL
|
||||||
|
|
||||||
_E-ARTHA_<br>
|
_E-ARTHA_\
|
||||||
DePlayer<br>
|
DePlayer\
|
||||||
2018 // Rotterdam, NL
|
2018 // Rotterdam, NL
|
||||||
|
|
||||||
_North Sea Jazz Around Town_<br>
|
_North Sea Jazz Around Town_\
|
||||||
VARIA<br>
|
VARIA\
|
||||||
2018 // Rotterdam, NL
|
2018 // Rotterdam, NL
|
||||||
|
|
||||||
_POST TOAST_<br>
|
_POST TOAST_\
|
||||||
Red Light Radio<br>
|
Red Light Radio\
|
||||||
2018 // Amsterdam, NL
|
2018 // Amsterdam, NL
|
||||||
|
|
||||||
#### Soundtracks
|
#### Soundtracks
|
||||||
|
|
||||||
_Dragon Hunt_<br>
|
_Dragon Hunt_\
|
||||||
by _Marko Gutić Mižimakov_<br>
|
by _Marko Gutić Mižimakov_\
|
||||||
2023 // Brussels, BE<br>
|
2023 // Brussels, BE\
|
||||||
|
|
||||||
_alternative echelons_ (trailer)<br>
|
_alternative echelons_ (trailer)\
|
||||||
by Amy Pickles<br>
|
by Amy Pickles\
|
||||||
2019
|
2019
|
||||||
|
|
||||||
_Ghost Terminal_<br>
|
_Ghost Terminal_\
|
||||||
by Ryan Cherewaty<br>
|
by Ryan Cherewaty\
|
||||||
2019
|
2019
|
||||||
|
|
||||||
_Memory of Death's Dream_<br>
|
_Memory of Death's Dream_\
|
||||||
by Ryan Cherewaty<br>
|
by Ryan Cherewaty\
|
||||||
2019
|
2019
|
||||||
|
|
||||||
#### Studio Experience
|
#### Studio Experience
|
||||||
|
|
||||||
_Linear Recording_<br>
|
_Linear Recording_\
|
||||||
2009 – 2010 // Sydney, AU<br>
|
2009 – 2010 // Sydney, AU\
|
||||||
Assistant Sound Engineer
|
Assistant Sound Engineer
|
||||||
|
|
||||||
### Selected Exhibitions & Events
|
### Selected Exhibitions & Events
|
||||||
|
|
||||||
_Sounds to See_<br>
|
_Sounds to See_\
|
||||||
Sign Gallery<br>
|
Sign Gallery\
|
||||||
2019 // Groningen, NL<br>
|
2019 // Groningen, NL\
|
||||||
Group exhibition. Presented _A Container in Two Movements_.
|
Group exhibition. Presented _A Container in Two Movements_.
|
||||||
|
|
||||||
_Autonomous Archive_<br>
|
_Autonomous Archive_\
|
||||||
Het Nieuw Instituut<br>
|
Het Nieuw Instituut\
|
||||||
2017 // Rotterdam, NL<br>
|
2017 // Rotterdam, NL\
|
||||||
Archival machine, installation and research project centred around autonomous living and archival practices. Presented alongside the Architecture of Appropriation exhibition.
|
Archival machine, installation and research project centred around autonomous living and archival practices. Presented alongside the Architecture of Appropriation exhibition.
|
||||||
|
|
||||||
_TGC#3 : Euclid_<br>
|
_TGC#3 : Euclid_\
|
||||||
De Player<br>
|
De Player\
|
||||||
2017 // Rotterdam, NL<br>
|
2017 // Rotterdam, NL\
|
||||||
Experimental sound publication object and performative instrument. Collaborative project between De Player and the Piet Zwart Experimental Publishing unit.</p>
|
Experimental sound publication object and performative instrument. Collaborative project between De Player and the Piet Zwart Experimental Publishing unit.
|
||||||
|
|
||||||
_LowTechLabLondon2016_<br>
|
_LowTechLabLondon2016_\
|
||||||
Saatchi Gallery<br>
|
Saatchi Gallery\
|
||||||
2016 // London, UK<br>
|
2016 // London, UK\
|
||||||
International art lab organised by Raul Marroquin around the theme of Low Tech.
|
International art lab organised by Raul Marroquin around the theme of Low Tech.
|
||||||
|
|
||||||
_Festival de Projets Scolaires_<br>
|
_Festival de Projets Scolaires_\
|
||||||
La Gaîté lyrique<br>
|
La Gaîté lyrique\
|
||||||
2016 // Paris, FR<br>
|
2016 // Paris, FR\
|
||||||
Partnership workshop show with Paris College of Art students and faculty.
|
Partnership workshop show with Paris College of Art students and faculty.
|
||||||
|
|
||||||
_IDENTITE REVE(L)EE_<br>
|
_IDENTITE REVE(L)EE_\
|
||||||
*Mi Gallery<br>
|
*Mi Gallery\
|
||||||
Paris Digital Week<br>
|
Paris Digital Week\
|
||||||
2015 // Paris, FR<br>
|
2015 // Paris, FR\
|
||||||
Collaborative piece presented at *Mi Gallery as part of Paris Digital Week.
|
Collaborative piece presented at *Mi Gallery as part of Paris Digital Week.
|
||||||
|
|
||||||
_Barcu Art Fair_<br>
|
_Barcu Art Fair_\
|
||||||
2015 // Bogota, CO<br>
|
2015 // Bogota, CO\
|
||||||
Presentation via Skype on Collaborative Art, Interactivity and Improvisation.
|
Presentation via Skype on Collaborative Art, Interactivity and Improvisation.
|
||||||
|
|
||||||
### Recent Programmes & Resdencies
|
### Recent Programmes & Resdencies
|
||||||
|
|
||||||
_Thresholds of the Algorithmic_<br>
|
_Thresholds of the Algorithmic_\
|
||||||
Algorithms that Matter<br>
|
Algorithms that Matter\
|
||||||
2018 // Bergen, NO<br>
|
2018 // Bergen, NO\
|
||||||
Workshop-in-Exposition is a hybrid format that places the workshop inside an exhibition context, where the exposed works and artefacts form the basis of the workshop’s activity.
|
Workshop-in-Exposition is a hybrid format that places the workshop inside an exhibition context, where the exposed works and artefacts form the basis of the workshop’s activity.
|
||||||
|
|
||||||
_Get a Room Residency_<br>
|
_Get a Room Residency_\
|
||||||
Frontyard<br>
|
Frontyard\
|
||||||
2018 // Sydney, AU<br>
|
2018 // Sydney, AU\
|
||||||
Research residency around Master's research on Software and Improvisation.
|
Research residency around Master's research on Software and Improvisation.
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
title: Quickdial Extension
|
||||||
|
git: https://github.com/m3astwood/ext.quickdial
|
||||||
|
tags:
|
||||||
|
- brower extension
|
||||||
|
- frontend
|
||||||
|
- development
|
||||||
|
summary: Personal project to learn how to develop and publish a firefox browser extension.
|
||||||
|
order: 999
|
||||||
|
imgFeat:
|
||||||
|
gallery:
|
||||||
|
- /dev/images/ext.light.main.png
|
||||||
|
- /dev/images/ext.dark.cat.png
|
||||||
|
- /dev/images/ext.dark.book.png
|
||||||
|
- /dev/images/ext.dark.mobile.png
|
||||||
|
---
|
||||||
|
|
||||||
|
# Quickdial Browser Extension
|
||||||
|
|
||||||
|
[git]({{git}})
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
A personal project to learn how to develop and publish a firefox browser extension.
|
||||||
|
|
||||||
|
Simple homescreen page that displays bookmarks for easy access.
|
||||||
|
|
||||||
|
![screenshot overview of web extension displaying bookmarks](/dev/images/ext.dark.main.png)
|
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
|
@ -2,3 +2,7 @@
|
||||||
title: index
|
title: index
|
||||||
layout: page.webc
|
layout: page.webc
|
||||||
---
|
---
|
||||||
|
|
||||||
|
Homepage of Max Franklin. I am an uneasy artist/musician/developer and enthusiastic educator of graphic design.
|
||||||
|
|
||||||
|
Use the little blocks above to navigate my audio, development, and (art?) work, and view my [CV](/cv).
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
---
|
---
|
||||||
title: fragile mastery
|
title: fragile mastery
|
||||||
|
git: https://git.suroh.tk/suroh/mastersthesis.git
|
||||||
|
---
|
||||||
|
|
||||||
|
[git]({{git}})
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# fragile mastery
|
# fragile mastery
|
||||||
|
|
||||||
Fragile Mastery is structured around conversations I had with my peers who are improvising musicians, supported by research on software, improvisation, and collective practices. These bodies of research are applied to my own works and my improvisational practice involving software and music. My interest in software and improvisation has lead me to ask, how can improvisation augment my practice involving music and software?
|
|
||||||
|
|
||||||
Fragile Mastery is the title of my master's thesis which now forms the basis of my work outside of a performance practice. Manifestations of this research have taken the form of printed material, digital intrusions into music performance tools and spaces, installations, and sound recordings. It also heavily influences my pedagogical pursuits where I try and re-consider implications of mastery and value within the institutions of a university, classroom, workshop or residency.
|
Fragile Mastery is the title of my master's thesis which now forms the basis of my work outside of a performance practice. Manifestations of this research have taken the form of printed material, digital intrusions into music performance tools and spaces, installations, and sound recordings. It also heavily influences my pedagogical pursuits where I try and re-consider implications of mastery and value within the institutions of a university, classroom, workshop or residency.
|
||||||
|
|
||||||
My thesis is freely available on my [git repository](https://git.suroh.tk/suroh/mastersThesis). It was designed for print using all open source tools, and generated using custom scripts which can also be found on my git.
|
Fragile Mastery is structured around conversations I had with my peers who are improvising musicians, supported by research on software, improvisation, and collective practices. These bodies of research are applied to my own works and my improvisational practice involving software and music. My interest in software and improvisation has lead me to ask, how can improvisation augment my practice involving music and software?
|
||||||
|
|
||||||
|
My thesis is available on my [git repository](https://git.suroh.tk/suroh/mastersthesis.git). It was designed for print using all open source tools, and generated using custom scripts which can also be found on my git.
|
||||||
|
|
||||||
![](/work/images/fragileMastery/thumb-gradInstallation.jpg)
|
![](/work/images/fragileMastery/thumb-gradInstallation.jpg)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<meta name="color-scheme" content="dark light">
|
||||||
<title @text="site.name"></title>
|
<title @text="site.name"></title>
|
||||||
|
|
||||||
<meta name="generator" :content="site.generator">
|
<meta name="generator" :content="site.generator">
|
||||||
|
|
|
@ -17,8 +17,8 @@ customElements.define('nav-link', NavLink)
|
||||||
|
|
||||||
<style webc:scoped>
|
<style webc:scoped>
|
||||||
:host {
|
:host {
|
||||||
--color-solid: #1e1e3cff;
|
--colour-solid: var(--primary-colour);
|
||||||
--color-transparent: #1e1e3c33;
|
--colour-transparent: var(--primary-colour-25);
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
color: var(--color-transparent);
|
color: var(--color-transparent);
|
||||||
|
|
|
@ -13,7 +13,7 @@ class NavPrimary extends HTMLElement {
|
||||||
this.setupAudio()
|
this.setupAudio()
|
||||||
|
|
||||||
this.categories = this.querySelectorAll('nav-link')
|
this.categories = this.querySelectorAll('nav-link')
|
||||||
this.subs = this.querySelectorAll('ul')
|
this.subs = this.querySelectorAll('#sub ul')
|
||||||
|
|
||||||
this.activate()
|
this.activate()
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class NavPrimary extends HTMLElement {
|
||||||
const category = n.attributes.getNamedItem('category')
|
const category = n.attributes.getNamedItem('category')
|
||||||
const link = n.attributes.getNamedItem('link')
|
const link = n.attributes.getNamedItem('link')
|
||||||
|
|
||||||
console.log(link)
|
console.log('category click', link, category)
|
||||||
|
|
||||||
if (link) {
|
if (link) {
|
||||||
history.pushState({}, '', link.value)
|
history.pushState({}, '', link.value)
|
||||||
|
@ -63,7 +63,6 @@ class NavPrimary extends HTMLElement {
|
||||||
activate() {
|
activate() {
|
||||||
let active, toOpen
|
let active, toOpen
|
||||||
|
|
||||||
|
|
||||||
this.categories.forEach(c => {
|
this.categories.forEach(c => {
|
||||||
const { value } = c.attributes.getNamedItem('category') || false
|
const { value } = c.attributes.getNamedItem('category') || false
|
||||||
|
|
||||||
|
@ -74,6 +73,7 @@ class NavPrimary extends HTMLElement {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
console.log(this.subs)
|
||||||
this.subs.forEach(s => {
|
this.subs.forEach(s => {
|
||||||
const { name } = s.dataset
|
const { name } = s.dataset
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,10 @@
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="audioToggle"></button>
|
<div class="controls">
|
||||||
|
<button class="audioToggle"></button>
|
||||||
|
<theme-switcher></theme-switcher>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<nav id="sub" slot="subnav">
|
<nav id="sub" slot="subnav">
|
||||||
|
@ -31,6 +34,12 @@
|
||||||
<script src="nav-primary.js" type="module"></script>
|
<script src="nav-primary.js" type="module"></script>
|
||||||
|
|
||||||
<style webc:scoped>
|
<style webc:scoped>
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* switch element taken from Andy Bell's article
|
||||||
|
* which can be found here:
|
||||||
|
* https://piccalil.li/blog/a-highly-configurable-switch-component-using-modern-css/
|
||||||
|
*/
|
||||||
/* => HOST */
|
/* => HOST */
|
||||||
:host {
|
:host {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -64,6 +73,12 @@ nav-link[data-name="<~"] {
|
||||||
gap: 0.25em;
|
gap: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* => CONTROLS */
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
/* => AUDIO TOGGLE */
|
/* => AUDIO TOGGLE */
|
||||||
.audioToggle {
|
.audioToggle {
|
||||||
background: none;
|
background: none;
|
||||||
|
@ -73,7 +88,7 @@ nav-link[data-name="<~"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.audioToggle:hover {
|
.audioToggle:hover {
|
||||||
color: #CECECE;
|
color: var(--primary-colour);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: color ease-in-out 0.1s;
|
transition: color ease-in-out 0.1s;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +116,6 @@ nav-link[data-name="<~"] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#sub > ul {
|
#sub > ul {
|
||||||
grid-row: 1 / span 1;
|
grid-row: 1 / span 1;
|
||||||
grid-column: 1 / span 1;
|
grid-column: 1 / span 1;
|
||||||
|
@ -136,14 +150,13 @@ ul.active {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 33vw;
|
font-size: 33vw;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
color: var(--neutral-100);
|
||||||
transform: translateY(100px);
|
transform: translateY(100px);
|
||||||
transform-origin: bottom left;
|
transform-origin: bottom left;
|
||||||
mix-blend-mode: difference;
|
|
||||||
transition: opacity ease-in-out 0.1s, transform ease-in-out 0.1s;
|
transition: opacity ease-in-out 0.1s, transform ease-in-out 0.1s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menuItem h1.active {
|
#menuItem h1.active {
|
||||||
mix-blend-mode: difference;
|
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
transform: translateY(-600px) !important;
|
transform: translateY(-600px) !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
<label class="switch-input">
|
||||||
|
<span class="visually-hidden">Enable setting</span>
|
||||||
|
<input type="checkbox" role="switch" class="visually-hidden" />
|
||||||
|
<span class="switch-input__thumb" aria-hidden="true"></span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
customElements.define('theme-switcher', class extends HTMLElement {
|
||||||
|
currentTheme
|
||||||
|
preferDark
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
|
||||||
|
this.preferDark = window.matchMedia("(prefers-color-scheme: dark)")
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
const checkbox = this.querySelector('input[type="checkbox"]')
|
||||||
|
this.currentTheme = localStorage.getItem('theme')
|
||||||
|
|
||||||
|
if (this.currentTheme == 'dark') {
|
||||||
|
checkbox.checked = true
|
||||||
|
document.body.classList.toggle('dark')
|
||||||
|
} else if (this.currentTheme == 'light') {
|
||||||
|
checkbox.checked = false
|
||||||
|
document.body.classList.toggle('light')
|
||||||
|
} else {
|
||||||
|
console.log(this.preferDark)
|
||||||
|
checkbox.checked = this.preferDark
|
||||||
|
}
|
||||||
|
|
||||||
|
checkbox.addEventListener('click', () => {
|
||||||
|
let theme
|
||||||
|
if (this.preferDark.matches) {
|
||||||
|
document.body.classList.toggle("light")
|
||||||
|
theme = document.body.classList.contains("light")
|
||||||
|
? "light"
|
||||||
|
: "dark"
|
||||||
|
} else {
|
||||||
|
document.body.classList.toggle("dark")
|
||||||
|
theme = document.body.classList.contains("dark")
|
||||||
|
? "dark"
|
||||||
|
: "light"
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem("theme", theme)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style webc:scoped>
|
||||||
|
/* Styles */
|
||||||
|
:host {
|
||||||
|
--switch-input-thumb-size: 0.88em;
|
||||||
|
--switch-input-thumb-bg: var(--bg-colour);
|
||||||
|
--switch-input-thumb-stroke: 1px solid var(--primary-colour-25);
|
||||||
|
--switch-input-off-bg: var(--neutral-100);
|
||||||
|
--switch-input-off-text: var(--neutral-900);
|
||||||
|
--switch-input-on-bg: var(--neutral-100-25);
|
||||||
|
--switch-input-on-text: var(--neutral-100);
|
||||||
|
--switch-input-gutter: 1px;
|
||||||
|
--switch-input-decor-space: var(--switch-input-gutter) 0.5ch;
|
||||||
|
--switch-input-focus-stroke: 2px solid #ff6978;
|
||||||
|
--switch-input-font-weight: bold;
|
||||||
|
/* --switch-input-font-family: sans-serif; */
|
||||||
|
--switch-input-font-size: 50cqw;
|
||||||
|
--switch-input-transition: inset 50ms linear;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visually-hidden {
|
||||||
|
border: 0;
|
||||||
|
clip: rect(0 0 0 0);
|
||||||
|
height: auto;
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input {
|
||||||
|
width: calc(
|
||||||
|
(var(--switch-input-thumb-size) * 2) + (var(--switch-input-gutter) * 3)
|
||||||
|
);
|
||||||
|
height: calc(
|
||||||
|
var(--switch-input-thumb-size) + (var(--switch-input-gutter) * 2)
|
||||||
|
);
|
||||||
|
border-radius: calc(
|
||||||
|
var(--switch-input-thumb-size) + var(--switch-input-gutter)
|
||||||
|
);
|
||||||
|
padding: var(--switch-input-gutter);
|
||||||
|
background: var(--switch-input-off-bg);
|
||||||
|
color: var(--switch-input-off-text);
|
||||||
|
text-align: left;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-family: var(--switch-input-font-family);
|
||||||
|
font-weight: var(--switch-input-font-weight);
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
container-type: inline-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input__decor {
|
||||||
|
position: absolute;
|
||||||
|
inset-block: 0;
|
||||||
|
inset-inline-start: 0;
|
||||||
|
padding: var(--switch-input-decor-space);
|
||||||
|
|
||||||
|
/* Font size lives here because we wanna use container units */
|
||||||
|
font-size: var(--switch-input-font-size);
|
||||||
|
|
||||||
|
/* Legacy */
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
/* align-items: center; */
|
||||||
|
|
||||||
|
/* Future */
|
||||||
|
/* align-content: center; */
|
||||||
|
/* display: block;
|
||||||
|
block-size: 100%; */
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input__decor[data-switch-input-state="off"] {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input__thumb {
|
||||||
|
display: block;
|
||||||
|
width: var(--switch-input-thumb-size);
|
||||||
|
height: var(--switch-input-thumb-size);
|
||||||
|
border-radius: var(--switch-input-thumb-size);
|
||||||
|
background: var(--switch-input-thumb-bg);
|
||||||
|
border: var(--switch-input-thumb-stroke);
|
||||||
|
z-index: 1;
|
||||||
|
position: absolute;
|
||||||
|
inset-block-start: var(--switch-input-gutter);
|
||||||
|
inset-inline-start: var(--switch-input-gutter);
|
||||||
|
transition: var(--switch-input-transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Could do this */
|
||||||
|
/* .switch-input:has(:focus) .switch-input__thumb {
|
||||||
|
outline: var(--switch-input-focus-stroke);
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* Better pointer experience. Still uses has because focus visible would have to be put direct on the checkbox */
|
||||||
|
.switch-input:has(:focus-visible) .switch-input__thumb {
|
||||||
|
outline: var(--switch-input-focus-stroke);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input:has(:checked) {
|
||||||
|
background: var(--switch-input-on-bg);
|
||||||
|
color: var(--switch-input-on-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input:has(:checked) .switch-input__thumb {
|
||||||
|
inset-inline-start: calc(
|
||||||
|
var(--switch-input-thumb-size) + (var(--switch-input-gutter) * 2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
</style>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,46 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: 'JetBrains';
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
src: url('JetBrainsMono-Regular.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'JetBrains';
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: italic;
|
||||||
|
src: local('JetBrainsMono'),
|
||||||
|
url('JetBrainsMono-Italic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'JetBrains';
|
||||||
|
font-weight: 200;
|
||||||
|
font-style: normal;
|
||||||
|
src: local('JetBrainsMono'),
|
||||||
|
url('JetBrainsMono-Light.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'JetBrains';
|
||||||
|
font-weight: 200;
|
||||||
|
font-style: italic;
|
||||||
|
src: local('JetBrainsMono'),
|
||||||
|
url('JetBrainsMono-LightItalic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'JetBrains';
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
src: local('JetBrainsMono'),
|
||||||
|
url('JetBrainsMono-Bold.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'JetBrains';
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
src: local('JetBrainsMono'),
|
||||||
|
url('JetBrainsMono-BoldItalic.woff2') format('woff2');
|
||||||
|
}
|
|
@ -1,20 +1,75 @@
|
||||||
/* PAGE STYLES */
|
/* PAGE STYLES */
|
||||||
@import url(https://cdn.jsdelivr.net/gh/tonsky/FiraCode@1.206/distr/fira_code.css);
|
@import url('./fonts/fonts.css');
|
||||||
|
|
||||||
* {
|
* {
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
|
font: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
-moz-text-size-adjust: none;
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
text-size-adjust: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* --> BASE STYLES <-- */
|
/* --> BASE STYLES <-- */
|
||||||
:root {
|
:root {
|
||||||
--page-margin-inline: 1em;
|
--page-margin-inline: 1em;
|
||||||
--neutral-900: #1e1e3cff;
|
--neutral-900: #080c11ff;
|
||||||
--neutral-900-25: #1e1e3c33;
|
--neutral-900-25: #080c1133;
|
||||||
|
--neutral-100: #c7c7c7ff;
|
||||||
|
--neutral-100-25: #c7c7c733;
|
||||||
|
|
||||||
|
--primary-colour: var(--neutral-900);
|
||||||
|
--primary-colour-25: var(--neutral-900-25);
|
||||||
|
--bg-colour: #fcfcfcff;
|
||||||
|
--bg-colour-25: #fcfcfc33;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
--primary-colour: var(--neutral-100);
|
||||||
|
--primary-colour-25: var(--neutral-100-25);
|
||||||
|
--bg-colour: var(--neutral-900);
|
||||||
|
--bg-colour-25: var(--neutral-900-25);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark {
|
||||||
|
--primary-colour: var(--neutral-100);
|
||||||
|
--primary-colour-25: var(--neutral-100-25);
|
||||||
|
--bg-colour: var(--neutral-900);
|
||||||
|
--bg-colour-25: var(--neutral-900-25);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.light {
|
||||||
|
--primary-colour: var(--neutral-900);
|
||||||
|
--primary-colour-25: var(--neutral-900-25);
|
||||||
|
--bg-colour: #fcfcfcff;
|
||||||
|
--bg-colour-25: #fcfcfc33;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: 'fira code', monospace;
|
font-family: 'JetBrains', 'fira code', monospace;
|
||||||
color: #1e1e3cff;
|
color: var(--primary-colour);
|
||||||
|
background-color: var(--bg-colour);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background-color: var(--bg-colour);
|
||||||
|
color: var(--primary-colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
|
@ -31,17 +86,16 @@ em {
|
||||||
}
|
}
|
||||||
|
|
||||||
a, a:visited {
|
a, a:visited {
|
||||||
color: #1e1e3cff;
|
color: var(--primary-colour);
|
||||||
padding-bottom: 2px;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-bottom: 1px #1e1e3c50 solid;
|
border-bottom: 1px var(--primary-colour) solid;
|
||||||
transition: color ease 0.5s, border ease 0.2s;
|
transition: color ease 0.5s, border ease 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
outline: 1px dotted var(--neutral-900);
|
outline: 1px dotted var(--bg-colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
|
@ -92,7 +146,7 @@ nav#toTop > span {
|
||||||
display: block;
|
display: block;
|
||||||
opacity: 0.0;
|
opacity: 0.0;
|
||||||
transform: translateY(-2em);
|
transform: translateY(-2em);
|
||||||
background-color: rgba(255,255,255,0.0);
|
background-color: var(--primary-colour);
|
||||||
padding: 0.3em 0.5em 0.5em;
|
padding: 0.3em 0.5em 0.5em;
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
transition: transform ease 0.5s, opacity ease 1s, background-color ease 0.5s 0.5s;
|
transition: transform ease 0.5s, opacity ease 1s, background-color ease 0.5s 0.5s;
|
||||||
|
@ -133,7 +187,7 @@ nav#sub > ul > li:before {
|
||||||
}
|
}
|
||||||
|
|
||||||
nav#sub > ul > li:hover {
|
nav#sub > ul > li:hover {
|
||||||
background: #d2d2d8;
|
background: var(--primary-colour-25);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +210,7 @@ section.page h1 {
|
||||||
@media screen and (min-width: 1360px) {
|
@media screen and (min-width: 1360px) {
|
||||||
body {
|
body {
|
||||||
font-size: 19px;
|
font-size: 19px;
|
||||||
line-height: 24px;
|
line-height: 1.5em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue