Commit graph

1092 commits

Author SHA1 Message Date
shakespeare.diy
c9bb5abfff sasquatch: left-anchor panel on mobile, leave right side free for Quick Snap + filter pills
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 20:08:03 +07:00
shakespeare.diy
be4e0bc986 map: remove duplicate sasquatch, reposition original bubble to bottom-right below Quick Snap
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 20:05:46 +07:00
shakespeare.diy
cc2e3d3165 map: replace Vibed with Shakespeare with Sasquatch trigger button below Quick Snap
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 20:03:19 +07:00
shakespeare.diy
889eb922eb map: move attribution to top-right below Near Me, add Vibed with Shakespeare below Quick Snap
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 20:01:28 +07:00
shakespeare.diy
f8b14f1056 map: switch tile layer to CartoDB Voyager
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 19:59:11 +07:00
shakespeare.diy
682e4d802b map: dark tiles, near me button, bottom sheet, floating filter pills
- Swap OSM tiles for CartoDB Dark Matter (near-black bg, neon markers pop)
- Add floating Near Me button (top-right, crosshair icon, flies to user location)
- Add SpotBottomSheet: tap a marker → drawer slides up from bottom with
  spot thumbnail, title, location, type badges, author, View Details + Directions CTAs
  (map stays fully visible behind the sheet)
- Add flyTo prop to SpotMap for programmatic map navigation
- Add floating layer filter pills (spots/shops/gear/tours) on map surface
  bottom-left, always visible, no toolbar required

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 19:57:06 +07:00
shakespeare.diy
1ce2837fef settings: replace 7-tab horizontal scroll with iOS-style vertical menu + sub-screens
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 19:32:38 +07:00
shakespeare.diy
f0eadf307b wallet: remove duplicate balance hero, single CashuWalletCard as source of truth
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 19:29:52 +07:00
shakespeare.diy
1876d14b0f wallet: mobile-first redesign - balance hero, compact status pills, collapsible educational content
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 19:27:14 +07:00
shakespeare.diy
df8bd39ce1 fix: push Leaflet attribution above mobile nav bar on /map
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 19:23:57 +07:00
shakespeare.diy
f7d8611031 fix: externalize all Capacitor native plugins from rollup build
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 17:24:48 +07:00
shakespeare.diy
32b3a366b3 fix: move nostr-signer-capacitor-plugin to rollupOptions.external (top level)
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 17:23:34 +07:00
shakespeare.diy
3b29089df2 fix: exclude nostr-signer-capacitor-plugin from Capacitor APK build
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 17:21:37 +07:00
shakespeare.diy
29b31d4b43 chore: update release-notes.txt for v1.0.35
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 17:18:35 +07:00
shakespeare.diy
a08871318d chore: bump version to 1.0.35
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 17:07:11 +07:00
shakespeare.diy
456f42a262 events: apply same UX pattern as /lab — sticky toolbar, filter drawer, location filter, active chips
- Replace scattered filter controls (search + Select dropdowns + ScrollArea chips + TrustFilter dropdown + SortDropdown) with the same unified toolbar + filter drawer pattern used on /lab
- Sticky toolbar: Events/Tours tab toggle with live counts, Upcoming/Past sub-tabs (events only) with counts, inline search + city location inputs, filter button with active count badge
- Responsive filter drawer: bottom sheet on mobile, right side panel on desktop (md:)
- Filter drawer: Sort pills, Trust Level inline pills (no nested dropdowns), Event Type chips (events) or Tour Category + Skill Level chips (tours) — all in one place
- Active filter chips row: selected event types as dismissible pills, sort/trust badges, "Clear all" — only visible when filters are active
- CreateFAB: replaces plain Link button with a dropdown for both "Create Event" and "Create Tour" from any view
- Unified EmptyState component with context-aware "Clear Filters" vs. "Create" CTA
- Dedicated location filter input split from general search (City field)
- Results count shown below toolbar, no empty-height gaps while loading
- Removed: Input, ScrollArea, ScrollBar, Select, Tabs, TabsList, TabsContent, TabsTrigger, TrustFilter, SortDropdown imports (all replaced inline)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 17:02:46 +07:00
shakespeare.diy
41ede8a122 lab: UX improvements — location filter, responsive drawer, inline trust pills, active filter chips
- Add dedicated City location input field in toolbar alongside search (splits "Name/bio" and "City" search into two focused inputs)
- Fix Filter drawer responsiveness: bottom sheet on mobile, right side panel on desktop (md:) 
- Replace TrustFilter compact dropdown in drawer with inline pill buttons (no nested dropdowns)
- Add active filter chips row in toolbar showing selected skills as dismissible pills, sort/trust badges, and "Clear all" button — only visible when filters are active
- Tab count badges now always show (including zero) to give clear feedback
- Fix results count row: remove empty min-h gap, now only renders when not loading
- Search now also matches against genUserName fallback for pubkey-derived names

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 16:57:49 +07:00
shakespeare.diy
0dc0d272e1 fix: filter panel overlap, Wallet & Stash rename, Sasquatch on all pages
Filter panel (MapPage):
- Sheet now h-[82vh] max-h-[680px] with flex-col layout
- Scrollable content area uses flex-1 min-h-0 (proper flex children)
- "Show Results" button is now flex-shrink-0 at bottom of column
- No more overlap between Show Results and Stash/Tour quick action buttons

Wallet & Stash rename:
- Settings tab renamed from "Wallet" to "Wallet & Stash"
- "Me" dropdown in mobile header shows "Wallet & Stash" for the wallet link

Sasquatch persistent button (all pages):
- Minimized bubble is now ALWAYS visible on every page (not just pages with a guide message)
- Tapping the bubble on any page opens Sasquatch with a generic helpful greeting
- Pages with specific context (/, /map, /lab, /onboarding) still show their custom message
- Pages without context (/wallet, /settings, /stash, /events, etc.) now show a generic "Ask me anything" greeting with common questions
- Removed the separate X close button (minimize was already the same) — bubble stays visible as entry point at all times
- onPointerUp now also sets isVisible=true so panel opens on pages without a message

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 16:45:11 +07:00
shakespeare.diy
340f6fd89f fix(mobile): redesign wallet page UI for mobile + global mobile polish
Wallet page (/wallet):
- Add BalanceHero banner at top showing Cashu balance + wallet status pills
- Cashu/Lightning tabs with colored active states (orange/yellow)
- Remove nested balance display in CashuWalletCard (now shown in hero)
- Compact balance row in CashuWalletCard
- Stacked full-width inputs on mobile (no side-by-side on small screens)
- h-11 touch targets on all inputs and buttons (44px min)
- inputMode="numeric" on number fields (prevents iOS zoom)
- Receive/Send tabs with green/red active colors for clear context
- History items now 52px min height with colored amount text
- WalletComparisonGuide stays collapsed by default
- Fix: add Nut icon import to CashuWalletCard (was crashing)
- All modals use w-[calc(100%-1rem)] for proper mobile sizing

Settings page (/settings):
- 7-tab bar now scrollable horizontally on mobile (no overflow/wrapping)
- -mx-3 bleed trick so scrollable area goes edge-to-edge
- Wallet tab buttons full-width on mobile
- Container max-w-3xl for better desktop centering

FAQ page (/faq):
- Compact hero on mobile (smaller icon, tighter padding)
- py-6 on mobile instead of py-12

CSS utilities:
- Add xs: breakpoint (375px) variants: flex, flex-row, px-4, -mx-4, gap-2, text-xs/sm, hidden

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 16:35:49 +07:00
shakespeare.diy
9da1796774 fix: cap map zoom out, prevent grey bands and tile duplication
- minZoom: 2 — stops user zooming past a single world view
- maxBounds: full lat range with infinite lng — locks vertical pan to the world
- maxBoundsViscosity: 1.0 — hard clamp, no elastic bounce into grey space
- TileLayer minZoom: 2 to match

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 16:21:58 +07:00
shakespeare.diy
e8151bee17 revert: remove 3D globe, restore flat map as default
- Removed SkateGlobe component from view toggle
- ViewMode back to 'map' | 'list', defaulting to 'map'
- Removed Globe import, selectedGlobeMarker state, and all globe render blocks
- Flat Leaflet map loads as default again

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-23 16:18:24 +07:00
shakespeare.diy
6331a937f2 feat: map as homepage, 3D globe, camera fix, Sasquatch upgrades, UI/UX polish
## 1. Map as Homepage
- `/` now renders MapPage (the globe/map) — removed old Index homepage
- `/home` redirects to Index (legacy), `/map` alias still works
- Navbar: removed HOME link, SPOTS (MapPin) is now first nav item
- isActive() treats both `/` and `/map` as active for SPOTS tab

## 2. 3D Globe View
- New SkateGlobe component using pure Three.js (no h3-js/CDN issues)
- Earth night texture with atmospheric neon red glow
- Spot pins (red) + shop pins (lime) on globe surface
- Click pin → zoom camera in + show info card
- Drag to rotate, scroll/pinch to zoom, auto-rotation when idle
- Globe toggle button added to map/list view switcher
- Selected marker ring + info card with View Spot/Shop links
- Lazy-loaded with Suspense skeleton

## 3. Settings → Stash Link
- Added My Stash card in Settings > Wallet tab
- Links to /stash with Package icon and description
- Smooth hover animation with ChevronRight

## 4. Camera Fix (Capacitor Native)
- CameraCapture now detects native Capacitor platform at runtime
- On native Android/iOS: uses @capacitor/camera (OS-level camera, no WebView permission popup)
- On browser: falls back to getUserMedia stream (existing behaviour)
- Added Upload from Gallery fallback when camera permission denied
- Better error handling for user cancellation

## 5. Sasquatch Upgrades
- FAQ page: replaced static accordion wall with Sasquatch-powered UI
  - Quick question chips that pre-load questions into Sasquatch
  - "Open The Sasquatch" CTA button
  - Quick facts grid, clean modern design
- About page: added Sasquatch CTA card at bottom
- SasquatchGuide: listens for sasquatch:open and sasquatch:ask custom events
  - External pages can now trigger and pre-fill the Sasquatch
  - Sasquatch now shows even without a page-level message prop (for external triggers)

## 6. UI/UX Audit & Polish
- Focus rings: on-brand red (WCAG accessible)
- Card hover micro-interactions: subtle translateY + shadow
- Button/link transition consistency (150ms ease)
- Reduced motion support (@media prefers-reduced-motion)
- Modal backdrop blur improvement
- Skeleton shimmer animation utility
- Globe CSS utilities (touch-action: none for canvas)
- Typography helpers (text-balance, text-pretty)
- Improved map-full-height responsive calculation

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-22 22:47:39 +07:00
shakespeare.diy
cf1a18e941 Fix NUser constructor call: use positional args not object
NUser takes (method, pubkey, signer) as separate args.
Was passing {pubkey, signer} as first arg so pubkey was always undefined.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 15:53:21 +07:00
shakespeare.diy
52bf618b51 Fix amber login type: use x-amber instead of amber
NLoginOther requires type x-${string} to be a valid NLoginType.
Using bare 'amber' meant pubkey was never properly stored/rehydrated
from localStorage — it was always undefined/empty.

Using NLogin('x-amber', pubkey, ...) correctly stores pubkey through
the NLoginBase interface and survives localStorage serialization.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 14:57:20 +07:00
shakespeare.diy
dd650ee57c Show stored pubkey in Settings when profile not loaded (debug)
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 14:42:47 +07:00
shakespeare.diy
de5de7abec Fix getPublicKey: JSON parse JSObject result + restore AMBER_PACKAGE arg
- JSObject from Capacitor needs JSON.parse(JSON.stringify()) to be
  accessible as plain JS object with property access
- Restore AMBER_PACKAGE as argument (null was causing broken URI)
- Remove debug toast from LoginDialog

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 14:28:58 +07:00
shakespeare.diy
0b1bf05e74 Fix useLoggedInAccounts: safely extract pubkey from amber login type
NLoginType doesn't expose pubkey field directly — amber login is cast
as unknown as NLoginType so l.pubkey was undefined. Use getPubkey()
helper that casts to extract pubkey safely for all login types.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 14:06:01 +07:00
shakespeare.diy
fc1c8aca26 Add visible debug toast showing pubkey returned by Amber after login
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 13:50:28 +07:00
shakespeare.diy
1c577f7392 Add debug logging to getAmberPublicKeyViaPlugin to trace exact return value
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 13:43:26 +07:00
shakespeare.diy
a6c220c911 Increase useAuthor timeout and retries for Capacitor WebView
WebSocket connections take longer to establish on first load in
Capacitor. Increase timeout from 8s to 15s and retries from 3 to 5.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 13:34:18 +07:00
shakespeare.diy
0d9cfa61fb Fix getPublicKey: pass null packageName to force Amber UI path
The Content Resolver silent path returns a cached/wrong key.
Passing null skips it and always opens Amber UI so the user
explicitly selects their key and the correct pubkey is returned.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 13:28:26 +07:00
shakespeare.diy
da1d208579 Fix getPublicKey: Java returns hex not npub despite field name
NostrSigner.npubToHex() is called before putting result in "npub" field,
so the value is already a 64-char hex pubkey. Skip nip19.decode() and
use it directly. This was causing the "data must be at least 8 chars" error.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 12:50:37 +07:00
shakespeare.diy
9eda3d5c86 Fix capacitorAmberSigner: rewrite with correct positional API
The actual plugin source uses positional args, not object params:
- getPublicKey(packageName)
- signEvent(packageName, eventJson, id, npub)
- nip04Encrypt/Decrypt(packageName, text, id, pubKey, npub)
- nip44Encrypt/Decrypt(packageName, text, id, pubKey, npub)
- isExternalSignerInstalled(packageName)

Previous implementation was based on wrong README docs.
Now based on actual dist/esm/index.js source.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 12:34:10 +07:00
shakespeare.diy
0f758d7b1f Fix capacitorAmberSigner: correct named export and setPackageName API
- Use named export { NostrSignerPlugin } not mod.default
- setPackageName takes a plain string not { packageName: string }
- isExternalSignerInstalled takes packageName as argument
- These were the exact bugs causing "plugin not available" error

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 12:25:25 +07:00
shakespeare.diy
387af2aa4f Update release notes for v1.0.38
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 12:15:52 +07:00
shakespeare.diy
543b7d32c0 Remove external: nostr-signer-capacitor-plugin from vite config
Plugin is now properly installed and registered via cap sync.
It must be bundled by Rollup, not treated as external.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 12:14:09 +07:00
shakespeare.diy
646c4f7761 Update release notes for v1.0.37
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 11:59:01 +07:00
shakespeare.diy
ef22eb2de7 Fix Amber "not installed" false positive - skip isExternalSignerInstalled() check
Android 11+ package visibility rules cause isExternalSignerInstalled() to
return false even when Amber is installed, unless <queries> is declared in
AndroidManifest.xml. Skip the pre-check and attempt login directly instead,
with better error messages for cancel vs not-found vs other errors.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 11:49:16 +07:00
shakespeare.diy
6230948383 Fix build: externalize capacitor plugin + remove duplicate lab i18n keys
- vite.config.ts: mark nostr-signer-capacitor-plugin as external so
  Rollup doesn't try to bundle it (it's resolved at runtime by Capacitor)
- en.ts / es.ts: remove duplicate lab key that was causing esbuild warnings

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 11:40:53 +07:00
shakespeare.diy
8256f05ca8 Wire up nostr-signer-capacitor-plugin for Amber login and signing
- Add CapacitorAmberSigner: a full NostrSigner implementation backed by
  the native nostr-signer-capacitor-plugin (login, signEvent, nip04,
  nip44 all go through Amber via native Android intents)
- LoginDialog: on Capacitor, call getAmberPublicKeyViaPlugin() directly
  instead of the intent:// URL redirect — returns a Promise, no
  callback URL or polling needed. Shows clear error if Amber not installed.
- useCurrentUser: on Capacitor amber logins use CapacitorAmberSigner
  so every publish/sign goes through the plugin, not window.location.href
- Web/PWA path unchanged — still uses URL redirect + AmberSigner

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-09 11:38:23 +07:00
shakespeare.diy
e3a95de807 Add release-notes.txt for v1.0.35
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-08 22:43:41 +07:00
shakespeare.diy
7d071787d0 Fix Amber login for ZapStore/Capacitor app
- LoginDialog now uses openAmberForLogin() which sends the proper
  intent:// URL with a callbackUrl instead of the old nostrsigner:
  scheme that only copies to clipboard (broken on most setups)
- Add polling loop (500ms, 3min timeout) for amber_pending_pubkey
  written by AmberCallbackPage — works even when Amber opens the
  callback in a new browser tab (GrapheneOS/Android behaviour)
- visibilitychange listener now waits for app to regain focus before
  attempting clipboard read, fixing race condition
- DeepLinkHandler pre-captures ?event= param into sessionStorage
  when Amber fires appUrlOpen deep link in Capacitor, so
  AmberCallbackPage can always find the result
- Add 'paste' to amberStep union type (was missing, caused TS error)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-08 22:29:26 +07:00
shakespeare.diy
f73cb0ec8c Add SNT4EVER as partner on Supporters page
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-08 16:44:51 +07:00
shakespeare.diy
6ed5ac23cb Invert SNT4EVER logo for contrast on dark background
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-08 16:37:38 +07:00
shakespeare.diy
2904df4eab Update SNT4EVER logo to new version
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-08 16:35:51 +07:00
shakespeare.diy
81dd69679c Add SNT4EVER as friend on Supporters page
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-08 16:12:28 +07:00
shakespeare.diy
132b6cae7c fix: Amber login using confirmed correct URL from Amber source code
Read Amber's actual IntentUtils.kt to confirm exact URL parsing:
- Strips "nostrsigner:" prefix
- URLDecodes the remainder
- Parses ?key=value&key=value query params
- "type" param controls operation
- No callbackUrl → copies result to clipboard

Correct URL: nostrsigner:?type=get_public_key&compressionType=none&returnType=signature

Flow:
1. Tap "Open Amber" → window.location.href = nostrsigner: URL
2. Amber opens, user approves, copies hex pubkey to clipboard
3. App regains focus → tries navigator.clipboard.readText() auto
4. If clipboard denied → shows paste input (accepts hex or npub1)
5. Login complete

Removed broken Capacitor plugin dependency (couldn't install git dep).

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-08 12:22:58 +07:00
shakespeare.diy
9e6d6f1c39 fix: switch to Coracle's nostr-signer-capacitor-plugin fork + correct API
The chebizarro npm version has a different API to the Coracle fork that
Welshman/Coracle actually use in production. Now using:

  github:coracle-social/nostr-signer-capacitor-plugin#main

Correct API (from Welshman nip55.js source):
  NostrSignerPlugin.setPackageName(packageName: string)  // string not object
  NostrSignerPlugin.getPublicKey(packageName?: string)   // packageName as arg
  NostrSignerPlugin.isExternalSignerInstalled(packageName?)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-08 12:11:18 +07:00
shakespeare.diy
f010a61608 fix: use nostr-signer-capacitor-plugin for Amber NIP-55 login
All previous URL-scheme approaches (nostrsigner:, intent:) were fundamentally
wrong for a Capacitor app. JavaScript in a WebView cannot reliably dispatch
Android intents via URL navigation.

The correct solution — used by Coracle and other Capacitor-based Nostr apps —
is the nostr-signer-capacitor-plugin which communicates with Amber via native
Android intents through the Capacitor bridge:

  NostrSignerPlugin.setPackageName({ packageName: 'com.greenart7c3.nostrsigner' })
  NostrSignerPlugin.isExternalSignerInstalled()
  NostrSignerPlugin.getPublicKey() → { npub }

This is synchronous from the JS side, handles the entire Android intent
roundtrip natively, and returns the pubkey directly. No URL encoding,
no callback URLs, no redirects, no malformed request errors.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-08 11:59:04 +07:00
shakespeare.diy
92f317f5e5 fix: Amber login for GrapheneOS — clipboard + paste flow
GrapheneOS Vanadium browser blocks intent: URLs from web pages as a
security hardening measure. This is why every URL format we tried
caused "malformed request" — Vanadium was blocking the intent before
Amber ever saw it.

New flow that works on ALL Android browsers including GrapheneOS:
1. Tap "Open Amber" → navigates to nostrsigner: URL with no callbackUrl
   (Amber copies pubkey to clipboard when no callbackUrl is given)
2. User approves in Amber, comes back to app
3. App tries navigator.clipboard.readText() automatically on visibilitychange
4. If clipboard permission denied → shows paste input for hex pubkey
5. User pastes pubkey → logged in

No intent: scheme, no callback URL, no redirect loop. Simple and bulletproof.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-08 11:43:59 +07:00