Compare commits

..

No commits in common. "6e4e2f3d0c1af30d460a4d276a24e88133b7dfa4" and "9eb75a201754dfe462b891507e144f839f9d63d9" have entirely different histories.

4 changed files with 10 additions and 38 deletions

View file

@ -96,10 +96,6 @@
/* Default palette: Catppuccin (Latte for light, Mocha for dark). /* Default palette: Catppuccin (Latte for light, Mocha for dark).
Other palettes are scoped via :root[data-theme="<name>"] in themes/*.css. */ Other palettes are scoped via :root[data-theme="<name>"] in themes/*.css. */
:root { :root {
/* Rendered height of the fixed BottomNav (h-14 + safe-area + border), kept
current by BottomNav.vue. Pin anything that must sit flush above the nav
with `bottom: var(--bottom-nav-height)`; 0 when no nav is mounted. */
--bottom-nav-height: 0px;
--background: oklch(0.9578 0.0058 264.5321); --background: oklch(0.9578 0.0058 264.5321);
--foreground: oklch(0.4355 0.0430 279.3250); --foreground: oklch(0.4355 0.0430 279.3250);
--card: oklch(1.0000 0 0); --card: oklch(1.0000 0 0);

View file

@ -1,8 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import type { Component } from 'vue' import type { Component } from 'vue'
import { useResizeObserver } from '@vueuse/core'
export interface BottomTab { export interface BottomTab {
/** Translated label shown under the icon. */ /** Translated label shown under the icon. */
@ -35,22 +33,6 @@ interface Props {
const props = defineProps<Props>() const props = defineProps<Props>()
// Publish the nav's rendered height (h-14 + safe-area padding + border,
// whatever the device makes of it) as `--bottom-nav-height` on <html>, so
// anything that needs to sit flush above the nav — sticky action bars,
// toasts — can use `bottom: var(--bottom-nav-height)` instead of
// re-deriving the CSS and drifting when insets or font scaling differ.
const navRef = ref<HTMLElement | null>(null)
function publishHeight() {
const h = navRef.value?.getBoundingClientRect().height ?? 0
document.documentElement.style.setProperty('--bottom-nav-height', `${Math.round(h)}px`)
}
useResizeObserver(navRef, publishHeight)
onMounted(publishHeight)
onBeforeUnmount(() => {
document.documentElement.style.setProperty('--bottom-nav-height', '0px')
})
const router = useRouter() const router = useRouter()
function onTabClick(tab: BottomTab) { function onTabClick(tab: BottomTab) {
@ -69,7 +51,6 @@ function isTabActive(tab: BottomTab): boolean {
<template> <template>
<nav <nav
ref="navRef"
class="fixed bottom-0 left-0 right-0 z-50 border-t bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60" class="fixed bottom-0 left-0 right-0 z-50 border-t bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60"
style="padding-bottom: env(safe-area-inset-bottom)" style="padding-bottom: env(safe-area-inset-bottom)"
> >

View file

@ -451,13 +451,8 @@ function goToMyTickets() {
@update:is-open="showReturnDialog = $event" @update:is-open="showReturnDialog = $event"
/> />
<!-- Sticky buy bar — see showStickyCta. Pinned flush above the <!-- Sticky buy bar — see showStickyCta. Sits above the bottom nav
bottom nav via the height it publishes (--bottom-nav-height, (h-14 + safe-area inset) and mirrors the inline CTA. -->
BottomNav.vue) and mirrors the inline CTA. -->
<!-- Teleported to <body>: inside the page the bar would inherit the
parent's space-y margin (margins offset fixed boxes too) and
float 24px above the nav. -->
<Teleport to="body">
<Transition <Transition
enter-active-class="transition duration-200 ease-out" enter-active-class="transition duration-200 ease-out"
enter-from-class="translate-y-4 opacity-0" enter-from-class="translate-y-4 opacity-0"
@ -465,9 +460,9 @@ function goToMyTickets() {
leave-to-class="translate-y-4 opacity-0" leave-to-class="translate-y-4 opacity-0"
> >
<div <div
v-if="showStickyCta && event" v-if="showStickyCta"
class="fixed inset-x-0 z-40 border-t border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80" class="fixed left-0 right-0 z-40 border-t border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80"
style="bottom: var(--bottom-nav-height)" style="bottom: calc(3.5rem + env(safe-area-inset-bottom))"
role="region" role="region"
:aria-label="t('events.detail.tickets')" :aria-label="t('events.detail.tickets')"
> >
@ -502,7 +497,6 @@ function goToMyTickets() {
</div> </div>
</div> </div>
</Transition> </Transition>
</Teleport>
<!-- External references --> <!-- External references -->
<div v-if="event.tags.length > 0" class="space-y-2"> <div v-if="event.tags.length > 0" class="space-y-2">

View file

@ -198,12 +198,13 @@ function back() {
</section> </section>
<!-- Sticky bottom bar with qty stepper + add-to-cart. <!-- Sticky bottom bar with qty stepper + add-to-cart.
Sits flush above BottomNav on every breakpoint via the height Sits flush above BottomNav (h-14 + safe-area inset) on every
the nav publishes (--bottom-nav-height, BottomNav.vue) — no breakpoint. Previously `bottom-16` left an 8px gap on mobile
hand-derived h-14 + safe-area arithmetic to drift. --> (BottomNav is h-14 = 56px, not 64px), and `sm:bottom-0` made
it overlap the nav on desktop. -->
<div <div
class="fixed inset-x-0 z-20 border-t border-border bg-background/95 px-4 py-3 backdrop-blur" class="fixed inset-x-0 z-20 border-t border-border bg-background/95 px-4 py-3 backdrop-blur"
style="bottom: var(--bottom-nav-height)" style="bottom: calc(3.5rem + env(safe-area-inset-bottom))"
> >
<div class="container mx-auto flex max-w-2xl items-center gap-3"> <div class="container mx-auto flex max-w-2xl items-center gap-3">
<div class="inline-flex items-center rounded-full border border-border bg-card"> <div class="inline-flex items-center rounded-full border border-border bg-card">