forked from 20266142/Overheard
138 lines
4.7 KiB
Svelte
138 lines
4.7 KiB
Svelte
<script>
|
|
import { onMount } from 'svelte';
|
|
import { globalCount, refreshGlobalCount } from '$lib/stores/globalCountStore.js';
|
|
|
|
// --- mobile tap/fade easter egg ----------------------------------------
|
|
// On desktop, the secondary "places remember..." line is always visible
|
|
// (see .secondary-desktop in the stylesheet below, shown via the
|
|
// min-width media query). On mobile it's hidden by default and only
|
|
// fades in when the pill is tapped, holds for a few seconds, then fades
|
|
// back out on its own - an easter egg rather than a persistent UI
|
|
// element. `secondaryVisible` is local Svelte 5 rune state driving the
|
|
// opacity/max-height transition on .secondary-mobile; .secondary-desktop
|
|
// is unaffected by it.
|
|
let secondaryVisible = $state(false);
|
|
let fadeOutTimer;
|
|
|
|
onMount(() => {
|
|
refreshGlobalCount();
|
|
});
|
|
|
|
function handleTap() {
|
|
secondaryVisible = true;
|
|
|
|
// restart the hold timer on every tap, so a second tap while the
|
|
// text is already visible just extends how long it stays up rather
|
|
// than racing with the previous fade-out
|
|
clearTimeout(fadeOutTimer);
|
|
fadeOutTimer = setTimeout(() => {
|
|
secondaryVisible = false;
|
|
}, 3000);
|
|
}
|
|
</script>
|
|
|
|
<!-- only render once the first fetch resolves, so the pill never briefly
|
|
shows a misleading "0 messages have been left worldwide" before the
|
|
real count arrives -->
|
|
{#if $globalCount !== null}
|
|
<button type="button" class="count-pill" onclick={handleTap}>
|
|
<span class="count-main">{$globalCount.toLocaleString()} messages have been left worldwide</span>
|
|
|
|
<!-- desktop: always-visible secondary line (hidden on mobile via the
|
|
same media query that reveals it - see <style> below) -->
|
|
<span class="count-secondary secondary-desktop">
|
|
while not all of them are visible to you or have been echoed long enough to reach you, places remember and memories live on in intangible ways.
|
|
</span>
|
|
|
|
<!-- mobile: same text, but only fades in on tap (handleTap above)
|
|
and is hidden entirely on desktop -->
|
|
<span class="count-secondary secondary-mobile" class:visible={secondaryVisible}>
|
|
while not all of them are visible to you or have been echoed long enough to reach you, places remember and memories live on in intangible ways.
|
|
</span>
|
|
</button>
|
|
{/if}
|
|
|
|
<style>
|
|
/* small rounded pill, top-right of the app on every page - cream
|
|
background + subtle shadow + muted text, matching the "first here"
|
|
speech bubble and opening ritual overlay's palette */
|
|
.count-pill {
|
|
position: fixed;
|
|
top: 1rem;
|
|
right: 1rem;
|
|
z-index: 150;
|
|
max-width: 60vw;
|
|
background: #f9f7f4;
|
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
border-radius: 16px;
|
|
padding: 0.5rem 0.9rem;
|
|
text-align: left;
|
|
font-family: Georgia, 'Times New Roman', Times, serif;
|
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.count-main {
|
|
display: block;
|
|
font-size: 0.7rem;
|
|
color: #888;
|
|
line-height: 1.4;
|
|
letter-spacing: 0.02em;
|
|
}
|
|
|
|
.count-secondary {
|
|
display: block;
|
|
font-size: 0.65rem;
|
|
color: #aaa;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
/* desktop-only secondary line: hidden on mobile by default */
|
|
.secondary-desktop {
|
|
display: none;
|
|
}
|
|
|
|
/* mobile-only secondary line: hidden + collapsed until tapped, then
|
|
fades in/out via .visible (toggled by handleTap above). max-height
|
|
(rather than display) is what allows the opacity transition to
|
|
actually animate instead of snapping. */
|
|
.secondary-mobile {
|
|
opacity: 0;
|
|
max-height: 0;
|
|
overflow: hidden;
|
|
margin-top: 0;
|
|
transition: opacity 0.6s ease, max-height 0.6s ease;
|
|
}
|
|
|
|
.secondary-mobile.visible {
|
|
opacity: 1;
|
|
max-height: 6rem;
|
|
margin-top: 0.35rem;
|
|
}
|
|
|
|
@media (min-width: 768px) {
|
|
.count-pill {
|
|
max-width: 320px;
|
|
padding: 0.65rem 1rem;
|
|
/* tap-to-reveal is mobile-only; desktop already shows everything,
|
|
so the pointer cursor would be misleading here */
|
|
cursor: default;
|
|
}
|
|
|
|
.count-main {
|
|
font-size: 0.8rem;
|
|
}
|
|
|
|
.secondary-desktop {
|
|
display: block;
|
|
margin-top: 0.35rem;
|
|
}
|
|
|
|
/* desktop already shows .secondary-desktop, so the mobile
|
|
tap-to-reveal copy is never shown here regardless of state */
|
|
.secondary-mobile {
|
|
display: none;
|
|
}
|
|
}
|
|
</style>
|