work in progress
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 3.9 MiB |
|
Before Width: | Height: | Size: 4.8 MiB |
BIN
website/src/lib/assets/img/home/map-overlay.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
website/src/lib/assets/img/home/map.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 6.9 MiB |
@@ -8,113 +8,111 @@
|
||||
import { getURLForLanguage } from '$lib/utils';
|
||||
</script>
|
||||
|
||||
<footer class="w-full">
|
||||
<div class="px-6 border-t">
|
||||
<div class="mx-12 py-10 flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
|
||||
<div class="grow flex flex-col items-start">
|
||||
<Logo class="h-8" width="153" />
|
||||
<footer class="w-full px-12 py-10 border-t flex flex-col items-center">
|
||||
<div class="w-full max-w-5xl flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
|
||||
<div class="grow flex flex-col items-start">
|
||||
<Logo class="h-8" width="153" />
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://github.com/gpxstudio/gpx.studio/blob/main/LICENSE"
|
||||
target="_blank"
|
||||
>
|
||||
MIT © 2026 gpx.studio
|
||||
</Button>
|
||||
<div class="mt-3 flex flex-row gap-1.5">
|
||||
<LanguageSelect />
|
||||
<ModeSwitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grow max-w-2xl flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
|
||||
<div class="flex flex-col items-start gap-1">
|
||||
<span class="font-semibold">{i18n._('homepage.website')}</span>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://github.com/gpxstudio/gpx.studio/blob/main/LICENSE"
|
||||
href={getURLForLanguage(i18n.lang, '/')}
|
||||
>
|
||||
<House size="16" />
|
||||
{i18n._('homepage.home')}
|
||||
</Button>
|
||||
<Button
|
||||
data-sveltekit-reload
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href={getURLForLanguage(i18n.lang, '/app')}
|
||||
>
|
||||
<Map size="16" />
|
||||
{i18n._('homepage.app')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href={getURLForLanguage(i18n.lang, '/help')}
|
||||
>
|
||||
<BookOpenText size="16" />
|
||||
{i18n._('menu.help')}
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex flex-col items-start gap-1" id="contact">
|
||||
<span class="font-semibold">{i18n._('homepage.contact')}</span>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://www.reddit.com/r/gpxstudio/"
|
||||
target="_blank"
|
||||
>
|
||||
MIT © 2026 gpx.studio
|
||||
<Logo company="reddit" class="h-4 fill-muted-foreground" />
|
||||
{i18n._('homepage.reddit')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://facebook.com/gpx.studio"
|
||||
target="_blank"
|
||||
>
|
||||
<Logo company="facebook" class="h-4 fill-muted-foreground" />
|
||||
{i18n._('homepage.facebook')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="mailto:hello@gpx.studio"
|
||||
target="_blank"
|
||||
>
|
||||
<AtSign size="16" />
|
||||
{i18n._('homepage.email')}
|
||||
</Button>
|
||||
<div class="mt-3 flex flex-row gap-1.5">
|
||||
<LanguageSelect />
|
||||
<ModeSwitch />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grow max-w-2xl flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
|
||||
<div class="flex flex-col items-start gap-1">
|
||||
<span class="font-semibold">{i18n._('homepage.website')}</span>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href={getURLForLanguage(i18n.lang, '/')}
|
||||
>
|
||||
<House size="16" />
|
||||
{i18n._('homepage.home')}
|
||||
</Button>
|
||||
<Button
|
||||
data-sveltekit-reload
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href={getURLForLanguage(i18n.lang, '/app')}
|
||||
>
|
||||
<Map size="16" />
|
||||
{i18n._('homepage.app')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href={getURLForLanguage(i18n.lang, '/help')}
|
||||
>
|
||||
<BookOpenText size="16" />
|
||||
{i18n._('menu.help')}
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex flex-col items-start gap-1" id="contact">
|
||||
<span class="font-semibold">{i18n._('homepage.contact')}</span>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://www.reddit.com/r/gpxstudio/"
|
||||
target="_blank"
|
||||
>
|
||||
<Logo company="reddit" class="h-4 fill-muted-foreground" />
|
||||
{i18n._('homepage.reddit')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://facebook.com/gpx.studio"
|
||||
target="_blank"
|
||||
>
|
||||
<Logo company="facebook" class="h-4 fill-muted-foreground" />
|
||||
{i18n._('homepage.facebook')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="mailto:hello@gpx.studio"
|
||||
target="_blank"
|
||||
>
|
||||
<AtSign size="16" />
|
||||
{i18n._('homepage.email')}
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex flex-col items-start gap-1">
|
||||
<span class="font-semibold">{i18n._('homepage.contribute')}</span>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://opencollective.com/gpxstudio"
|
||||
target="_blank"
|
||||
>
|
||||
<Heart size="16" />
|
||||
{i18n._('menu.donate')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://crowdin.com/project/gpxstudio"
|
||||
target="_blank"
|
||||
>
|
||||
<Logo company="crowdin" class="h-4 fill-muted-foreground" />
|
||||
{i18n._('homepage.crowdin')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://github.com/gpxstudio/gpx.studio"
|
||||
target="_blank"
|
||||
>
|
||||
<Logo company="github" class="h-4 fill-muted-foreground" />
|
||||
{i18n._('homepage.github')}
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex flex-col items-start gap-1">
|
||||
<span class="font-semibold">{i18n._('homepage.contribute')}</span>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://opencollective.com/gpxstudio"
|
||||
target="_blank"
|
||||
>
|
||||
<Heart size="16" />
|
||||
{i18n._('menu.donate')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://crowdin.com/project/gpxstudio"
|
||||
target="_blank"
|
||||
>
|
||||
<Logo company="crowdin" class="h-4 fill-muted-foreground" />
|
||||
{i18n._('homepage.crowdin')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="link"
|
||||
class="h-6 px-0 has-[>svg]:px-0 text-muted-foreground"
|
||||
href="https://github.com/gpxstudio/gpx.studio"
|
||||
target="_blank"
|
||||
>
|
||||
<Logo company="github" class="h-4 fill-muted-foreground" />
|
||||
{i18n._('homepage.github')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,16 +12,17 @@
|
||||
|
||||
const { velocityUnits } = settings;
|
||||
|
||||
let panelHeight: number = $state(0);
|
||||
let panelWidth: number = $state(0);
|
||||
|
||||
let {
|
||||
gpxStatistics,
|
||||
slicedGPXStatistics,
|
||||
orientation,
|
||||
panelSize,
|
||||
}: {
|
||||
gpxStatistics: Readable<GPXStatisticsGroup>;
|
||||
slicedGPXStatistics: Readable<[GPXGlobalStatistics, number, number] | undefined>;
|
||||
orientation: 'horizontal' | 'vertical';
|
||||
panelSize: number;
|
||||
} = $props();
|
||||
|
||||
let statistics = $derived(
|
||||
@@ -32,58 +33,60 @@
|
||||
<Card.Root
|
||||
class="h-full {orientation === 'vertical'
|
||||
? 'min-w-40 sm:min-w-44'
|
||||
: 'w-full h-10'} border-none shadow-none p-0 text-sm sm:text-base bg-inherit"
|
||||
: 'w-full h-fit my-1'} border-none shadow-none p-0 text-sm sm:text-base bg-transparent"
|
||||
>
|
||||
<Card.Content
|
||||
class="h-full flex {orientation === 'vertical'
|
||||
? 'flex-col justify-center'
|
||||
: 'flex-row w-full justify-evenly'} gap-4 p-0"
|
||||
>
|
||||
<Tooltip label={i18n._('quantities.distance')}>
|
||||
<span class="flex flex-row items-center">
|
||||
<Ruler size="16" class="mr-1" />
|
||||
<WithUnits value={statistics.distance.total} type="distance" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip label={i18n._('quantities.elevation_gain_loss')}>
|
||||
<span class="flex flex-row items-center">
|
||||
<MoveUpRight size="16" class="mr-1" />
|
||||
<WithUnits value={statistics.elevation.gain} type="elevation" />
|
||||
<MoveDownRight size="16" class="mx-1" />
|
||||
<WithUnits value={statistics.elevation.loss} type="elevation" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
{#if panelSize > 120 || orientation === 'horizontal'}
|
||||
<Tooltip
|
||||
class={orientation === 'horizontal' ? 'hidden xs:block' : ''}
|
||||
label="{$velocityUnits === 'speed'
|
||||
? i18n._('quantities.speed')
|
||||
: i18n._('quantities.pace')} ({i18n._('quantities.moving')} / {i18n._(
|
||||
'quantities.total'
|
||||
)})"
|
||||
>
|
||||
<Card.Content class="h-full p-0">
|
||||
<div
|
||||
bind:clientHeight={panelHeight}
|
||||
bind:clientWidth={panelWidth}
|
||||
class="flex {orientation === 'vertical'
|
||||
? 'flex-col h-full justify-center'
|
||||
: 'flex-row w-full justify-evenly'} gap-4"
|
||||
>
|
||||
<Tooltip label={i18n._('quantities.distance')}>
|
||||
<span class="flex flex-row items-center">
|
||||
<Zap size="16" class="mr-1" />
|
||||
<WithUnits value={statistics.speed.moving} type="speed" showUnits={false} />
|
||||
<span class="mx-1">/</span>
|
||||
<WithUnits value={statistics.speed.total} type="speed" />
|
||||
<Ruler size="16" class="mr-1" />
|
||||
<WithUnits value={statistics.distance.total} type="distance" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
{#if panelSize > 160 || orientation === 'horizontal'}
|
||||
<Tooltip
|
||||
class={orientation === 'horizontal' ? 'hidden md:block' : ''}
|
||||
label="{i18n._('quantities.time')} ({i18n._('quantities.moving')} / {i18n._(
|
||||
'quantities.total'
|
||||
)})"
|
||||
>
|
||||
<Tooltip label={i18n._('quantities.elevation_gain_loss')}>
|
||||
<span class="flex flex-row items-center">
|
||||
<Timer size="16" class="mr-1" />
|
||||
<WithUnits value={statistics.time.moving} type="time" />
|
||||
<span class="mx-1">/</span>
|
||||
<WithUnits value={statistics.time.total} type="time" />
|
||||
<MoveUpRight size="16" class="mr-1" />
|
||||
<WithUnits value={statistics.elevation.gain} type="elevation" />
|
||||
<MoveDownRight size="16" class="mx-1" />
|
||||
<WithUnits value={statistics.elevation.loss} type="elevation" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
{#if panelHeight > 120 || (orientation === 'horizontal' && panelWidth > 450)}
|
||||
<Tooltip
|
||||
label="{$velocityUnits === 'speed'
|
||||
? i18n._('quantities.speed')
|
||||
: i18n._('quantities.pace')} ({i18n._('quantities.moving')} / {i18n._(
|
||||
'quantities.total'
|
||||
)})"
|
||||
>
|
||||
<span class="flex flex-row items-center">
|
||||
<Zap size="16" class="mr-1" />
|
||||
<WithUnits value={statistics.speed.moving} type="speed" showUnits={false} />
|
||||
<span class="mx-1">/</span>
|
||||
<WithUnits value={statistics.speed.total} type="speed" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
{#if panelHeight > 160 || (orientation === 'horizontal' && panelWidth > 620)}
|
||||
<Tooltip
|
||||
label="{i18n._('quantities.time')} ({i18n._('quantities.moving')} / {i18n._(
|
||||
'quantities.total'
|
||||
)})"
|
||||
>
|
||||
<span class="flex flex-row items-center">
|
||||
<Timer size="16" class="mr-1" />
|
||||
<WithUnits value={statistics.time.moving} type="time" />
|
||||
<span class="mx-1">/</span>
|
||||
<WithUnits value={statistics.time.total} type="time" />
|
||||
</span>
|
||||
</Tooltip>
|
||||
{/if}
|
||||
</div>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
import { getURLForLanguage } from '$lib/utils';
|
||||
</script>
|
||||
|
||||
<nav class="w-full sticky top-0 bg-background z-50">
|
||||
<div class="px-12 py-2 flex flex-row items-center border-b gap-4 sm:gap-8">
|
||||
<nav class="sticky top-0 w-full px-12 py-2 bg-background z-50 flex flex-col items-center border-b">
|
||||
<div class="w-full max-w-5xl flex flex-row items-center gap-4 sm:gap-8">
|
||||
<a
|
||||
href={getURLForLanguage(i18n.lang, '/')}
|
||||
class="shrink-0 translate-y-0.25 justify-self-start"
|
||||
|
||||
@@ -123,7 +123,6 @@
|
||||
<GPXStatistics
|
||||
{gpxStatistics}
|
||||
{slicedGPXStatistics}
|
||||
panelSize={options.elevation.height}
|
||||
orientation={options.elevation.show ? 'vertical' : 'horizontal'}
|
||||
/>
|
||||
{#if options.elevation.show}
|
||||
|
||||
@@ -54,7 +54,7 @@ export class MapLibreGLMap {
|
||||
zoom: 0,
|
||||
hash: hash,
|
||||
boxZoom: false,
|
||||
maxPitch: 85,
|
||||
maxPitch: 90,
|
||||
});
|
||||
this.layerEventManager = new MapLayerEventManager(map);
|
||||
map.addControl(
|
||||
|
||||
@@ -95,7 +95,6 @@ You can also use the mouse wheel to zoom in and out on the elevation profile, an
|
||||
<GPXStatistics
|
||||
{gpxStatistics}
|
||||
{slicedGPXStatistics}
|
||||
panelSize={120}
|
||||
orientation={'horizontal'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -494,6 +494,7 @@
|
||||
"contribute": "Contribute",
|
||||
"supported_by": "supported by",
|
||||
"support_button": "Support gpx.studio on Open Collective",
|
||||
"features": "Features",
|
||||
"route_planning": "Route planning",
|
||||
"route_planning_description": "An intuitive interface to create itineraries tailored to each sport, based on OpenStreetMap data.",
|
||||
"file_processing": "Advanced file processing",
|
||||
@@ -502,6 +503,7 @@
|
||||
"maps_description": "A large collection of basemaps, overlays and points of interest to help you craft your next outdoor adventure, or visualize your latest achievement.",
|
||||
"data_visualization": "Data visualization",
|
||||
"data_visualization_description": "An interactive elevation profile with detailed statistics to analyze recorded activities and future objectives.",
|
||||
"philosophy": "Philosophy",
|
||||
"identity": "Free, ad-free and open source",
|
||||
"identity_description": "The website is free to use, without ads, and the source code is publicly available on GitHub. This is only possible thanks to the incredible support of the community."
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import { getURLForLanguage } from '$lib/utils';
|
||||
import { exampleGPXFile } from '$lib/assets/example';
|
||||
import { writable } from 'svelte/store';
|
||||
import Toolbar from '$lib/components/toolbar/Toolbar.svelte';
|
||||
import Scissors from '$lib/components/toolbar/tools/scissors/Scissors.svelte';
|
||||
import { currentTool, Tool } from '$lib/components/toolbar/tools';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
|
||||
@@ -53,17 +53,17 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="space-y-24 my-24">
|
||||
<div class="-mt-12 sm:mt-0">
|
||||
<div class="px-12 w-full flex flex-col items-center">
|
||||
<div class="flex flex-col gap-6 items-center max-w-3xl">
|
||||
<h1 class="text-4xl sm:text-6xl font-black text-center">
|
||||
<div class="w-full px-12 flex flex-col items-center">
|
||||
<div class="w-full max-w-5xl flex flex-col items-center">
|
||||
<div class="mt-12 flex flex-col lg:items-center gap-12">
|
||||
<div class="flex flex-col lg:items-center gap-6 max-w-3xl">
|
||||
<h1 class="text-4xl xs:text-5xl sm:text-6xl lg:text-center font-black">
|
||||
{i18n._('metadata.home_title')}
|
||||
</h1>
|
||||
<div class="text-lg sm:text-xl text-muted-foreground text-center">
|
||||
<div class="text-lg sm:text-xl text-muted-foreground lg:text-center">
|
||||
{i18n._('metadata.description')}
|
||||
</div>
|
||||
<div class="w-full flex flex-row justify-center gap-3">
|
||||
<div class="w-full flex flex-row lg:justify-center gap-3">
|
||||
<Button
|
||||
data-sveltekit-reload
|
||||
href={getURLForLanguage(i18n.lang, '/app')}
|
||||
@@ -82,184 +82,221 @@
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative overflow-hidden">
|
||||
<enhanced:img
|
||||
src="/src/lib/assets/img/home/routing.png"
|
||||
alt="Screenshot of the gpx.studio map in 3D."
|
||||
class="w-full min-w-[1200px] ml-[20%] -translate-x-[20%]"
|
||||
src="/src/lib/assets/img/docs/getting-started/interface.webp"
|
||||
alt="The gpx.studio interface."
|
||||
class="rounded-xl shadow-2xl w-full"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-center text-4xl font-extrabold mt-24 mb-6">
|
||||
{i18n._('homepage.features')}
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 gap-12 border-t pt-6">
|
||||
<div class="grid md:grid-rows-subgrid md:row-start-1 md:row-end-3 gap-4">
|
||||
<div class="markdown homepage">
|
||||
<h1>
|
||||
<Route size="20" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.route_planning')}
|
||||
</h1>
|
||||
<p>
|
||||
{i18n._('homepage.route_planning_description')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<div
|
||||
class="p-3 border rounded-xl shadow-xl origin-top-left scale-45 xs:scale-75 md:scale-45 lg:scale-70 absolute top-1.5 left-1.5 bg-background"
|
||||
>
|
||||
<Routing minimizable={false} />
|
||||
</div>
|
||||
<enhanced:img
|
||||
src="/src/lib/assets/img/docs/tools/routing.png"
|
||||
alt="Route planning illustration."
|
||||
class="h-full object-cover rounded-xl shadow-lg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid md:grid-rows-subgrid md:row-start-1 md:row-end-3 gap-4">
|
||||
<div class="markdown homepage">
|
||||
<h1>
|
||||
<Map size="20" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.maps')}
|
||||
</h1>
|
||||
<p>{i18n._('homepage.maps_description')}</p>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<enhanced:img
|
||||
src="/src/lib/assets/img/home/map.png"
|
||||
alt="MapTiler Topo map screenshot."
|
||||
class="h-full object-cover rounded-xl shadow-lg"
|
||||
/>
|
||||
<enhanced:img
|
||||
src="/src/lib/assets/img/home/map-overlay.png"
|
||||
alt="MapTiler Topo map screenshot."
|
||||
class="absolute top-0 left-0 rounded-xl opacity-0 hover:opacity-100 transition-opacity duration-200"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid md:grid-rows-subgrid md:row-start-3 md:row-end-6 gap-4">
|
||||
<div class="markdown homepage">
|
||||
<h1>
|
||||
<ChartArea size="20" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.data_visualization')}
|
||||
</h1>
|
||||
<p>
|
||||
{i18n._('homepage.data_visualization_description')}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="h-full w-full aspect-3/2 overflow-hidden flex flex-col gap-2 rounded-xl pt-6 pb-4 px-6 bg-secondary/50 border shadow-lg"
|
||||
>
|
||||
<div class="grow">
|
||||
<ElevationProfile
|
||||
{gpxStatistics}
|
||||
{slicedGPXStatistics}
|
||||
{hoveredPoint}
|
||||
{additionalDatasets}
|
||||
{elevationFill}
|
||||
/>
|
||||
</div>
|
||||
<GPXStatistics
|
||||
{gpxStatistics}
|
||||
{slicedGPXStatistics}
|
||||
orientation={'horizontal'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid md:grid-rows-subgrid md:row-start-3 md:row-end-6 gap-4">
|
||||
<div class="markdown homepage">
|
||||
<h1>
|
||||
<PencilRuler size="20" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.file_processing')}
|
||||
</h1>
|
||||
<p>
|
||||
{i18n._('homepage.file_processing_description')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<div
|
||||
class="p-3 border rounded-xl shadow-xl origin-top-right scale-45 xs:scale-75 md:scale-45 lg:scale-70 absolute top-1.5 right-1.5 bg-background"
|
||||
>
|
||||
<Scissors />
|
||||
</div>
|
||||
<enhanced:img
|
||||
src="/src/lib/assets/img/docs/tools/split.png"
|
||||
alt="Splitting illustration."
|
||||
class="h-full object-cover rounded-xl shadow-lg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center text-4xl font-extrabold mt-24 mb-6">
|
||||
{i18n._('homepage.philosophy')}
|
||||
</div>
|
||||
<div class="grid md:grid-cols-2 gap-12 border-t pt-6">
|
||||
<div class="grid md:grid-rows-subgrid md:row-start-1 md:row-end-3 gap-4">
|
||||
<div class="markdown homepage">
|
||||
<h1>
|
||||
<PencilRuler size="20" class="inline-block align-baseline" />
|
||||
Free and ad-free
|
||||
</h1>
|
||||
<p>explanation</p>
|
||||
</div>
|
||||
<p>image?</p>
|
||||
</div>
|
||||
<div class="grid md:grid-rows-subgrid md:row-start-1 md:row-end-3 gap-4">
|
||||
<div class="markdown homepage">
|
||||
<h1>
|
||||
<PencilRuler size="20" class="inline-block align-baseline" />
|
||||
Privacy first
|
||||
</h1>
|
||||
<p>explanation</p>
|
||||
</div>
|
||||
<p>image?</p>
|
||||
</div>
|
||||
<div class="grid md:grid-rows-subgrid md:row-start-3 md:row-end-6 gap-4">
|
||||
<div class="markdown homepage">
|
||||
<h1>
|
||||
<PencilRuler size="20" class="inline-block align-baseline" />
|
||||
Free and ad-free
|
||||
</h1>
|
||||
<p>explanation</p>
|
||||
</div>
|
||||
<p>image?</p>
|
||||
</div>
|
||||
<div class="grid md:grid-rows-subgrid md:row-start-3 md:row-end-6 gap-4">
|
||||
<div class="markdown homepage">
|
||||
<h1>
|
||||
<PencilRuler size="20" class="inline-block align-baseline" />
|
||||
Free and ad-free
|
||||
</h1>
|
||||
<p>explanation</p>
|
||||
</div>
|
||||
<p>image?</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-12 sm:px-24 w-full flex flex-col items-center">
|
||||
<div
|
||||
class="absolute top-0 left-0 w-full h-full bg-gradient-to-b from-background via-transparent to-background"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-12 sm:px-24 w-full flex flex-col items-center">
|
||||
<div
|
||||
class="flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl"
|
||||
>
|
||||
<div class="markdown text-center">
|
||||
<h1>
|
||||
<Route size="24" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.route_planning')}
|
||||
</h1>
|
||||
<p class="text-muted-foreground">{i18n._('homepage.route_planning_description')}</p>
|
||||
</div>
|
||||
<div class="p-3 w-fit rounded-md border shadow-xl md:shrink-0">
|
||||
<Routing minimizable={false} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-12 sm:px-24 w-full flex flex-col items-center">
|
||||
<div
|
||||
class="flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl"
|
||||
>
|
||||
<div class="markdown text-center md:hidden">
|
||||
<h1>
|
||||
<PencilRuler size="24" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.file_processing')}
|
||||
</h1>
|
||||
<p class="text-muted-foreground">
|
||||
{i18n._('homepage.file_processing_description')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="relative md:shrink-0 max-w-[400px]">
|
||||
<Toolbar />
|
||||
</div>
|
||||
<div class="markdown text-center hidden md:block">
|
||||
<h1>
|
||||
<PencilRuler size="24" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.file_processing')}
|
||||
</h1>
|
||||
<p class="text-muted-foreground">
|
||||
{i18n._('homepage.file_processing_description')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-12 sm:px-24 w-full flex flex-col items-center">
|
||||
<div
|
||||
class="markdown flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl"
|
||||
>
|
||||
<div class="markdown text-center">
|
||||
<h1>
|
||||
<Map size="24" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.maps')}
|
||||
</h1>
|
||||
<p class="text-muted-foreground">{i18n._('homepage.maps_description')}</p>
|
||||
</div>
|
||||
<div
|
||||
class="relative w-full max-w-[320px] aspect-square rounded-2xl shadow-xl overflow-clip"
|
||||
class="flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl"
|
||||
>
|
||||
<enhanced:img
|
||||
src="/src/lib/assets/img/home/maptiler-topo.png"
|
||||
alt="MapTiler Topo map screenshot."
|
||||
class="absolute"
|
||||
style="clip-path: inset(0 50% 50% 0);"
|
||||
/>
|
||||
<enhanced:img
|
||||
src="/src/lib/assets/img/home/maptiler-satellite.png"
|
||||
alt="MapTiler Satellite map screenshot."
|
||||
class="absolute"
|
||||
style="clip-path: inset(0 0 50% 50%);"
|
||||
/>
|
||||
<enhanced:img
|
||||
src="/src/lib/assets/img/home/ign.png"
|
||||
alt="IGN map screenshot."
|
||||
class="absolute"
|
||||
style="clip-path: inset(50% 50% 0 0);"
|
||||
/>
|
||||
<enhanced:img
|
||||
src="/src/lib/assets/img/home/cyclosm.png"
|
||||
alt="CyclOSM map screenshot."
|
||||
class="absolute"
|
||||
style="clip-path: inset(50% 0 0 50%);"
|
||||
/>
|
||||
<enhanced:img
|
||||
src="/src/lib/assets/img/home/waymarked.png"
|
||||
alt="Waymarked Trails map screenshot."
|
||||
class="absolute"
|
||||
/>
|
||||
<div class="markdown text-center md:hidden">
|
||||
<h1>
|
||||
<Scale size="20" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.identity')}
|
||||
</h1>
|
||||
<p class="text-muted-foreground">{i18n._('homepage.identity_description')}</p>
|
||||
</div>
|
||||
<a href="https://github.com/gpxstudio/gpx.studio" target="_blank">
|
||||
<Logo class="h-32" company="github" />
|
||||
</a>
|
||||
<div class="markdown text-center hidden md:block">
|
||||
<h1>
|
||||
<Scale size="20" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.identity')}
|
||||
</h1>
|
||||
<p class="text-muted-foreground">{i18n._('homepage.identity_description')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-8 md:px-12">
|
||||
<div class="markdown text-center px-4 md:px-12">
|
||||
<h1>
|
||||
<ChartArea size="24" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.data_visualization')}
|
||||
</h1>
|
||||
<p class="text-muted-foreground mb-6">
|
||||
{i18n._('homepage.data_visualization_description')}
|
||||
</p>
|
||||
</div>
|
||||
<div class="h-48 w-full">
|
||||
<ElevationProfile
|
||||
{gpxStatistics}
|
||||
{slicedGPXStatistics}
|
||||
{hoveredPoint}
|
||||
{additionalDatasets}
|
||||
{elevationFill}
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="h-10 w-fit">
|
||||
<GPXStatistics
|
||||
{gpxStatistics}
|
||||
{slicedGPXStatistics}
|
||||
panelSize={192}
|
||||
orientation={'horizontal'}
|
||||
/>
|
||||
<div class="flex flex-row flex-wrap lg:flex-nowrap items-center justify-center">
|
||||
<div
|
||||
class="grow max-w-xl flex flex-col items-center gap-6 p-8 border rounded-2xl shadow-xl"
|
||||
>
|
||||
{#await data.fundingModule then fundingModule}
|
||||
<DocsContainer module={fundingModule.default} />
|
||||
{/await}
|
||||
<Button
|
||||
href="https://opencollective.com/gpxstudio"
|
||||
target="_blank"
|
||||
class="text-base"
|
||||
>
|
||||
<Heart size="16" fill="var(--support)" color="var(--support)" />
|
||||
<span>{i18n._('homepage.support_button')}</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-12 sm:px-24 w-full flex flex-col items-center">
|
||||
<div
|
||||
class="flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl"
|
||||
>
|
||||
<div class="markdown text-center md:hidden">
|
||||
<h1>
|
||||
<Scale size="24" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.identity')}
|
||||
</h1>
|
||||
<p class="text-muted-foreground">{i18n._('homepage.identity_description')}</p>
|
||||
<div
|
||||
class="grow max-w-lg mx-6 h-fit bg-background flex flex-col items-center gap-6 p-8 border rounded-2xl shadow-xl"
|
||||
>
|
||||
{#await data.translationModule then translationModule}
|
||||
<DocsContainer module={translationModule.default} />
|
||||
{/await}
|
||||
<Button
|
||||
href="https://crowdin.com/project/gpxstudio"
|
||||
target="_blank"
|
||||
class="text-base"
|
||||
>
|
||||
<PenLine size="16" />
|
||||
<span>{i18n._('homepage.contribute')}</span>
|
||||
</Button>
|
||||
</div>
|
||||
<a href="https://github.com/gpxstudio/gpx.studio" target="_blank">
|
||||
<Logo class="h-32" company="github" />
|
||||
</a>
|
||||
<div class="markdown text-center hidden md:block">
|
||||
<h1>
|
||||
<Scale size="24" class="inline-block align-baseline" />
|
||||
{i18n._('homepage.identity')}
|
||||
</h1>
|
||||
<p class="text-muted-foreground">{i18n._('homepage.identity_description')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="px-12 md:px-24 flex flex-row flex-wrap lg:flex-nowrap items-center justify-center -space-y-0.5 lg:-space-x-6"
|
||||
>
|
||||
<div
|
||||
class="grow max-w-xl flex flex-col items-center gap-6 p-8 border rounded-2xl shadow-xl -rotate-1 lg:rotate-1"
|
||||
>
|
||||
{#await data.fundingModule then fundingModule}
|
||||
<DocsContainer module={fundingModule.default} />
|
||||
{/await}
|
||||
<Button href="https://opencollective.com/gpxstudio" target="_blank" class="text-base">
|
||||
<Heart size="16" fill="var(--support)" color="var(--support)" />
|
||||
<span>{i18n._('homepage.support_button')}</span>
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
class="grow max-w-lg mx-6 h-fit bg-background flex flex-col items-center gap-6 p-8 border rounded-2xl shadow-xl rotate-1 lg:-rotate-1"
|
||||
>
|
||||
{#await data.translationModule then translationModule}
|
||||
<DocsContainer module={translationModule.default} />
|
||||
{/await}
|
||||
<Button href="https://crowdin.com/project/gpxstudio" target="_blank" class="text-base">
|
||||
<PenLine size="16" />
|
||||
<span>{i18n._('homepage.contribute')}</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
@reference "../../app.css";
|
||||
|
||||
:global(.markdown.homepage > h1) {
|
||||
@apply text-2xl;
|
||||
@apply pt-0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -141,7 +141,6 @@
|
||||
<GPXStatistics
|
||||
{gpxStatistics}
|
||||
{slicedGPXStatistics}
|
||||
panelSize={$bottomPanelSize}
|
||||
orientation={bottomPanelOrientation == 'horizontal' ? 'vertical' : 'horizontal'}
|
||||
/>
|
||||
{#if $elevationProfile}
|
||||
|
||||