Compare commits

..

No commits in common. "main" and "gitea-workflow" have entirely different histories.

24 changed files with 111 additions and 450 deletions

View File

@ -46,7 +46,7 @@ module.exports = (config) => {
let sorted = []
let unsorted = []
let pages = collection.getFilteredByGlob(`_content/${cat}/*.md`)
let pages = collection.getFilteredByGlob(`src/_content/work/${cat}/*.md`)
for (let page of pages) {
if (page.data.sort) {
@ -66,6 +66,7 @@ module.exports = (config) => {
let _p = collection.getFilteredByGlob('_content/*.md')
let pages = {}
// _cat = { ..._cat, ...pages }
_p.forEach(p => {
if (p.data.title != 'index') {

View File

@ -1,5 +1,5 @@
name: 11ty build and deploy for work.suroh.tk
run-name: 11ty build and deploy for work.suroh.tk
name: work.suroh.tk deploy
run-name: ${{ github.action_repository }} is being built and deployed
on:
push:
branches:
@ -7,30 +7,15 @@ on:
jobs:
build-deploy:
runs-on: ubuntu-latest
container:
volumes:
- /www
steps:
- name: Clone code to runner
uses: actions/checkout@v4
- name: Move to directory
run: cd ${{ gitea.workspace }}
run: cd ${{ github.workspace }}
- name: Install dependencies
run: npm i
- name: Building dependencies
run: npm ci
- name: Build 11ty site
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 }}
- name: Check deployment directory
run: ls -lh /var/www/

View File

@ -6,163 +6,157 @@ category: root
## Max Franklin
_mx[at]suroh.tk_\
_+33 (0) 7 66 14 33 99_\
_mx[at]suroh.tk_<br>
_+33 (0) 7 66 14 33 99_<br>
_[@suroh@post.lurk.org](https://post.lurk.org/@suroh)_
### Education
_Piet Zwart Institute_\
2016 - 2018 // Rotterdam, NL\
_Piet Zwart Institute_<br>
2016 - 2018 // Rotterdam, NL<br>
Master's in Media Design : Experimental Publishing
_Conservatorium of Sydney (University of Sydney)_\
2009 // Sydney, AU\
_Conservatorium of Sydney (University of Sydney)_<br>
2009 // Sydney, AU<br>
Bachelor Jazz Performance (Saxophone) &amp; Creative Sound Engineering
### Development
Arturia\
2024 - Current // Grenoble, FR\
Fullstack developer
### Teaching
_Willem de Kooning Academie_\
2020 - 2023 // Rotterdam, NL\
_Willem de Kooning Academie_<br>
2020 - 2023 // Rotterdam, NL<br>
Tutor within the Graphic Design Major
_Paris College of Art_\
2014 - 2022 // Paris, FR\
_Paris College of Art_<br>
2014 - 2022 // Paris, FR<br>
Faculty Member within the Communication Design department
_LISAA Graphic Design_\
2020 - 2021 // Paris, FR\
_LISAA Graphic Design_<br>
2020 - 2021 // Paris, FR<br>
Faculty Member within the Graphic Design department
_École Européenne des Métiers de l'Internet_\
2018 - 2019 // Paris, FR\
_École Européenne des Métiers de l'Internet_<br>
2018 - 2019 // Paris, FR<br>
Faculty Member within the Graphic Design department
### Freelance
_Meredith Monk : Rooms for Listening & Looking_\
Oude Kerk\
2023 // Amsterdam, NL\
_Meredith Monk : Rooms for Listening & Looking_<br>
Oude Kerk<br>
2023 // Amsterdam, NL<br>
Development of application to showcase video and audio work
_Fondation Meyer_\
2022 // Paris, FR\
_Fondation Meyer_<br>
2022 // Paris, FR<br>
Website development
_Green-Shoots_\
NOOR Images\
2022 // Paris, FR\
_Green-Shoots_<br>
NOOR Images<br>
2022 // Paris, FR<br>
Website development
_World Press Photo_\
2021 // Paris, FR\
_World Press Photo_<br>
2021 // Paris, FR<br>
Website development for online exhibition
_Performance Lab Workshop Series_\
2019 // Rotterdam, NL\
_Performance Lab Workshop Series_<br>
2019 // Rotterdam, NL<br>
Website design & development
### Sound
#### Performances
_alternative echelons_\
2020 // UBIK, Rotterdam, NL\
_alternative echelons_<br>
2020 // UBIK, Rotterdam, NL<br>
_Design Days Finnisage_\
Espace 15\
_Design Days Finnisage_<br>
Espace 15<br>
2019 // Paris, FR
_Read My Lips: No New Taxes_\
Galerie Lecq\
_Read My Lips: No New Taxes_<br>
Galerie Lecq<br>
2019 // Rotterdam, NL
_E-ARTHA_\
DePlayer\
_E-ARTHA_<br>
DePlayer<br>
2018 // Rotterdam, NL
_North Sea Jazz Around Town_\
VARIA\
_North Sea Jazz Around Town_<br>
VARIA<br>
2018 // Rotterdam, NL
_POST TOAST_\
Red Light Radio\
_POST TOAST_<br>
Red Light Radio<br>
2018 // Amsterdam, NL
#### Soundtracks
_Dragon Hunt_\
by _Marko Gutić Mižimakov_\
2023 // Brussels, BE\
_Dragon Hunt_<br>
by _Marko Gutić Mižimakov_<br>
2023 // Brussels, BE<br>
_alternative echelons_ (trailer)\
by Amy Pickles\
_alternative echelons_ (trailer)<br>
by Amy Pickles<br>
2019
_Ghost Terminal_\
by Ryan Cherewaty\
_Ghost Terminal_<br>
by Ryan Cherewaty<br>
2019
_Memory of Death's Dream_\
by Ryan Cherewaty\
_Memory of Death's Dream_<br>
by Ryan Cherewaty<br>
2019
#### Studio Experience
_Linear Recording_\
2009 2010 // Sydney, AU\
_Linear Recording_<br>
2009 2010 // Sydney, AU<br>
Assistant Sound Engineer
### Selected Exhibitions & Events
_Sounds to See_\
Sign Gallery\
2019 // Groningen, NL\
_Sounds to See_<br>
Sign Gallery<br>
2019 // Groningen, NL<br>
Group exhibition. Presented _A Container in Two Movements_.
_Autonomous Archive_\
Het Nieuw Instituut\
2017 // Rotterdam, NL\
_Autonomous Archive_<br>
Het Nieuw Instituut<br>
2017 // Rotterdam, NL<br>
Archival machine, installation and research project centred around autonomous living and archival practices. Presented alongside the Architecture of Appropriation exhibition.
_TGC#3 : Euclid_\
De Player\
2017 // Rotterdam, NL\
Experimental sound publication object and performative instrument. Collaborative project between De Player and the Piet Zwart Experimental Publishing unit.
_TGC#3 : Euclid_<br>
De Player<br>
2017 // Rotterdam, NL<br>
Experimental sound publication object and performative instrument. Collaborative project between De Player and the Piet Zwart Experimental Publishing unit.</p>
_LowTechLabLondon2016_\
Saatchi Gallery\
2016 // London, UK\
_LowTechLabLondon2016_<br>
Saatchi Gallery<br>
2016 // London, UK<br>
International art lab organised by Raul Marroquin around the theme of Low Tech.
_Festival de Projets Scolaires_\
La Gaîté lyrique\
2016 // Paris, FR\
_Festival de Projets Scolaires_<br>
La Gaîté lyrique<br>
2016 // Paris, FR<br>
Partnership workshop show with Paris College of Art students and faculty.
_IDENTITE REVE(L)EE_\
*Mi Gallery\
Paris Digital Week\
2015 // Paris, FR\
_IDENTITE REVE(L)EE_<br>
*Mi Gallery<br>
Paris Digital Week<br>
2015 // Paris, FR<br>
Collaborative piece presented at *Mi Gallery as part of Paris Digital Week.
_Barcu Art Fair_\
2015 // Bogota, CO\
_Barcu Art Fair_<br>
2015 // Bogota, CO<br>
Presentation via Skype on Collaborative Art, Interactivity and Improvisation.
### Recent Programmes & Resdencies
_Thresholds of the Algorithmic_\
Algorithms that Matter\
2018 // Bergen, NO\
_Thresholds of the Algorithmic_<br>
Algorithms that Matter<br>
2018 // Bergen, NO<br>
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 workshops activity.
_Get a Room Residency_\
Frontyard\
2018 // Sydney, AU\
_Get a Room Residency_<br>
Frontyard<br>
2018 // Sydney, AU<br>
Research residency around Master's research on Software and Improvisation.

View File

@ -1,28 +0,0 @@
---
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.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

View File

@ -2,7 +2,3 @@
title: index
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).

View File

@ -1,18 +1,13 @@
---
title: fragile mastery
git: https://git.suroh.tk/suroh/mastersthesis.git
---
[git]({{git}})
---
# fragile mastery
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 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.
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.
![](/work/images/fragileMastery/thumb-gradInstallation.jpg)

View File

@ -5,7 +5,6 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="color-scheme" content="dark light">
<title @text="site.name"></title>
<meta name="generator" :content="site.generator">

View File

@ -17,8 +17,8 @@ customElements.define('nav-link', NavLink)
<style webc:scoped>
:host {
--colour-solid: var(--primary-colour);
--colour-transparent: var(--primary-colour-25);
--color-solid: #1e1e3cff;
--color-transparent: #1e1e3c33;
display: flex;
position: relative;
color: var(--color-transparent);

View File

@ -13,7 +13,7 @@ class NavPrimary extends HTMLElement {
this.setupAudio()
this.categories = this.querySelectorAll('nav-link')
this.subs = this.querySelectorAll('#sub ul')
this.subs = this.querySelectorAll('ul')
this.activate()
@ -28,7 +28,7 @@ class NavPrimary extends HTMLElement {
const category = n.attributes.getNamedItem('category')
const link = n.attributes.getNamedItem('link')
console.log('category click', link, category)
console.log(link)
if (link) {
history.pushState({}, '', link.value)
@ -63,6 +63,7 @@ class NavPrimary extends HTMLElement {
activate() {
let active, toOpen
this.categories.forEach(c => {
const { value } = c.attributes.getNamedItem('category') || false
@ -73,7 +74,6 @@ class NavPrimary extends HTMLElement {
}
})
console.log(this.subs)
this.subs.forEach(s => {
const { name } = s.dataset

View File

@ -7,10 +7,7 @@
</template>
</div>
<div class="controls">
<button class="audioToggle"></button>
<theme-switcher></theme-switcher>
</div>
<button class="audioToggle"></button>
</nav>
<nav id="sub" slot="subnav">
@ -34,12 +31,6 @@
<script src="nav-primary.js" type="module"></script>
<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 {
display: grid;
@ -73,12 +64,6 @@ nav-link[data-name="<~"] {
gap: 0.25em;
}
/* => CONTROLS */
.controls {
display: flex;
gap: 0.5em;
}
/* => AUDIO TOGGLE */
.audioToggle {
background: none;
@ -88,7 +73,7 @@ nav-link[data-name="<~"] {
}
.audioToggle:hover {
color: var(--primary-colour);
color: #CECECE;
cursor: pointer;
transition: color ease-in-out 0.1s;
}
@ -116,6 +101,7 @@ nav-link[data-name="<~"] {
}
}
#sub > ul {
grid-row: 1 / span 1;
grid-column: 1 / span 1;
@ -150,13 +136,14 @@ ul.active {
padding: 0;
font-size: 33vw;
opacity: 0;
color: var(--neutral-100);
transform: translateY(100px);
transform-origin: bottom left;
mix-blend-mode: difference;
transition: opacity ease-in-out 0.1s, transform ease-in-out 0.1s;
}
#menuItem h1.active {
mix-blend-mode: difference;
opacity: 1 !important;
transform: translateY(-600px) !important;
}

View File

@ -1,168 +0,0 @@
<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>

View File

@ -1,46 +0,0 @@
@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');
}

View File

@ -1,75 +1,20 @@
/* PAGE STYLES */
@import url('./fonts/fonts.css');
@import url(https://cdn.jsdelivr.net/gh/tonsky/FiraCode@1.206/distr/fira_code.css);
* {
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 <-- */
:root {
--page-margin-inline: 1em;
--neutral-900: #080c11ff;
--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;
--neutral-900: #1e1e3cff;
--neutral-900-25: #1e1e3c33;
}
body {
font-family: 'JetBrains', 'fira code', monospace;
color: var(--primary-colour);
background-color: var(--bg-colour);
}
input {
background-color: var(--bg-colour);
color: var(--primary-colour);
font-family: 'fira code', monospace;
color: #1e1e3cff;
}
p {
@ -86,16 +31,17 @@ em {
}
a, a:visited {
color: var(--primary-colour);
color: #1e1e3cff;
padding-bottom: 2px;
text-decoration: none;
border-bottom: 1px var(--primary-colour) solid;
border-bottom: 1px #1e1e3c50 solid;
transition: color ease 0.5s, border ease 0.2s;
}
img {
max-width: 100%;
height: auto;
outline: 1px dotted var(--bg-colour);
outline: 1px dotted var(--neutral-900);
}
hr {
@ -146,7 +92,7 @@ nav#toTop > span {
display: block;
opacity: 0.0;
transform: translateY(-2em);
background-color: var(--primary-colour);
background-color: rgba(255,255,255,0.0);
padding: 0.3em 0.5em 0.5em;
border-radius: 1em;
transition: transform ease 0.5s, opacity ease 1s, background-color ease 0.5s 0.5s;
@ -187,7 +133,7 @@ nav#sub > ul > li:before {
}
nav#sub > ul > li:hover {
background: var(--primary-colour-25);
background: #d2d2d8;
cursor: pointer;
}
@ -210,7 +156,7 @@ section.page h1 {
@media screen and (min-width: 1360px) {
body {
font-size: 19px;
line-height: 1.5em;
line-height: 24px;
margin: 0;
padding: 0;
}