Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b70b878a4 | ||
|
|
232ef4d914 | ||
|
|
df81c74d76 | ||
|
|
d85708a571 | ||
|
|
3911e55a6c | ||
|
|
c09df15821 | ||
|
|
defd3968fd | ||
|
|
0386cc3fe0 | ||
|
|
832c37ef9d | ||
|
|
f2f42c0400 | ||
|
|
d49d5e79f2 | ||
|
|
4209771189 | ||
|
|
e43baa13da | ||
|
|
b243c3129d | ||
|
|
3f60672bb0 | ||
|
|
5792d7d15f | ||
|
|
91ea78c632 | ||
|
|
961fd0d198 | ||
|
|
1cba7b398b | ||
|
|
05d3bca10b | ||
|
|
3acfc6db47 | ||
|
|
6c350bf2d5 | ||
|
|
712d408736 | ||
|
|
bfdd433a5f | ||
|
|
ac6558392c | ||
|
|
484fe3b031 | ||
|
|
c88133a9a3 | ||
|
|
1cb77dd6f0 | ||
|
|
a2fe47210f | ||
|
|
38dfd3c952 |
26
README.md
@@ -1,5 +1,25 @@
|
||||
# Leim Maps
|
||||
Repository for interactive maps using Leim's Wiki data
|
||||
🗺️ A simple Astro static site to display custom maps with Leaflet. Includes sample images with maps from my own world.
|
||||
|
||||
## Demo
|
||||
Live demo available at https://maps.alexcreates.fr
|
||||
## Features
|
||||
* Add your own markers for cities, NPCs, or quests
|
||||
* Search through markers
|
||||
* Create multiple maps for different continents or countries
|
||||
* Measure distances between two points
|
||||
* Custom client-side markers
|
||||
|
||||
## Documentation
|
||||
### Making usable map assets
|
||||
Since we're not using earth maps, we need to build one compatible with Leaflet. I used Zoomify to generate usable tile data from my SVG maps. I don't know if this will fit your use case ; if you use something else, you can contact me !
|
||||
|
||||
> [!IMPORTANT]
|
||||
> As of writing this, it appears Zoomify Unlimited Converter (which is what I used) is not available on Linux or for download anymore
|
||||
|
||||
### Enabling features
|
||||
Some features are able to be toggled on and off. If you don't use multiple languages, or if you don't want the custom markers, you can disable them in the .env file. By default, all of them are true.
|
||||
|
||||
## Contributing
|
||||
I'm not currently accepting pull-requests for this project, but if you have a suggestion, feel free to contact me !
|
||||
|
||||
## Notes
|
||||
As someone with some degree of with [aphantasia](https://en.wikipedia.org/wiki/Aphantasia), I struggle with visualization and immersion, and DMing in general. If you find yourself in the same situation, I hope my little thing made your life easier !
|
||||
|
||||
22
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "leim-maps",
|
||||
"type": "module",
|
||||
"version": "1.4.10",
|
||||
"version": "1.4.13",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
@@ -10,18 +10,18 @@
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/sitemap": "^3.4.1",
|
||||
"@astrojs/vue": "^5.1.0",
|
||||
"@nanostores/persistent": "1.0.0",
|
||||
"@nanostores/vue": "^1.0.0",
|
||||
"@types/leaflet": "^1.9.18",
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"astro": "^5.9.3",
|
||||
"nanostores": "^1.0.1",
|
||||
"@astrojs/sitemap": "^3.6.0",
|
||||
"@astrojs/vue": "^5.1.3",
|
||||
"@nanostores/persistent": "1.2.0",
|
||||
"@nanostores/vue": "^1.0.1",
|
||||
"@types/leaflet": "^1.9.21",
|
||||
"@vueuse/core": "^14.0.0",
|
||||
"astro": "^5.15.9",
|
||||
"nanostores": "^1.1.0",
|
||||
"radix-vue": "^1.9.17",
|
||||
"vue": "^3.5.16"
|
||||
"vue": "^3.5.24"
|
||||
},
|
||||
"devDependencies": {
|
||||
"sass": "^1.89.2"
|
||||
"sass": "^1.94.1"
|
||||
}
|
||||
}
|
||||
|
||||
2259
pnpm-lock.yaml
generated
1
public/icon/question-mark-dark.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="#FFF"><path d="M140,180a12,12,0,1,1-12-12A12,12,0,0,1,140,180ZM128,72c-22.06,0-40,16.15-40,36v4a8,8,0,0,0,16,0v-4c0-11,10.77-20,24-20s24,9,24,20-10.77,20-24,20a8,8,0,0,0-8,8v8a8,8,0,0,0,16,0v-.72c18.24-3.35,32-17.9,32-35.28C168,88.15,150.06,72,128,72Zm104,56A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 440 B |
1
public/icon/ruler-dark.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#FFF" viewBox="0 0 256 256"><path d="M235.32,73.37,182.63,20.69a16,16,0,0,0-22.63,0L20.68,160a16,16,0,0,0,0,22.63l52.69,52.68a16,16,0,0,0,22.63,0L235.32,96A16,16,0,0,0,235.32,73.37ZM84.68,224,32,171.31l32-32,26.34,26.35a8,8,0,0,0,11.32-11.32L75.31,128,96,107.31l26.34,26.35a8,8,0,0,0,11.32-11.32L107.31,96,128,75.31l26.34,26.35a8,8,0,0,0,11.32-11.32L139.31,64l32-32L224,84.69Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 461 B |
1
public/icon/ruler.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#020617" viewBox="0 0 256 256"><path d="M235.32,73.37,182.63,20.69a16,16,0,0,0-22.63,0L20.68,160a16,16,0,0,0,0,22.63l52.69,52.68a16,16,0,0,0,22.63,0L235.32,96A16,16,0,0,0,235.32,73.37ZM84.68,224,32,171.31l32-32,26.34,26.35a8,8,0,0,0,11.32-11.32L75.31,128,96,107.31l26.34,26.35a8,8,0,0,0,11.32-11.32L107.31,96,128,75.31l26.34,26.35a8,8,0,0,0,11.32-11.32L139.31,64l32-32L224,84.69Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 464 B |
1
public/icon/square-arrow-out-dark.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M224,104a8,8,0,0,1-13.66,5.66L184,83.31l-42.34,42.35a8,8,0,0,1-11.32-11.32L172.69,72,146.34,45.66A8,8,0,0,1,152,32h64a8,8,0,0,1,8,8Zm-40,24a8,8,0,0,0-8,8v72H48V80h72a8,8,0,0,0,0-16H48A16,16,0,0,0,32,80V208a16,16,0,0,0,16,16H176a16,16,0,0,0,16-16V136A8,8,0,0,0,184,128Z" fill="#FFF" /></svg>
|
||||
|
After Width: | Height: | Size: 405 B |
BIN
public/leaflet/images/marker-icon-2x.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
public/leaflet/images/marker-icon.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
public/leaflet/images/marker-shadow.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
@@ -1,7 +1,7 @@
|
||||
// Animations on load
|
||||
@media screen and (prefers-reduced-motion: no-preference) {
|
||||
.appear-from-top {
|
||||
animation: fadeIn .2s cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||
animation: fadeIn .2s var(--timing-function);
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
gap: .5rem;
|
||||
font-size: .9em;
|
||||
font-weight: 500;
|
||||
color: var(--foreground);
|
||||
border: 1px solid transparent;
|
||||
border-radius: .2rem;
|
||||
border-radius: var(--border-radius);
|
||||
cursor: pointer;
|
||||
transition-property: color, background-color, border-color;
|
||||
transition-duration: .2s;
|
||||
transition-timing-function: cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||
transition-timing-function: var(--timing-function);
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
@@ -18,40 +19,40 @@
|
||||
|
||||
&.btn-secondary {
|
||||
&:not(:disabled) {
|
||||
background-color: var(--slate-200);
|
||||
background-color: color-mix(in srgb, var(--foreground) 20%, var(--background));
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
color: var(--white);
|
||||
background-color: var(--blue-500);
|
||||
color: var(--background);
|
||||
background-color: var(--accent);
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: var(--slate-500);
|
||||
background-color: var(--slate-100);
|
||||
color: color-mix(in srgb, var(--foreground) 50%, var(--background));
|
||||
background-color: color-mix(in srgb, var(--foreground) 10%, var(--background));
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-info {
|
||||
&:not(:disabled) {
|
||||
background-color: var(--slate-200);
|
||||
background-color: color-mix(in srgb, var(--foreground) 20%, var(--background));
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
color: var(--white);
|
||||
background-color: var(--blue-500);
|
||||
color: var(--background);
|
||||
background-color: var(--accent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-danger {
|
||||
&:not(:disabled) {
|
||||
background-color: var(--slate-200);
|
||||
background-color: color-mix(in srgb, var(--foreground) 20%, var(--background));
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
color: var(--white);
|
||||
color: var(--background);
|
||||
background-color: var(--red-500);
|
||||
}
|
||||
}
|
||||
@@ -76,7 +77,7 @@
|
||||
}
|
||||
|
||||
&.btn-shadow {
|
||||
box-shadow: color-mix(in srgb, var(--black) 10%, transparent) 0 .2rem .3rem;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,41 +86,42 @@
|
||||
place-items: center;
|
||||
height: 45px;
|
||||
aspect-ratio: 1;
|
||||
background-color: var(--white);
|
||||
border: 1px solid var(--slate-400);
|
||||
box-shadow: color-mix(in srgb, var(--black) 10%, transparent) 0px 4px 12px;
|
||||
background-color: var(--background);
|
||||
border: 1px solid var(--border);
|
||||
box-shadow: var(--shadow);
|
||||
border-radius: 100vmax;
|
||||
pointer-events: all;
|
||||
cursor: pointer;
|
||||
outline: .2rem solid transparent;
|
||||
transition-property: color, background-color, border-color, outline-color;
|
||||
transition-duration: .15s;
|
||||
transition-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
||||
transition-timing-function: var(--timing-function);
|
||||
|
||||
svg {
|
||||
fill: var(--foreground);
|
||||
width: 1.15em;
|
||||
transition-property: fill;
|
||||
transition-duration: .15s;
|
||||
transition-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
||||
transition-timing-function: var(--timing-function);
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
outline-color: color-mix(in srgb, var(--blue-500) 20%, transparent);
|
||||
border-color: var(--blue-500);
|
||||
outline-color: color-mix(in srgb, var(--accent) 20%, transparent);
|
||||
border-color: var(--accent);
|
||||
|
||||
svg {
|
||||
fill: var(--blue-500);
|
||||
fill: var(--accent);
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--white);
|
||||
background-color: var(--blue-500);
|
||||
border-color: var(--blue-700);
|
||||
color: var(--background);
|
||||
background-color: var(--accent);
|
||||
border-color: color-mix(in srgb, var(--accent) 75%, var(--background));
|
||||
|
||||
svg {
|
||||
fill: var(--white);
|
||||
fill: var(--background);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,14 @@
|
||||
padding-block: 0.75rem;
|
||||
padding-inline: .75rem;
|
||||
border-radius: 8px;
|
||||
background-color: var(--white);
|
||||
border: 1px solid var(--slate-100);
|
||||
box-shadow: color-mix(in srgb, var(--black) 10%, transparent) 0px 4px 12px;
|
||||
color: var(--foreground);
|
||||
background-color: var(--background);
|
||||
border: 1px solid var(--border);
|
||||
box-shadow: var(--shadow);
|
||||
min-width: 15rem;
|
||||
|
||||
.card-arrow {
|
||||
fill: var(--white);
|
||||
fill: var(--background);
|
||||
}
|
||||
|
||||
&.p-sm {
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: .4rem .5rem;
|
||||
border: 1px solid var(--slate-300);
|
||||
border: 1px solid color-mix(in srgb, var(--foreground) 30%, var(--background));
|
||||
font-size: .8em;
|
||||
border-radius: .2rem;
|
||||
border-radius: var(--border-radius);
|
||||
transition-property: box-shadow;
|
||||
transition-duration: .2s;
|
||||
transition-timing-function: cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||
transition-timing-function: var(--timing-function);
|
||||
|
||||
&:focus-visible {
|
||||
box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--slate-300) 20%, transparent);
|
||||
box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--accent) 20%, transparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
.leaflet-map-pane {
|
||||
.leaflet-popup-pane {
|
||||
.leaflet-popup-content-wrapper {
|
||||
border-radius: .25rem;
|
||||
color: var(--foreground);
|
||||
background-color: var(--background);
|
||||
border-radius: var(--border-radius);
|
||||
overflow: clip;
|
||||
|
||||
.leaflet-popup-content {
|
||||
@@ -22,6 +24,7 @@
|
||||
.leaflet-popup-tip {
|
||||
width: .8rem;
|
||||
height: .8rem;
|
||||
background-color: var(--background);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,15 +32,18 @@
|
||||
.leaflet-tooltip {
|
||||
&.capital-name {
|
||||
padding: .2rem .4rem;
|
||||
color: #EEE;
|
||||
color: var(--foreground);
|
||||
font-weight: bold;
|
||||
background: none;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
transition-property: color, text-shadow;
|
||||
transition-duration: .15s;
|
||||
transition-timing-function: var(--timing-function);
|
||||
|
||||
@include text.stroke(2, #18181b);
|
||||
@include text.stroke(2, var(--background));
|
||||
|
||||
&::before {
|
||||
display: none;
|
||||
@@ -47,3 +53,56 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border-color: var(--border);
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
color: var(--foreground);
|
||||
background-color: var(--background);
|
||||
border-color: var(--border);
|
||||
transition-property: color, background-color, border-color, outline-color;
|
||||
transition-duration: .15s;
|
||||
transition-timing-function: var(--timing-function);
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
color: var(--background);
|
||||
background-color: var(--accent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-measure {
|
||||
color: var(--foreground);
|
||||
background-color: var(--background);
|
||||
transition-property: color, background-color, border-color, outline-color;
|
||||
transition-duration: .15s;
|
||||
transition-timing-function: var(--timing-function);
|
||||
|
||||
.leaflet-control-measure-toggle {
|
||||
color: var(--foreground);
|
||||
background-color: var(--background);
|
||||
border-color: var(--border);
|
||||
background-image: url('/icon/ruler.svg');
|
||||
background-size: 66%;
|
||||
transition-property: color, background-color, border-color, outline-color;
|
||||
transition-duration: .15s;
|
||||
transition-timing-function: var(--timing-function);
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
color: var(--background);
|
||||
background-color: var(--accent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dark {
|
||||
.leaflet-touch .leaflet-control-measure {
|
||||
.leaflet-control-measure-toggle {
|
||||
background-image: url('/icon/ruler-dark.svg');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
.dialog-overlay {
|
||||
background-color: color-mix(in srgb, var(--black) 40%, transparent);
|
||||
background-color: color-mix(in srgb, var(--black) 50%, transparent);
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
animation: show-overlay 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
animation: show-overlay 150ms var(--timing-function);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
@@ -19,11 +19,12 @@
|
||||
padding: 25px;
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
border-radius: 8px;
|
||||
background-color: var(--white);
|
||||
border: 1px solid var(--slate-100);
|
||||
box-shadow: color-mix(in srgb, var(--black) 10%, transparent) 0px 4px 12px;
|
||||
animation: show-content 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
color: var(--foreground);
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--background);
|
||||
border: 1px solid var(--border);
|
||||
box-shadow: var(--shadow);
|
||||
animation: show-content 150ms var(--timing-function);
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
@@ -46,7 +47,7 @@
|
||||
}
|
||||
|
||||
font-size: 1em;
|
||||
color: var(--slate-800);
|
||||
color: color-mix(in srgb, var(--foreground) 80%, var(--background));
|
||||
line-height: 1.5;
|
||||
|
||||
> * + * {
|
||||
@@ -63,11 +64,6 @@
|
||||
text-decoration: none;
|
||||
color: var(--green-500);
|
||||
}
|
||||
|
||||
&::after {
|
||||
top: 50%;
|
||||
transform: translateY(-70%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,16 +23,16 @@
|
||||
grid-template-columns: auto max-content;
|
||||
column-gap: 15px;
|
||||
align-items: center;
|
||||
color: var(--slate-800);
|
||||
border: 1px solid var(--slate-400);
|
||||
background-color: var(--white);
|
||||
border-radius: 6px;
|
||||
color: var(--foreground);
|
||||
border: 1px solid var(--border);
|
||||
background-color: var(--background);
|
||||
border-radius: var(--border-radius);
|
||||
box-shadow: hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px;
|
||||
|
||||
&.toast-success {
|
||||
color: var(--green-700);
|
||||
border: 1px solid var(--green-700);
|
||||
background-color: color-mix(in srgb, var(--green-500) 17.5%, var(--white));
|
||||
background-color: color-mix(in srgb, var(--green-500) 17.5%, var(--background));
|
||||
|
||||
.toast-icon svg {
|
||||
fill: var(--green-700);
|
||||
@@ -51,20 +51,20 @@
|
||||
}
|
||||
}
|
||||
.toast-root[data-state='open'] {
|
||||
animation: slideIn 150ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
animation: slideIn 150ms var(--timing-function);
|
||||
}
|
||||
.toast-root[data-state='closed'] {
|
||||
animation: hide 100ms ease-in;
|
||||
animation: hide 100ms var(--timing-function);
|
||||
}
|
||||
.toast-root[data-swipe='move'] {
|
||||
transform: translateX(var(--radix-toast-swipe-move-x));
|
||||
}
|
||||
.toast-root[data-swipe='cancel'] {
|
||||
transform: translateX(0);
|
||||
transition: transform 200ms ease-out;
|
||||
transition: transform 200ms var(--timing-function);
|
||||
}
|
||||
.toast-root[data-swipe='end'] {
|
||||
animation: swipeOut 100ms ease-out;
|
||||
animation: swipeOut 100ms var(--timing-function);
|
||||
}
|
||||
|
||||
@keyframes hide {
|
||||
|
||||
@@ -37,19 +37,34 @@
|
||||
--orange-700: #c2410c;
|
||||
--purple-500: #8b5cf6;
|
||||
--purple-700: #6d28d9;
|
||||
|
||||
--foreground: var(--black);
|
||||
--background: var(--white);
|
||||
--border: var(--slate-400);
|
||||
--accent: var(--blue-500);
|
||||
|
||||
--border-radius: .25rem;
|
||||
--shadow: color-mix(in srgb, var(--foreground) 10%, transparent) 0px 4px 12px;
|
||||
--timing-function: cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--foreground: var(--slate-300);
|
||||
--background: var(--slate-950);
|
||||
--border: var(--slate-600);
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
color: var(--slate-900);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
a[href^='http'] {
|
||||
padding-right: 1.25em;
|
||||
white-space: nowrap;
|
||||
orphans: 2;
|
||||
}
|
||||
|
||||
a[href^='http']::after {
|
||||
position: absolute;
|
||||
content: url('/icon/square-arrow-out.svg');
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
@@ -57,6 +72,12 @@ a[href^='http']::after {
|
||||
margin-left: .25em;
|
||||
}
|
||||
|
||||
.dark {
|
||||
a[href^='http']::after {
|
||||
content: url('/icon/square-arrow-out-dark.svg');
|
||||
}
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: .5ch;
|
||||
color: var(--slate-700);
|
||||
color: color-mix(in srgb, var(--foreground) 70%, var(--background));
|
||||
cursor: pointer;
|
||||
text-underline-offset: 2px;
|
||||
text-decoration: none;
|
||||
@@ -75,7 +75,7 @@ button {
|
||||
svg {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
fill: var(--slate-700);
|
||||
fill: color-mix(in srgb, var(--foreground) 70%, var(--background));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
32
src/components/global/ThemeSwitch.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<script lang="ts" setup>
|
||||
import { useDark, useToggle } from '@vueuse/core'
|
||||
|
||||
import { currentLang, t } from '@/i18n/store';
|
||||
|
||||
const isDark = useDark({ storageKey: "theme", disableTransition: false })
|
||||
const toggleDark = useToggle(isDark)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div data-theme-toggle id="theme-switcher" class="wrapper appear-from-top">
|
||||
<button @click="toggleDark()" class="btn-round" :title="t('nav.theme.aria-label')">
|
||||
<svg v-if="isDark" xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M120,40V32a8,8,0,0,1,16,0v8a8,8,0,0,1-16,0Zm72,88a64,64,0,1,1-64-64A64.07,64.07,0,0,1,192,128Zm-16,0a48,48,0,1,0-48,48A48.05,48.05,0,0,0,176,128ZM58.34,69.66A8,8,0,0,0,69.66,58.34l-8-8A8,8,0,0,0,50.34,61.66Zm0,116.68-8,8a8,8,0,0,0,11.32,11.32l8-8a8,8,0,0,0-11.32-11.32ZM192,72a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0-11.32-11.32l-8,8A8,8,0,0,0,192,72Zm5.66,114.34a8,8,0,0,0-11.32,11.32l8,8a8,8,0,0,0,11.32-11.32ZM40,120H32a8,8,0,0,0,0,16h8a8,8,0,0,0,0-16Zm88,88a8,8,0,0,0-8,8v8a8,8,0,0,0,16,0v-8A8,8,0,0,0,128,208Zm96-88h-8a8,8,0,0,0,0,16h8a8,8,0,0,0,0-16Z"></path></svg>
|
||||
<svg v-else xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M233.54,142.23a8,8,0,0,0-8-2,88.08,88.08,0,0,1-109.8-109.8,8,8,0,0,0-10-10,104.84,104.84,0,0,0-52.91,37A104,104,0,0,0,136,224a103.09,103.09,0,0,0,62.52-20.88,104.84,104.84,0,0,0,37-52.91A8,8,0,0,0,233.54,142.23ZM188.9,190.34A88,88,0,0,1,65.66,67.11a89,89,0,0,1,31.4-26A106,106,0,0,0,96,56,104.11,104.11,0,0,0,200,160a106,106,0,0,0,14.92-1.06A89,89,0,0,1,188.9,190.34Z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrapper {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.btn-round {
|
||||
position: relative;
|
||||
|
||||
> svg {
|
||||
width: 1.25em;
|
||||
height: 1.25em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -8,6 +8,7 @@ import SearchMarkers from "./overlay/SearchMarkers.vue";
|
||||
import LangSwitcher from "./overlay/LangSwitcher.vue";
|
||||
import MapOverlayBreadcrumbs from "./MapOverlayBreadcrumbs.astro";
|
||||
import ToastService from "./overlay/ToastService.vue";
|
||||
import ThemeSwitch from "../global/ThemeSwitch.vue";
|
||||
|
||||
interface Props extends MapOverlayProps {}
|
||||
|
||||
@@ -41,9 +42,14 @@ const currentUrl = Astro.url
|
||||
</SearchMarkers>
|
||||
}
|
||||
|
||||
{ENABLE_I18N &&
|
||||
<LangSwitcher currentUrl={currentUrl} client:only="vue" />
|
||||
}
|
||||
|
||||
<div class="right-menu">
|
||||
{ENABLE_I18N &&
|
||||
<LangSwitcher currentUrl={currentUrl} client:only="vue" />
|
||||
}
|
||||
|
||||
<ThemeSwitch client:only="vue" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{ENABLE_BREADCRUMB &&
|
||||
@@ -71,5 +77,15 @@ const currentUrl = Astro.url
|
||||
align-items: top;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.right-menu {
|
||||
display: grid;
|
||||
gap: .5rem;
|
||||
align-content: flex-start;
|
||||
|
||||
@media screen and (width >= 900px) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -14,7 +14,7 @@ const { breadcrumbs = [] } = Astro.props
|
||||
{breadcrumbs.map((breadcrumb, index) => (
|
||||
<li>
|
||||
{index === breadcrumbs.length - 1 &&
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#0f172a" viewBox="0 0 256 256" class="folder"><path d="M245,110.64A16,16,0,0,0,232,104H216V88a16,16,0,0,0-16-16H130.67L102.94,51.2a16.14,16.14,0,0,0-9.6-3.2H40A16,16,0,0,0,24,64V208h0a8,8,0,0,0,8,8H211.1a8,8,0,0,0,7.59-5.47l28.49-85.47A16.05,16.05,0,0,0,245,110.64ZM93.34,64,123.2,86.4A8,8,0,0,0,128,88h72v16H69.77a16,16,0,0,0-15.18,10.94L40,158.7V64Z"></path></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#0f172a" viewBox="0 0 256 256" class="icon folder"><path d="M245,110.64A16,16,0,0,0,232,104H216V88a16,16,0,0,0-16-16H130.67L102.94,51.2a16.14,16.14,0,0,0-9.6-3.2H40A16,16,0,0,0,24,64V208h0a8,8,0,0,0,8,8H211.1a8,8,0,0,0,7.59-5.47l28.49-85.47A16.05,16.05,0,0,0,245,110.64ZM93.34,64,123.2,86.4A8,8,0,0,0,128,88h72v16H69.77a16,16,0,0,0-15.18,10.94L40,158.7V64Z"></path></svg>
|
||||
|
||||
<span class="breadcrumb" aria-current="page">
|
||||
<h1 class="label">
|
||||
@@ -23,7 +23,7 @@ const { breadcrumbs = [] } = Astro.props
|
||||
</span>
|
||||
}
|
||||
{!(index === breadcrumbs.length - 1) &&
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#0f172a" viewBox="0 0 256 256" class="folder"><path d="M216,72H131.31L104,44.69A15.86,15.86,0,0,0,92.69,40H40A16,16,0,0,0,24,56V200.62A15.4,15.4,0,0,0,39.38,216H216.89A15.13,15.13,0,0,0,232,200.89V88A16,16,0,0,0,216,72ZM40,56H92.69l16,16H40ZM216,200H40V88H216Z"></path></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#0f172a" viewBox="0 0 256 256" class="icon folder"><path d="M216,72H131.31L104,44.69A15.86,15.86,0,0,0,92.69,40H40A16,16,0,0,0,24,56V200.62A15.4,15.4,0,0,0,39.38,216H216.89A15.13,15.13,0,0,0,232,200.89V88A16,16,0,0,0,216,72ZM40,56H92.69l16,16H40ZM216,200H40V88H216Z"></path></svg>
|
||||
|
||||
<a href={breadcrumb.url} class="breadcrumb" class:list={{ active: index === breadcrumbs.length - 1 }} data-astro-prefetch="hover">
|
||||
<span class="label">
|
||||
@@ -31,7 +31,7 @@ const { breadcrumbs = [] } = Astro.props
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="#0f172a" viewBox="0 0 256 256"><path d="M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z"></path></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="#0f172a" viewBox="0 0 256 256" class="icon"><path d="M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z"></path></svg>
|
||||
}
|
||||
</li>
|
||||
))}
|
||||
@@ -48,17 +48,25 @@ menu {
|
||||
margin-top: .5rem;
|
||||
padding-block: .25rem;
|
||||
padding-inline: .8rem;
|
||||
border: 1px solid var(--slate-400);
|
||||
background: var(--white);
|
||||
color: var(--foreground);
|
||||
border: 1px solid var(--border);
|
||||
background: var(--background);
|
||||
border-radius: 100vmax;
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
|
||||
pointer-events: all;
|
||||
transition-property: color, background-color, border-color, outline-color;
|
||||
transition-duration: .15s;
|
||||
transition-timing-function: var(--timing-function);
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .25ch;
|
||||
|
||||
svg {
|
||||
fill: var(--foreground);
|
||||
}
|
||||
|
||||
&:has(a:hover, a:focus-visible) {
|
||||
svg.folder {
|
||||
fill: var(--blue-500);
|
||||
@@ -83,7 +91,7 @@ menu {
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 1.1em;
|
||||
fill: var(--foreground);
|
||||
}
|
||||
|
||||
.label {
|
||||
|
||||
@@ -49,7 +49,7 @@ a {
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
background-color: var(--slate-200);
|
||||
background-color: color-mix(in srgb, var(--foreground) 20%, var(--background));
|
||||
}
|
||||
|
||||
&[aria-current="page"] {
|
||||
|
||||
@@ -275,10 +275,11 @@ menu {
|
||||
padding-block: .25rem;
|
||||
top: calc(var(--mouse-y) - .5rem);
|
||||
left: calc(var(--mouse-x) + .75rem);
|
||||
background-color: var(--white);
|
||||
border: 1px solid var(--slate-400);
|
||||
color: var(--foreground);
|
||||
background-color: var(--background);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: .3rem;
|
||||
box-shadow: rgba(0, 0, 0, 0.3) 0px 4px 12px;
|
||||
box-shadow: var(--shadow);
|
||||
z-index: 1000;
|
||||
transition-property: top, left;
|
||||
transition-duration: .16s;
|
||||
@@ -295,13 +296,17 @@ menu {
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
|
||||
svg {
|
||||
fill: var(--foreground);
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus-within {
|
||||
color: var(--blue-700);
|
||||
background-color: var(--slate-100);
|
||||
color: color-mix(in srgb, var(--accent) 90%, var(--background));
|
||||
background-color: color-mix(in srgb, var(--accent) 10%, var(--background));
|
||||
|
||||
svg {
|
||||
fill: var(--blue-700);
|
||||
fill: color-mix(in srgb, var(--accent) 75%, var(--background));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,10 +318,11 @@ dialog {
|
||||
max-width: calc(100% - 6rem);
|
||||
padding: 1.5rem 2rem;
|
||||
z-index: 9999;
|
||||
background-color: var(--white);
|
||||
border: 1px solid var(--slate-400);
|
||||
color: var(--foreground);
|
||||
background-color: var(--background);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: .75rem;
|
||||
box-shadow: rgba(0, 0, 0, 0.3) 0px 4px 12px;
|
||||
box-shadow: var(--shadow);
|
||||
overflow: visible;
|
||||
transform: translateY(1rem);
|
||||
transition: visibility 0s ease-out .3s, opacity .3s ease-out, transform .3s ease-out;
|
||||
|
||||
@@ -94,8 +94,7 @@ const menus: Menu[] = [
|
||||
{
|
||||
name: 'Mines Blanches',
|
||||
img: '/images/aldys-cantane-mines-blanches-cover.png',
|
||||
url: `/${$currentLang.value}/aldys/cantane/mines-blanches`,
|
||||
newItem: true
|
||||
url: `/${$currentLang.value}/aldys/cantane/mines-blanches`
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -213,6 +212,10 @@ const menus: Menu[] = [
|
||||
}
|
||||
}
|
||||
|
||||
.dark .legal::before {
|
||||
content: url('/icon/question-mark-dark.svg');
|
||||
}
|
||||
|
||||
.map-menu {
|
||||
margin-top: .25rem;
|
||||
margin-bottom: .5rem;
|
||||
@@ -251,7 +254,7 @@ const menus: Menu[] = [
|
||||
img {
|
||||
display: block;
|
||||
border-radius: .3rem;
|
||||
border: .1rem solid var(--white);
|
||||
border: .1rem solid var(--background);
|
||||
outline: .15rem solid transparent;
|
||||
}
|
||||
|
||||
@@ -264,14 +267,14 @@ const menus: Menu[] = [
|
||||
pointer-events: none;
|
||||
|
||||
.fill { fill: var(--orange-500); }
|
||||
.stroke { fill: var(--white); }
|
||||
.stroke { fill: var(--background); }
|
||||
}
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: .75em;
|
||||
text-align: center;
|
||||
color: var(--slate-500);
|
||||
color: color-mix(in srgb, var(--foreground) 80%, var(--background));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,11 +308,15 @@ function resetAllFields(actionAfter?: "focusAfter") {
|
||||
margin-left: calc(45px + .5rem);
|
||||
padding: .5rem 1.2rem;
|
||||
width: calc(100% - 3rem);
|
||||
background: var(--white);
|
||||
border: 1px solid var(--slate-400);
|
||||
color: var(--foreground);
|
||||
background: var(--background);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 25px;
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
|
||||
box-shadow: var(--shadow);
|
||||
pointer-events: all;
|
||||
transition-property: color, background-color, border-color, outline-color;
|
||||
transition-duration: .15s;
|
||||
transition-timing-function: var(--timing-function);
|
||||
|
||||
@media screen and (width >= 900px) {
|
||||
width: clamp(25rem, 35dvw, 30rem);
|
||||
@@ -338,7 +342,7 @@ function resetAllFields(actionAfter?: "focusAfter") {
|
||||
flex-grow: 1;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--slate-400);
|
||||
color: color-mix(in srgb, var(--foreground) 75%, var(--background));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +352,7 @@ function resetAllFields(actionAfter?: "focusAfter") {
|
||||
transform: translateY(-50%);
|
||||
left: 0;
|
||||
width: $search-icon-size;
|
||||
fill: var(--slate-400);
|
||||
fill: color-mix(in srgb, var(--foreground) 75%, var(--background));
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@@ -375,16 +379,20 @@ function resetAllFields(actionAfter?: "focusAfter") {
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.icon {
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
&::before {
|
||||
background-color: var(--slate-300);
|
||||
background-color: color-mix(in srgb, var(--foreground) 20%, var(--background));
|
||||
}
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
&::before {
|
||||
background-color: var(--slate-200);
|
||||
outline: 1px dotted var(--slate-500);
|
||||
outline: 4px auto var(--slate-900);
|
||||
background-color: color-mix(in srgb, var(--foreground) 20%, var(--background));
|
||||
outline: 1px dotted color-mix(in srgb, var(--foreground) 50%, var(--background));
|
||||
outline: 4px auto color-mix(in srgb, var(--foreground) 90%, var(--background));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,22 +407,22 @@ function resetAllFields(actionAfter?: "focusAfter") {
|
||||
|
||||
&:hover {
|
||||
&::before {
|
||||
background-color: var(--slate-300);
|
||||
background-color: color-mix(in srgb, var(--foreground) 20%, var(--background));
|
||||
}
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
&::before {
|
||||
background-color: var(--slate-200);
|
||||
outline: 1px dotted var(--slate-500);
|
||||
outline: 4px auto var(--slate-900);
|
||||
background-color: color-mix(in srgb, var(--foreground) 20%, var(--background));
|
||||
outline: 1px dotted color-mix(in srgb, var(--foreground) 50%, var(--background));
|
||||
outline: 4px auto color-mix(in srgb, var(--foreground) 90%, var(--background));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
font-size: 1.1em;
|
||||
color: var(--slate-500);
|
||||
color: color-mix(in srgb, var(--foreground) 75%, var(--background));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,7 +444,7 @@ function resetAllFields(actionAfter?: "focusAfter") {
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-color: var(--slate-300);
|
||||
background-color: color-mix(in srgb, var(--foreground) 30%, var(--background));
|
||||
}
|
||||
|
||||
> * + * {
|
||||
@@ -453,7 +461,7 @@ function resetAllFields(actionAfter?: "focusAfter") {
|
||||
}
|
||||
|
||||
&:hover:not(:has(a:hover)) {
|
||||
background-color: var(--slate-100);
|
||||
background-color: color-mix(in srgb, var(--foreground) 10%, var(--background));
|
||||
|
||||
.title {
|
||||
text-decoration: underline;
|
||||
@@ -490,9 +498,14 @@ function resetAllFields(actionAfter?: "focusAfter") {
|
||||
.title {
|
||||
font-weight: 500;
|
||||
text-underline-offset: 2px;
|
||||
|
||||
& + .desc {
|
||||
margin-top: .25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: var(--slate-500);
|
||||
color: color-mix(in srgb, var(--foreground) 50%, var(--background));
|
||||
|
||||
.map-link {
|
||||
margin-top: .5rem;
|
||||
@@ -528,12 +541,12 @@ function resetAllFields(actionAfter?: "focusAfter") {
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
right: .75rem;
|
||||
fill: var(--slate-400);
|
||||
fill: color-mix(in srgb, var(--foreground) 70%, var(--background));
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 1px dotted var(--slate-500);
|
||||
outline: 4px auto var(--slate-900);
|
||||
outline: 1px dotted color-mix(in srgb, var(--foreground) 50%, var(--background));
|
||||
outline: 4px auto color-mix(in srgb, var(--foreground) 90%, var(--background));
|
||||
|
||||
.title {
|
||||
text-decoration: underline;
|
||||
@@ -600,8 +613,9 @@ function resetAllFields(actionAfter?: "focusAfter") {
|
||||
|
||||
&[data-focused="true"] {
|
||||
margin-bottom: 1em;
|
||||
|
||||
.input-w {
|
||||
border-bottom: 1px solid var(--slate-200);
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--foreground) 20%, var(--background));
|
||||
margin-bottom: .5rem;
|
||||
padding-bottom: .5rem;
|
||||
|
||||
|
||||
@@ -125,10 +125,11 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
||||
padding-inline: .8rem;
|
||||
font-weight: 600;
|
||||
font-size: .85em;
|
||||
background: var(--white);
|
||||
border: 1px solid var(--slate-400);
|
||||
color: var(--foreground);
|
||||
background: var(--background);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 100vmax;
|
||||
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
|
||||
box-shadow: var(--shadow);
|
||||
white-space: nowrap;
|
||||
pointer-events: all;
|
||||
cursor: pointer;
|
||||
@@ -145,6 +146,10 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
||||
width: 1.1em;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: var(--foreground);
|
||||
}
|
||||
|
||||
.label {
|
||||
text-underline-offset: .15rem;
|
||||
}
|
||||
@@ -154,12 +159,12 @@ function emitCategorySwitch(newCategory: MapMarkerGroup) {
|
||||
@each $c in $colors {
|
||||
&.#{$c} {
|
||||
&.active {
|
||||
color: var(--white);
|
||||
color: var(--background);
|
||||
background-color: var(--#{$c}-500);
|
||||
border-color: var(--#{$c}-700);
|
||||
|
||||
.icon {
|
||||
fill: var(--white);
|
||||
fill: var(--background);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,10 @@ export const translations: LanguageDict = {
|
||||
'capitals': 'Capitales',
|
||||
'points-of-interest': 'Points d\'intérêt',
|
||||
'personals': 'Personnels',
|
||||
'nav.aria-label': 'Navigation principale',
|
||||
'nav.aria-label': 'Menu principal',
|
||||
'nav.map.aria-label': 'Changer de carte',
|
||||
'nav.lang.aria-label': 'Changer de langue',
|
||||
'nav.theme.aria-label': 'Changer de thème',
|
||||
'maps.go-to-map': 'Voir la carte détaillée',
|
||||
'maps.go-to-player': 'Aller à la position actuelle des joueurs',
|
||||
'maps.seeQuest': 'Voir la quête',
|
||||
@@ -65,9 +66,10 @@ export const translations: LanguageDict = {
|
||||
'capitals': 'Capitals',
|
||||
'points-of-interest': 'Points of interest',
|
||||
'personals': 'Personals',
|
||||
'nav.aria-label': 'Main navigation',
|
||||
'nav.aria-label': 'Main menu',
|
||||
'nav.map.aria-label': 'Switch map',
|
||||
'nav.lang.aria-label': 'Switch language',
|
||||
'nav.theme.aria-label': 'Switch color theme',
|
||||
'maps.go-to-map': 'See detailed map',
|
||||
'maps.go-to-player': 'Go to current players position',
|
||||
'maps.seeQuest': 'See the quest',
|
||||
|
||||
@@ -16,6 +16,13 @@ const lang = getLangFromUrl(Astro.url) || defaultLang;
|
||||
<!doctype html>
|
||||
<html lang={lang}>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>{title} — Leim Wiki</title>
|
||||
|
||||
<script is:inline src="/leaflet/leaflet.js" />
|
||||
<script is:inline type="text/javascript" src="/js/leaflet-measure.min.js"></script>
|
||||
<script is:inline type="text/javascript" src="/js/leaflet-zoomify.min.js"></script>
|
||||
<script>
|
||||
import { setLang } from "@/i18n/store";
|
||||
import { defaultLang, type Language } from "@/i18n/ui";
|
||||
@@ -25,12 +32,21 @@ const lang = getLangFromUrl(Astro.url) || defaultLang;
|
||||
setLang(currentLang || defaultLang);
|
||||
</script>
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="stylesheet" href="/leaflet/leaflet.css" rel="preload" />
|
||||
<link rel="stylesheet" href="/leaflet-measure/leaflet-measure.css" rel="preload" />
|
||||
|
||||
<meta name="author" content="Alexis Pelé" />
|
||||
{head?.description && <meta name="description" content={head.description} /> }
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta property="og:author" content="Alexis Pelé" />
|
||||
<meta property="og:locale" content={lang}>
|
||||
<meta name="application-name" content="leim-maps">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-config" content="none">
|
||||
|
||||
{head?.description && (
|
||||
<meta name="description" content={head.description} />
|
||||
<meta property="og:description" content={head.description} />
|
||||
)}
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{title} — Leim Wiki</title>
|
||||
|
||||
<link rel="canonical" href={Astro.url}>
|
||||
|
||||
@@ -41,24 +57,68 @@ const lang = getLangFromUrl(Astro.url) || defaultLang;
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#6595b4">
|
||||
<meta name="msapplication-TileColor" content="#00aba9">
|
||||
<meta name="theme-color" content="#a9d1eb">
|
||||
<meta name="color-scheme" content="dark light">
|
||||
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={Astro.url} />
|
||||
{head?.image && <meta property="og:image" content={head.image} />}
|
||||
|
||||
{head?.description && <meta name="twitter:description" content={head.description} /> }
|
||||
{head?.image && <meta property="twitter:image" content={head.image} />}
|
||||
|
||||
<link rel="stylesheet" href="/leaflet/leaflet.css" rel="preload" />
|
||||
<script is:inline src="/leaflet/leaflet.js" />
|
||||
|
||||
<script is:inline type="text/javascript" src="/js/leaflet-zoomify.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/leaflet-measure/leaflet-measure.css" rel="preload" />
|
||||
<script is:inline type="text/javascript" src="/js/leaflet-measure.min.js"></script>
|
||||
{head?.image && (
|
||||
<meta property="og:image" content={`${Astro.site?.origin}${head.image}`} />
|
||||
<meta name="twitter:image" content={`${Astro.site?.origin}${head.image}`} />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
)}
|
||||
</head>
|
||||
<body>
|
||||
<script is:inline>
|
||||
let initialTheme = localStorage.getItem("theme");
|
||||
const darkModeMq = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
|
||||
// Initial paint from localstorage
|
||||
switch (initialTheme) {
|
||||
case "light":
|
||||
enableLightTheme();
|
||||
break;
|
||||
case "system":
|
||||
resetTheme();
|
||||
break;
|
||||
case "dark":
|
||||
default:
|
||||
enableDarkTheme();
|
||||
break;
|
||||
}
|
||||
|
||||
// Enables dark theme and updates preferences
|
||||
function enableDarkTheme() {
|
||||
document.documentElement.classList.add('dark');
|
||||
document.documentElement.classList.remove('light');
|
||||
localStorage.setItem("theme", "dark");
|
||||
}
|
||||
|
||||
// Enables light theme and updates preferences
|
||||
function enableLightTheme() {
|
||||
document.documentElement.classList.add('light');
|
||||
document.documentElement.classList.remove('dark');
|
||||
localStorage.setItem("theme", "light");
|
||||
}
|
||||
|
||||
// Reset theme to OS values
|
||||
function resetTheme() {
|
||||
const prefersDark = darkModeMq.matches;
|
||||
|
||||
if (prefersDark) {
|
||||
document.documentElement.classList.add('dark');
|
||||
document.documentElement.classList.remove('light');
|
||||
} else {
|
||||
document.documentElement.classList.add('light');
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
|
||||
localStorage.setItem("theme", "system");
|
||||
}
|
||||
</script>
|
||||
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -4,7 +4,12 @@ import Map from '@/components/maps/Map.astro'
|
||||
import MapOverlay from '@/components/maps/MapOverlay.astro'
|
||||
---
|
||||
|
||||
<Layout title="Borélis ~ Maps">
|
||||
<Layout
|
||||
title="Borélis ~ Maps"
|
||||
head={{
|
||||
description: "Map of Borélis, a harbour city on the northern shores of the Kaldelium Accord."
|
||||
}}
|
||||
>
|
||||
<MapOverlay
|
||||
mapKey='aldys-borelis'
|
||||
searchConfig={{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
import type { MapMarker, PlayerMarker } from '@/types/Leaflet';
|
||||
import type { MapMarker } from '@/types/Leaflet';
|
||||
|
||||
import Layout from '@/layouts/Layout.astro';
|
||||
import Map from '@/components/maps/Map.astro'
|
||||
@@ -10,7 +10,12 @@ import markersData from '@/components/maps/data/en/aldys/cantane/markers.json'
|
||||
const markers = markersData.data as MapMarker[]
|
||||
---
|
||||
|
||||
<Layout title="Cantane ~ Maps">
|
||||
<Layout
|
||||
title="Cantane ~ Maps"
|
||||
head={{
|
||||
description: "Map of the old city of Cantane, south of the Kaldelium Accord."
|
||||
}}
|
||||
>
|
||||
<MapOverlay
|
||||
mapKey='aldys-cantane'
|
||||
markers={markers}
|
||||
|
||||
@@ -10,7 +10,12 @@ import markersData from '@/components/maps/data/en/aldys/cantane/les-mines-blanc
|
||||
const markers = markersData.data as MapMarker[]
|
||||
---
|
||||
|
||||
<Layout title="White Hollow ~ Maps">
|
||||
<Layout
|
||||
title="White Hollow ~ Maps"
|
||||
head={{
|
||||
description: "Map of the White Hollow mining complex, left abandonned east of Cantane."
|
||||
}}
|
||||
>
|
||||
<MapOverlay
|
||||
mapKey='aldys-cantane-mines'
|
||||
markers={markers}
|
||||
|
||||
@@ -12,7 +12,12 @@ const markers = markersData.data as MapMarker[]
|
||||
const players = playersData as PlayerMarker
|
||||
---
|
||||
|
||||
<Layout title="Bamast ~ Maps">
|
||||
<Layout
|
||||
title="Bamast ~ Maps"
|
||||
head={{
|
||||
description: "Map of the archipelago of Bamast and its many islands in the Balamian Ocean."
|
||||
}}
|
||||
>
|
||||
<MapOverlay
|
||||
mapKey='bamast'
|
||||
markers={markers}
|
||||
|
||||
@@ -16,8 +16,8 @@ const players = playersData as PlayerMarker
|
||||
title="Aldys ~ Maps"
|
||||
head={
|
||||
{
|
||||
description: "Carte de l'Alliance Kaldélienne sur la planète de Léim.",
|
||||
image: '/images/bailey-zindel-NRQV-hBF10M-unsplash.jpg'
|
||||
description: "Map of the Aldys continent on the planet of Léim, displaying the Kaldelium accord and the Common Lands of Syaltha.",
|
||||
image: '/bailey-zindel-NRQV-hBF10M-unsplash.jpg'
|
||||
}
|
||||
}
|
||||
>
|
||||
|
||||
@@ -4,7 +4,12 @@ import Map from '@/components/maps/Map.astro'
|
||||
import MapOverlay from '@/components/maps/MapOverlay.astro'
|
||||
---
|
||||
|
||||
<Layout title="Borélis ~ Cartographie">
|
||||
<Layout
|
||||
title="Borélis ~ Cartographie"
|
||||
head={{
|
||||
description: "Carte de la ville côtière de Borélis, sur les côtes gelées au nord de l'Alliance Kaldélienne."
|
||||
}}
|
||||
>
|
||||
<MapOverlay
|
||||
mapKey='aldys-borelis'
|
||||
searchConfig={{
|
||||
|
||||
@@ -10,7 +10,12 @@ import markersData from '@/components/maps/data/fr/aldys/cantane/markers.json'
|
||||
const markers = markersData.data as MapMarker[]
|
||||
---
|
||||
|
||||
<Layout title="Cantane ~ Cartographie">
|
||||
<Layout
|
||||
title="Cantane ~ Cartographie"
|
||||
head={{
|
||||
description: "Carte de la ville de Cantane, au sud de l'Alliance Kaldélienne."
|
||||
}}
|
||||
>
|
||||
<MapOverlay
|
||||
mapKey='aldys-cantane'
|
||||
markers={markers}
|
||||
|
||||
@@ -10,7 +10,12 @@ import markersData from '@/components/maps/data/fr/aldys/cantane/les-mines-blanc
|
||||
const markers = markersData.data as MapMarker[]
|
||||
---
|
||||
|
||||
<Layout title="Les Mines Blanches ~ Cartographie">
|
||||
<Layout
|
||||
title="Les Mines Blanches ~ Cartographie"
|
||||
head={{
|
||||
description: "Cartographie du complexe des Mines Blanches, laissé à l'abandon à l'est de Cantane."
|
||||
}}
|
||||
>
|
||||
<MapOverlay
|
||||
mapKey='aldys-cantane-mines'
|
||||
markers={markers}
|
||||
|
||||
@@ -12,7 +12,12 @@ const markers = markersData.data as MapMarker[]
|
||||
const players = playersData as PlayerMarker
|
||||
---
|
||||
|
||||
<Layout title="Bamast ~ Cartographie">
|
||||
<Layout
|
||||
title="Bamast ~ Cartographie"
|
||||
head={{
|
||||
description: "Carte de l'Archipel de Bamast et ses nombreuses îles de l'Océan Balamien."
|
||||
}}
|
||||
>
|
||||
<MapOverlay
|
||||
mapKey='bamast'
|
||||
markers={markers}
|
||||
|
||||
@@ -16,8 +16,8 @@ const players = playersData as PlayerMarker
|
||||
title="Aldys ~ Cartographie"
|
||||
head={
|
||||
{
|
||||
description: "Carte de l'Alliance Kaldélienne sur la planète de Léim.",
|
||||
image: '/images/bailey-zindel-NRQV-hBF10M-unsplash.jpg'
|
||||
description: "Carte du continent Aldys sur la planète de Léim, comprenant l'Alliance Kaldélienne et les Terres de Syaltha.",
|
||||
image: '/bailey-zindel-NRQV-hBF10M-unsplash.jpg'
|
||||
}
|
||||
}
|
||||
>
|
||||
|
||||