Add CSS-only mobile handling for PDFs

- Score icon: mobile downloads PDF, desktop opens modal
- Document icon: mobile downloads PDF, desktop opens modal
- Works page: mobile hides score iframe, Score link downloads PDF
- Uses pure CSS (md:hidden/hidden md:block) - no JS needed
This commit is contained in:
Michael Winter 2026-03-06 17:12:33 +01:00
parent d5fc1eed21
commit 54ab2d8b24
2 changed files with 29 additions and 21 deletions

View file

@ -2,16 +2,29 @@
<div class="inline-flex p-1 min-w-[25px]"> <div class="inline-flex p-1 min-w-[25px]">
<div v-show="visible" class="bg-black rounded-full text-xs inline-flex" > <div v-show="visible" class="bg-black rounded-full text-xs inline-flex" >
<a v-if="type === 'score' && isMobile" :href="scoreLink" class="inline-flex p-1"> <!-- Score: Mobile = PDF (downloads), Desktop = work page with hash (opens modal) -->
<Icon name="ion:book-sharp" style="color: white" /> <span v-if="type === 'score'" class="md:hidden">
</a> <a :href="scoreLink" class="inline-flex p-1">
<button v-else-if="type === 'score'" @click="openWithHash('score')" class="inline-flex p-1"> <Icon name="ion:book-sharp" style="color: white" />
<Icon name="ion:book-sharp" style="color: white" /> </a>
</button> </span>
<span v-if="type === 'score'" class="hidden md:block">
<a :href="'/works/' + workSlug + '#score'" class="inline-flex p-1">
<Icon name="ion:book-sharp" style="color: white" />
</a>
</span>
<a v-else-if="type === 'document'" :href="isExternalLink ? link : undefined" :target="isExternalLink ? '_blank' : undefined" :rel="isExternalLink ? 'noopener noreferrer' : undefined" @click="openDocument()" class="inline-flex p-1 cursor-pointer"> <!-- Document: Mobile = PDF (downloads), Desktop = modal -->
<Icon name="ion:book-sharp" style="color: white" /> <span v-if="type === 'document'" class="md:hidden">
</a> <a :href="link" class="inline-flex p-1 cursor-pointer">
<Icon name="ion:book-sharp" style="color: white" />
</a>
</span>
<span v-if="type === 'document'" class="hidden md:block">
<a :href="isExternalLink ? link : undefined" :target="isExternalLink ? '_blank' : undefined" :rel="isExternalLink ? 'noopener noreferrer' : undefined" @click="openDocument()" class="inline-flex p-1 cursor-pointer">
<Icon name="ion:book-sharp" style="color: white" />
</a>
</span>
<a v-else-if="type === 'buy'" :href="link" :target="newTab ? '_blank' : undefined" :rel="newTab ? 'noopener noreferrer' : undefined" class="inline-flex p-1 cursor-pointer"> <a v-else-if="type === 'buy'" :href="link" :target="newTab ? '_blank' : undefined" :rel="newTab ? 'noopener noreferrer' : undefined" class="inline-flex p-1 cursor-pointer">
<Icon name="bxs:purchase-tag" style="color: white" /> <Icon name="bxs:purchase-tag" style="color: white" />
@ -58,11 +71,6 @@
const workSlug = computed(() => slugify(props.work?.title)) const workSlug = computed(() => slugify(props.work?.title))
const isMobile = computed(() => {
if (typeof window === 'undefined') return false
return window.innerWidth < 768
})
const scoreLink = computed(() => { const scoreLink = computed(() => {
if (!props.work?.score) return null if (!props.work?.score) return null
if (props.work.score.startsWith('/scores/')) { if (props.work.score.startsWith('/scores/')) {

View file

@ -8,7 +8,12 @@
<nav v-if="itemCount >= 2" class="flex gap-4 mb-6"> <nav v-if="itemCount >= 2" class="flex gap-4 mb-6">
<a v-if="work.vimeo_trackid" href="#video" class="hover:underline">Video</a> <a v-if="work.vimeo_trackid" href="#video" class="hover:underline">Video</a>
<a v-if="gallery && gallery.length" href="#images" class="hover:underline">Images</a> <a v-if="gallery && gallery.length" href="#images" class="hover:underline">Images</a>
<a v-if="scoreUrl" :href="isMobile ? scoreUrl : '#score'" class="hover:underline">Score</a> <span class="md:hidden">
<a v-if="scoreUrl" :href="scoreUrl" class="hover:underline">Score</a>
</span>
<span class="hidden md:block">
<a v-if="scoreUrl" href="#score" class="hover:underline">Score</a>
</span>
</nav> </nav>
</div> </div>
</div> </div>
@ -22,7 +27,7 @@
<ImageSlider :bucket="'images'" :gallery="gallery"></ImageSlider> <ImageSlider :bucket="'images'" :gallery="gallery"></ImageSlider>
</div> </div>
<div id="score" v-if="scoreUrl && !isMobile" class="mb-8 scroll-mt-[280px]"> <div id="score" v-if="scoreUrl" class="mb-8 scroll-mt-[280px] hidden md:block">
<iframe :src="scoreUrl + '#toolbar=1&navpanes=0&sidebar=0'" class="w-full h-[85vh] border"></iframe> <iframe :src="scoreUrl + '#toolbar=1&navpanes=0&sidebar=0'" class="w-full h-[85vh] border"></iframe>
</div> </div>
</div> </div>
@ -77,11 +82,6 @@ const itemCount = computed(() => {
return count return count
}) })
const isMobile = computed(() => {
if (typeof window === 'undefined') return false
return window.innerWidth < 768
})
onMounted(() => { onMounted(() => {
if (work.value?.soundcloud_trackid) { if (work.value?.soundcloud_trackid) {
audioPlayerStore.setSoundCloudTrackID(work.value.soundcloud_trackid) audioPlayerStore.setSoundCloudTrackID(work.value.soundcloud_trackid)