@@ -6,4 +6,6 @@ | |||
// ee.preventDefault(); | |||
// }) | |||
// }) | |||
// }) | |||
// }) | |||
// htmx.logAll(); |
@@ -116,12 +116,26 @@ p + p { | |||
display: block; | |||
} | |||
.htmx-request.loading { | |||
#modal-content main { | |||
opacity: 1; | |||
} | |||
.htmx-request #modal-content main { | |||
/* transition: opacity 0.2s ease; */ | |||
opacity: 0; | |||
} | |||
.htmx-request .loading { | |||
opacity: 1; | |||
} | |||
.active { | |||
@apply bg-[#ffff00] | |||
@apply bg-[#ffff00]; | |||
} | |||
.link:hover { | |||
@apply bg-[#ffff00]; | |||
} | |||
details[open]::details-content { | |||
@@ -129,6 +143,7 @@ details[open]::details-content { | |||
} | |||
.text a { | |||
font-family: 'ag-fett'; | |||
/* font-family: 'ag-fett'; */ | |||
text-decoration: underline; | |||
} | |||
@@ -534,21 +534,6 @@ video { | |||
.top-10 { | |||
top: 2.5rem; | |||
} | |||
.top-20 { | |||
top: 5rem; | |||
} | |||
.top-16 { | |||
top: 4rem; | |||
} | |||
.top-8 { | |||
top: 2rem; | |||
} | |||
.top-12 { | |||
top: 3rem; | |||
} | |||
.top-11 { | |||
top: 2.75rem; | |||
} | |||
.z-10 { | |||
z-index: 10; | |||
} | |||
@@ -561,18 +546,41 @@ video { | |||
.row-span-2 { | |||
grid-row: span 2 / span 2; | |||
} | |||
.row-span-3 { | |||
grid-row: span 3 / span 3; | |||
} | |||
.row-start-1 { | |||
grid-row-start: 1; | |||
} | |||
.float-right { | |||
float: right; | |||
} | |||
.m-16 { | |||
margin: 4rem; | |||
} | |||
.m-8 { | |||
margin: 2rem; | |||
} | |||
.my-8 { | |||
margin-top: 2rem; | |||
margin-bottom: 2rem; | |||
} | |||
.mx-4 { | |||
margin-left: 1rem; | |||
margin-right: 1rem; | |||
} | |||
.mb-2 { | |||
margin-bottom: 0.5rem; | |||
} | |||
.mb-3 { | |||
margin-bottom: 0.75rem; | |||
} | |||
.mb-4 { | |||
margin-bottom: 1rem; | |||
} | |||
.mb-8 { | |||
margin-bottom: 2rem; | |||
} | |||
.mr-auto { | |||
margin-right: auto; | |||
} | |||
@@ -582,8 +590,11 @@ video { | |||
.mt-3 { | |||
margin-top: 0.75rem; | |||
} | |||
.mb-8 { | |||
margin-bottom: 2rem; | |||
.ml-auto { | |||
margin-left: auto; | |||
} | |||
.mb-16 { | |||
margin-bottom: 4rem; | |||
} | |||
.block { | |||
display: block; | |||
@@ -618,11 +629,17 @@ video { | |||
.w-full { | |||
width: 100%; | |||
} | |||
.min-w-\[15rem\] { | |||
min-width: 15rem; | |||
.w-\[3rem\] { | |||
width: 3rem; | |||
} | |||
.w-\[30rem\] { | |||
width: 30rem; | |||
} | |||
.min-w-\[20rem\] { | |||
min-width: 20rem; | |||
.w-\[20rem\] { | |||
width: 20rem; | |||
} | |||
.w-\[25rem\] { | |||
width: 25rem; | |||
} | |||
.min-w-\[10rem\] { | |||
min-width: 10rem; | |||
@@ -630,8 +647,14 @@ video { | |||
.max-w-\[30rem\] { | |||
max-width: 30rem; | |||
} | |||
.max-w-\[20rem\] { | |||
max-width: 20rem; | |||
.max-w-\[55ch\] { | |||
max-width: 55ch; | |||
} | |||
.max-w-\[25rem\] { | |||
max-width: 25rem; | |||
} | |||
.shrink-0 { | |||
flex-shrink: 0; | |||
} | |||
.rotate-\[15deg\] { | |||
--tw-rotate: 15deg; | |||
@@ -640,8 +663,11 @@ video { | |||
.cursor-pointer { | |||
cursor: pointer; | |||
} | |||
.grid-cols-\[1fr\2c 3fr\] { | |||
grid-template-columns: 1fr 3fr; | |||
.grid-flow-col { | |||
grid-auto-flow: column; | |||
} | |||
.grid-cols-\[1fr\2c 4fr\] { | |||
grid-template-columns: 1fr 4fr; | |||
} | |||
.items-center { | |||
align-items: center; | |||
@@ -649,15 +675,27 @@ video { | |||
.justify-center { | |||
justify-content: center; | |||
} | |||
.justify-evenly { | |||
justify-content: space-evenly; | |||
.justify-between { | |||
justify-content: space-between; | |||
} | |||
.gap-2 { | |||
gap: 0.5rem; | |||
} | |||
.gap-4 { | |||
gap: 1rem; | |||
} | |||
.gap-8 { | |||
gap: 2rem; | |||
} | |||
.overflow-x-scroll { | |||
overflow-x: scroll; | |||
} | |||
.overflow-y-scroll { | |||
overflow-y: scroll; | |||
} | |||
.overscroll-none { | |||
overscroll-behavior: none; | |||
} | |||
.truncate { | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
@@ -666,21 +704,12 @@ video { | |||
.rounded-full { | |||
border-radius: 9999px; | |||
} | |||
.border { | |||
border-width: 1px; | |||
} | |||
.border-\[3px\] { | |||
border-width: 3px; | |||
} | |||
.border-2 { | |||
border-width: 2px; | |||
} | |||
.border-b-\[3px\] { | |||
border-bottom-width: 3px; | |||
} | |||
.border-b-2 { | |||
border-bottom-width: 2px; | |||
} | |||
.border-black { | |||
--tw-border-opacity: 1; | |||
border-color: rgb(0 0 0 / var(--tw-border-opacity)); | |||
@@ -709,6 +738,9 @@ video { | |||
.p-8 { | |||
padding: 2rem; | |||
} | |||
.p-1 { | |||
padding: 0.25rem; | |||
} | |||
.py-3 { | |||
padding-top: 0.75rem; | |||
padding-bottom: 0.75rem; | |||
@@ -719,8 +751,11 @@ video { | |||
.text-center { | |||
text-align: center; | |||
} | |||
.align-bottom { | |||
vertical-align: bottom; | |||
} | |||
.text-base { | |||
font-size: 1.2rem; | |||
font-size: 1.08rem; | |||
line-height: 1.35; | |||
} | |||
.text-sm { | |||
@@ -731,6 +766,9 @@ video { | |||
font-size: 0.75rem; | |||
line-height: 1rem; | |||
} | |||
.leading-tight { | |||
line-height: 1.25; | |||
} | |||
.text-red-600 { | |||
--tw-text-opacity: 1; | |||
color: rgb(220 38 38 / var(--tw-text-opacity)); | |||
@@ -849,7 +887,7 @@ h2,h3 { | |||
} | |||
h2 { | |||
font-size: 3rem; | |||
font-size: 2.53rem; | |||
line-height: 1; | |||
} | |||
@@ -888,7 +926,17 @@ p + p { | |||
display: block; | |||
} | |||
.htmx-request.loading { | |||
#modal-content main { | |||
opacity: 1; | |||
} | |||
.htmx-request #modal-content main { | |||
/* transition: opacity 0.2s ease; */ | |||
opacity: 0; | |||
} | |||
.htmx-request .loading { | |||
opacity: 1; | |||
} | |||
@@ -897,12 +945,18 @@ p + p { | |||
background-color: rgb(255 255 0 / var(--tw-bg-opacity)); | |||
} | |||
.link:hover { | |||
--tw-bg-opacity: 1; | |||
background-color: rgb(255 255 0 / var(--tw-bg-opacity)); | |||
} | |||
details[open]::details-content { | |||
display: contents; | |||
} | |||
.text a { | |||
font-family: 'ag-fett'; | |||
/* font-family: 'ag-fett'; */ | |||
text-decoration: underline; | |||
} | |||
@media (min-width: 1024px) { | |||
@@ -911,12 +965,12 @@ details[open]::details-content { | |||
display: flex; | |||
} | |||
.lg\:grid-cols-2 { | |||
grid-template-columns: repeat(2, minmax(0, 1fr)); | |||
} | |||
.lg\:grid-cols-3 { | |||
grid-template-columns: repeat(3, minmax(0, 1fr)); | |||
} | |||
.lg\:grid-rows-3 { | |||
grid-template-rows: repeat(3, minmax(0, 1fr)); | |||
} | |||
} | |||
@@ -8,12 +8,12 @@ module.exports = { | |||
fontSize: { | |||
// xs: ['0.95rem', { lineHeight: '1.35' }], | |||
sm: ['0.95rem', { lineHeight: '1.35' }], | |||
base: ['1.2rem', { lineHeight: '1.35' }], | |||
base: ['1.08rem', { lineHeight: '1.35' }], | |||
// lg: ['1.125rem', { lineHeight: '1.5' }], | |||
// xl: ['1.25rem', { lineHeight: '1.6' }], | |||
// '2xl': ['1.5rem', { lineHeight: '1.88rem' }], | |||
// '3xl': ['1.875rem', { lineHeight: '2.25rem' }], | |||
'4xl': ['3rem', { lineHeight: '1' }], | |||
'4xl': ['2.53rem', { lineHeight: '1' }], | |||
// '5xl': ['3rem', { lineHeight: '1.1' }], | |||
// '6xl': ['3.75rem', { lineHeight: '1.04' }], | |||
// '7xl': ['4.5rem', { lineHeight: '1.1' }], |
@@ -2,7 +2,7 @@ | |||
{% block content %} | |||
<div class="std-margin text"> | |||
<div class="cell-margin text max-w-[55ch]"> | |||
{{ text|safe }} | |||
</div> | |||
@@ -12,18 +12,27 @@ | |||
# Boostrap select: https://stackoverflow.com/questions/67942546/bootstrap-5-select-dropdown-with-the-multiple-attribute-collapsed | |||
--> | |||
{% macro popup_link(title,url) %} | |||
<a href="{{ url }}" class="nav-link"> | |||
{{ title }} | |||
</a> | |||
{% endmacro %} | |||
{% macro resource_lead(type, title, leadtext, url, year, thumbnail='', large_title=false) %} | |||
<div class="relative cell "> | |||
<a | |||
<div class="relative cell h-full"> | |||
<a | |||
class="block cursor-pointer" | |||
href="{{ url }}" | |||
hx-target="#modal-content" | |||
hx-select="main" | |||
hx-swap="innerHTML" | |||
@click="openModal()" | |||
> | |||
{% if large_title %} | |||
<h2 class="">{{ title }}</h2> | |||
{% else %} | |||
@@ -120,27 +129,45 @@ | |||
</head> | |||
<script> | |||
htmx.logAll(); | |||
// htmx.on('htmx:beforeRequest', e=> { | |||
// console.log(e) | |||
// }) | |||
// htmx.logAll() | |||
function base() { | |||
return { | |||
menuOpen: false, | |||
modalOpen: false, | |||
showRelated: false, | |||
home: '/', | |||
hideIfBase() { | |||
let str = document.location.toString(); | |||
str = str.replace('http://', ''); | |||
str = str.replace('https://', ''); | |||
let l = str.split('/').length-1; | |||
if(l<2) { | |||
this.modalOpen = false; | |||
} | |||
return l; | |||
}, | |||
init() { | |||
this.$watch('document.location', (value, oldValue) => { | |||
console.log('new url', value); | |||
}); | |||
window.addEventListener('popstate', e => { | |||
console.log(document.location); | |||
if (document.location == this.home) { | |||
this.modalOpen = false; | |||
} | |||
}) | |||
this.hideIfBase(); | |||
}); | |||
}, | |||
hideOverlay() { | |||
this.modalOpen = false; | |||
window.history.pushState({}, '', this.home); | |||
// window.history.pushState({}, '', this.home); | |||
}, | |||
openModal() { | |||
this.$refs.modal.innerHTML = ''; | |||
// this.$refs.modal.innerHTML = ''; | |||
this.modalOpen = true; | |||
let mc = document.querySelector('#modal-content'); | |||
mc.scrollTo(0,0); | |||
} | |||
} | |||
} | |||
@@ -151,8 +178,8 @@ | |||
hx-boost="true" | |||
hx-select="#all" | |||
hx-target="#all" | |||
hx-indicator="#loading" | |||
hx-swap="outerHTML" | |||
hx-indicator="body" | |||
> | |||
<div id="loading" class="loading"> | |||
<div class="pointer-events-none fixed top-0 left-0 w-full h-screen z-50 flex justify-center items-center p-4"> | |||
@@ -163,45 +190,50 @@ | |||
</div> | |||
<div id="all"> | |||
<header class="sticky top-0 z-10 bg-white std-padding border-b-[3px] border-black"> | |||
<nav class="lg:flex gap-8"> | |||
<nav class=""> | |||
<div class="lg:flex gap-2 mb-2"> | |||
<a class="link leading-tight" href="{{ url_for('main.index') }}">ExPub<br>Compendium</a> | |||
<a class="mr-auto" href="{{ url_for('main.index')}}">ExPub Compendium</a> | |||
<a href="{{ url_for('main.about') }}" class="{{ 'active' if request.path == url_for('main.about') }} ml-auto link"> | |||
About | |||
</a> | |||
<a href="{{ url_for('main.about') }}" class="nav-link"> | |||
About | |||
</a> | |||
<a href="{{ url_for('tool.get_tools') }}" class="nav-link"> | |||
Tools | |||
</a> | |||
<a href="{{ url_for('practice.get_practices') }}" class="nav-link"> | |||
Practices | |||
</a> | |||
<a href="{{ url_for('book.get_books') }}" class="nav-link"> | |||
Books | |||
</a> | |||
{% if current_user.is_authenticated %} | |||
<a href="{{ url_for('create.create_resource') }}" class="nav-link"> | |||
Add resource | |||
</a> | |||
{% endif %} | |||
{% if current_user.is_authenticated %} | |||
<a href="{{ url_for('main.profile') }}" class="nav-link"> | |||
Profile | |||
</a> | |||
{% endif %} | |||
{% if not current_user.is_authenticated %} | |||
<a href="{{ url_for('auth.login') }}" class="nav-link"> | |||
Login | |||
</a> | |||
<a href="{{ url_for('auth.signup') }}" class="nav-link"> | |||
Sign Up | |||
</a> | |||
{% endif %} | |||
{% if current_user.is_authenticated %} | |||
<a href="{{ url_for('auth.logout') }}" class="nav-link"> | |||
Logout | |||
</a> | |||
{% endif %} | |||
{% if current_user.is_authenticated %} | |||
<a href="{{ url_for('create.create_resource') }}" class="link"> | |||
Add resource | |||
</a> | |||
{% endif %} | |||
{% if current_user.is_authenticated %} | |||
<a href="{{ url_for('main.profile') }}" class="link"> | |||
Profile | |||
</a> | |||
{% endif %} | |||
{% if not current_user.is_authenticated %} | |||
<a href="{{ url_for('auth.login') }}" class="link"> | |||
Login | |||
</a> | |||
<a href="{{ url_for('auth.signup') }}" class="link"> | |||
Sign Up | |||
</a> | |||
{% endif %} | |||
{% if current_user.is_authenticated %} | |||
<a href="{{ url_for('auth.logout') }}" class="link"> | |||
Logout | |||
</a> | |||
{% endif %} | |||
</div> | |||
<h2 class="flex gap-4 "> | |||
<a href="{{ url_for('tool.get_tools') }}" class=" link align-bottom"> | |||
Tools | |||
</a> | |||
<a href="{{ url_for('practice.get_practices') }}" class="link"> | |||
Practices | |||
</a> | |||
<a href="{{ url_for('book.get_books') }}" class="link"> | |||
Books | |||
</a> | |||
<input class="ml-auto text-base border-2 border-black p-1 " type="text" placeholder="Search"> | |||
</h2> | |||
</nav> | |||
</header> | |||
@@ -219,7 +251,7 @@ | |||
</main> | |||
</div> | |||
<div id="modal" x-show="modalOpen" class="modal h-screen w-full fixed top-0 z-20 p-8 bg-black/20"> | |||
<div id="modal" x-show="modalOpen" class="modal h-screen w-full fixed top-0 z-20 p-8 bg-black/20 overscroll-none"> | |||
<div class="cross cursor-pointer absolute top-10 right-10 w-10 h-10" @click="hideOverlay()"> | |||
<svg width="100%" height="100%" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
<path d="M2 2L18 18M18 2L2 18" stroke="black" stroke-width="1"></path> |
@@ -2,7 +2,7 @@ | |||
{% block content %} | |||
<div class="cell-margin"> | |||
<!-- <div class="cell-margin"> | |||
<div class="mb-8"> | |||
<h2> | |||
{% block title %} | |||
@@ -17,81 +17,122 @@ | |||
Integer accumsan ullamcorper diam, non rhoncus tellus molestie ut. Maecenas finibus pretium dolor ac sagittis. | |||
</p> | |||
</div> | |||
</div> | |||
<div class=""> | |||
<div class="search sticky top-11 z-10 border-b-2 border-black"> | |||
<div class="sticky top-20 flex p-2 pt-4 gap-8 bg-white "> | |||
<input class="border-2 border-black p-2 mb-2" type="text" placeholder="filter by search..."> | |||
{% if practices_filter %} | |||
<details class="min-w-[10rem]"> | |||
<summary>Practices</summary> | |||
<div class=""> | |||
{% for practice in practices_filter %} | |||
<div {% if request.args.get('practice')==practice[0]|string %} class="active" {% endif %}> | |||
<a href="/{{type + 's'}}?practice={{practice[0]}}">{{ practice[1] }}</a> | |||
</div> | |||
{% endfor %} | |||
</div> --> | |||
<script> | |||
function filter() { | |||
return { | |||
filterOpen: false, | |||
init() { | |||
// console.log(this.showRelated) | |||
} | |||
} | |||
} | |||
</script> | |||
<div class="" x-data="filter()"> | |||
<div | |||
class="search fixed z-20 top-0 left-0 w-[20rem] h-screen bg-white cell-padding " | |||
x-show="filterOpen" | |||
style="box-shadow:0 0 2rem rgba(0,0,0,0.3)" | |||
@click.outside = "filterOpen = false" | |||
> | |||
<div class=" p-2 pt-4 gap-8 bg-white "> | |||
{% if practices_filter %} | |||
<details class="" open> | |||
<summary>Practices</summary> | |||
<div class=""> | |||
{% for practice in practices_filter %} | |||
<div {% if request.args.get('practice')==practice[0]|string %} class="active" {% endif %}> | |||
<a href="/{{type + 's'}}?practice={{practice[0]}}">{{ practice[1] }}</a> | |||
</div> | |||
</details> | |||
{% endif %} | |||
{% if year_filter %} | |||
<details class="min-w-[10rem]"> | |||
<summary>Year</summary> | |||
<div id="filter-year" class="collapse filter-items"> | |||
{% for year in year_filter %} | |||
<li {% if request.args.get('year')==year %} class="active" {% endif %}> | |||
<a href="/books?year={{year}}">{{ year }}</a> | |||
</li> | |||
{% endfor %} | |||
{% endfor %} | |||
</div> | |||
</details> | |||
{% endif %} | |||
{% if year_filter %} | |||
<details class=""> | |||
<summary>Year</summary> | |||
<div id="filter-year" class="collapse filter-items"> | |||
{% for year in year_filter %} | |||
<li {% if request.args.get('year')==year %} class="active" {% endif %}> | |||
<a href="/books?year={{year}}">{{ year }}</a> | |||
</li> | |||
{% endfor %} | |||
</div> | |||
</details> | |||
{% endif %} | |||
{% if typology_filter %} | |||
<details class=""> | |||
<summary class="">Typology category</summary> | |||
<div class=""> | |||
{% for typology in typology_filter %} | |||
<div {% if request.args.get('typology')==typology %} class="active" {% endif %}> | |||
<a href="/books?typology={{typology}}">{{ typology }}</a> | |||
</div> | |||
</details> | |||
{% endif %} | |||
{% if typology_filter %} | |||
<details class="min-w-[10rem]"> | |||
<summary class="">Typology category</summary> | |||
<div class=""> | |||
{% for typology in typology_filter %} | |||
<div {% if request.args.get('typology')==typology %} class="active" {% endif %}> | |||
<a href="/books?typology={{typology}}">{{ typology }}</a> | |||
</div> | |||
{% endfor %} | |||
{% endfor %} | |||
</div> | |||
</details> | |||
{% endif %} | |||
{% if languages_filter %} | |||
<details class=""> | |||
<summary>Scripting languages</summary> | |||
<div class=""> | |||
{% for language in languages_filter %} | |||
<div {% if request.args.get('scriptingLanguage')==language %} class="active" {% endif %}> | |||
<a href="/tools?scriptingLanguage={{language}}">{{ language }}</a> | |||
</div> | |||
</details> | |||
{% endif %} | |||
{% if languages_filter %} | |||
<details class="min-w-[10rem]"> | |||
<summary>Scripting languages</summary> | |||
<div class=""> | |||
{% for language in languages_filter %} | |||
<div {% if request.args.get('scriptingLanguage')==language %} class="active" {% endif %}> | |||
<a href="/tools?scriptingLanguage={{language}}">{{ language }}</a> | |||
</div> | |||
{% endfor %} | |||
{% endfor %} | |||
</div> | |||
</details> | |||
{% endif %} | |||
{% if licenses_filter %} | |||
<details class="min-w-[10rem]"> | |||
<summary>License</summary> | |||
<div class=""> | |||
{% for license in licenses_filter %} | |||
<div {% if request.args.get('license')==license %} class="active" {% endif %}> | |||
<a href="/tools?license={{license}}">{{ license }}</a> | |||
</div> | |||
</details> | |||
{% endif %} | |||
{% if licenses_filter %} | |||
<details class="min-w-[10rem]"> | |||
<summary>License</summary> | |||
<div class=""> | |||
{% for license in licenses_filter %} | |||
<div {% if request.args.get('license')==license %} class="active" {% endif %}> | |||
<a href="/tools?license={{license}}">{{ license }}</a> | |||
</div> | |||
{% endfor %} | |||
</div> | |||
</details> | |||
{% endif %} | |||
{% endfor %} | |||
</div> | |||
</details> | |||
{% endif %} | |||
</div> | |||
</div> | |||
<div class="flex justify-between mx-4 my-8"> | |||
<div class="cursor-pointer" @click="filterOpen = true">← Show filters</div> | |||
<div class=""> | |||
<input type="checkbox" name="filter-open" x-model="showRelated" id=""> Also show everything related | |||
</div> | |||
</div> | |||
<div class="col-md-8 col-lg-9"> | |||
<div class="grid lg:grid-cols-3"> | |||
{% for resource in resources %} | |||
<div class="grid lg:grid-cols-3" x-show="!showRelated"> | |||
{% for resource in resources %} | |||
{{ resource_small(resource) }} | |||
{% endfor %} | |||
</div> | |||
{% endfor %} | |||
</div> | |||
<div x-show="showRelated"> | |||
{% for resource in resources %} | |||
<div class="w-full overflow-x-scroll"> | |||
<div class="grid lg:grid-rows-3 grid-flow-col mb-16"> | |||
<div class="w-[25rem] shrink-0 row-span-3 h-full"> | |||
{{ resource_small(resource) }} | |||
</div> | |||
<div class="w-[25rem] cell row-start-1"> | |||
Something Related | |||
</div> | |||
<div class="w-[25rem] cell shrink-0 row-start-1"> | |||
Something Related | |||
</div> | |||
<div class="w-[25rem] cell shrink-0 row-start-1"> | |||
Something Related | |||
</div> | |||
<div class="w-[25rem] cell shrink-0 row-start-1"> | |||
Something Related | |||
</div> | |||
</div> | |||
</div> | |||
{% endfor %} | |||
</div> | |||
</div> | |||
@@ -1,5 +1,5 @@ | |||
## ExPub Compendium | |||
## ExPub <br>Compendium | |||
The Experimental Publishing Compendium is for authors, designers, publishers, institutions and technologist who challenge, push and redefine the shape, form and rationale of scholarly works. The compendium offers a catalogues of tools, practices, and books to inspire experimental scholarly works. | |||
[Read more](/about) | |||
[About ExPub](/about) |