Merge branch 'refs/heads/astro'

# Conflicts:
#	website/assets/style.css
#	website_astro/src/content/index/rest.md
This commit is contained in:
Zsolt Ero
2024-06-13 15:24:44 +02:00
47 changed files with 2863 additions and 1682 deletions

1
.gitignore vendored
View File

@@ -19,3 +19,4 @@ venv
/pnpm-lock.yaml
/astro_blog

View File

@@ -3,6 +3,16 @@ const config = {
semi: false,
singleQuote: true,
arrowParens: 'avoid',
plugins: ['prettier-plugin-astro'],
overrides: [
{
files: '*.astro',
options: {
parser: 'astro',
},
},
],
}
module.exports = config

View File

@@ -1,5 +1,6 @@
{
"dependencies": {
"prettier": "^3.2.4"
"prettier": "^3.2.4",
"prettier-plugin-astro": "^0.14.0"
}
}

1
website/.gitignore vendored
View File

@@ -1 +0,0 @@
_out

View File

@@ -1,2 +0,0 @@
Run `./generate.py` to create the `_out` folder.
on macOS: `open _out/index.html`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 KiB

View File

@@ -1,50 +0,0 @@
[
{
"price": 10,
"name": "Steel",
"icon": "🗡️",
"lm_url": "af5553c6-f5fe-4253-b5d5-eb5531f8dcdf"
},
{
"price": 20,
"name": "Bronze",
"icon": "🗽",
"lm_url": "9d2b0961-d8d2-4b10-94fc-5d7497baef40"
},
{
"price": 40,
"name": "Copper",
"icon": "🎷",
"lm_url": "76d47d46-9ffa-411c-b6c3-96dd491631bc"
},
{
"price": 75,
"name": "Silver",
"icon": "🍴",
"lm_url": "df45c1e6-49dc-4494-9bdf-071d85e254a5"
},
{
"price": 150,
"name": "Gold",
"icon": "🏆",
"lm_url": "30bf66e8-c9ff-4642-bb39-17a1dfe278f2"
},
{
"price": 250,
"name": "Platinum",
"icon": "🛰",
"lm_url": "c837df35-eb23-4206-a0b5-024a236077cb"
},
{
"price": 500,
"name": "Sapphire",
"icon": "💍",
"lm_url": "5e5f0b42-b885-4bb6-a981-642d1e40d9ac"
},
{
"price": 1000,
"name": "Diamond",
"icon": "👑",
"lm_url": "5c24c85b-cd08-42ff-9515-743e46f3e825"
}
]

View File

@@ -1,384 +0,0 @@
/*
Josh's Custom CSS Reset
https://www.joshwcomeau.com/css/custom-css-reset/
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
* {
margin: 0;
}
img,
picture,
video,
canvas,
svg {
display: block;
max-width: 100%;
}
input,
button,
textarea,
select {
font: inherit;
}
/* normalize.css */
button {
font-family: inherit;
font-size: 100%;
line-height: 1.15;
overflow: visible;
text-transform: none;
-webkit-appearance: button;
}
button::-moz-focus-inner {
border-style: none;
padding: 0;
}
button:-moz-focusring {
outline: 1px dotted ButtonText;
}
/* --- start --- */
body {
padding-bottom: 100px;
line-height: 1.5;
font-size: 17px;
-webkit-font-smoothing: antialiased;
font-family: Avenir, Montserrat, Corbel, 'URW Gothic', source-sans-pro, sans-serif;
font-weight: normal;
color: #000;
}
.static,
h1,
h2,
h3,
h4,
h5,
h6,
.col-lbl,
p,
.button-container,
#support-plans-slider {
margin-left: 40px;
margin-right: 40px;
}
.static {
max-width: 600px;
margin: 0 auto;
}
h1,
h2,
h3,
h4,
h5,
h6,
.col-lbl {
color: #333;
max-width: 600px;
margin: 1em auto 0.5em;
line-height: 1.2;
font-family: Seravek, 'Gill Sans Nova', Ubuntu, Calibri, 'DejaVu Sans', source-sans-pro,
sans-serif;
font-weight: bold;
}
p a {
color: #333;
font-weight: bold;
text-decoration: none;
box-shadow: 0 1px 0 #adc2ee;
transition: box-shadow 200ms ease 0s;
}
p a:hover {
box-shadow: 0 2px 0 #adc2ee;
}
strong {
color: #333;
}
.logo {
margin: 0 auto;
}
.icons {
margin: 0 auto;
width: 80px;
display: flex;
justify-content: space-between;
}
h1 {
text-align: center;
}
/*.subtitle {*/
/* text-align: center;*/
/* font-style: italic;*/
/* color: #333;*/
/* margin-top: 1em;*/
/*}*/
.footer {
max-width: 600px;
margin: 3em auto 0;
display: flex;
justify-content: space-evenly;
}
.footer a {
color: #777;
text-decoration: none;
}
p {
max-width: 600px;
margin: 0 auto 0.6em;
}
pre {
background: #efefef;
font-size: 14px !important;
max-width: 600px;
margin: 0 auto 0.6em !important;
overflow: scroll;
font-weight: bold;
}
code {
font-family: 'Nimbus Mono PS', 'Courier New', monospace !important;
background: #efefef;
}
#map-container {
width: 100%;
height: 500px;
margin-bottom: 24px;
position: relative;
}
#mapbg-image {
width: 100%;
height: 100%;
position: absolute;
z-index: 1;
background-image: url('berlin.webp');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
transition: opacity 3s;
}
.mapbg-attrib {
font:
12px / 20px Helvetica Neue,
Arial,
Helvetica,
sans-serif;
background-color: hsla(0, 0%, 100%, 0.5);
padding: 0 5px;
bottom: 0;
right: 0;
position: absolute;
}
.mapbg-attrib a {
color: rgba(0, 0, 0, 0.75);
text-decoration: none;
}
.mapbg-attrib a:hover {
text-decoration: underline;
}
.btn {
border: 0;
border-radius: 0.25rem;
background: #2f5f8b;
color: white;
font-size: 1rem;
white-space: nowrap;
text-decoration: none;
padding: 0.25rem 0.5rem;
margin-right: 0.5rem;
cursor: pointer;
display: inline-flex;
align-items: center;
}
.btn.selected {
background: #4892d9;
}
.button-container {
margin: 0 auto 0.6em;
max-width: 600px;
display: flex;
flex-wrap: nowrap;
}
.btn:hover {
background: #4892d9;
}
/*button:focus { }*/
/*button:active { }*/
.col-lbl {
display: block;
cursor: pointer;
color: #333;
}
.col-chk {
display: none;
}
.col-lbl:before {
/* Triangle pointing right */
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="0.8em" height="0.8em" viewBox="0 0 180 180" id="U+25B6"><path d="m20,15v150l130-75" fill="%23555"/></svg>');
margin-right: 1em;
}
.col-cnt {
display: none;
margin: 1em 0 2em;
}
.col-chk:checked ~ .col-cnt {
display: block;
}
.col-chk:checked ~ .col-lbl:before {
/* Triangle pointing down */
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="0.8em" height="0.8em" viewBox="0 0 180 180" id="U+25BC"><path d="m90,150 75-130H15" fill="%23555"/></svg>');
}
hr {
border: 0;
height: 1px;
background-color: #555;
margin: 2em 0;
}
#support-plans-slider {
max-width: 600px;
margin: 200px auto 150px;
}
@media (max-width: 550px) {
#support-plans-slider {
max-width: 98%;
margin: 170px auto 120px;
}
}
.noUi-connects {
cursor: pointer;
}
.noUi-value {
line-height: 0;
margin-top: 32px;
font-size: 30px;
transition: font-size 0.3s ease;
cursor: pointer;
}
.noUi-value.active {
font-size: 45px;
}
.noUi-marker-horizontal.noUi-marker-large {
height: 5px;
}
.noUi-marker-horizontal.noUi-marker {
margin-left: 0;
width: 1px;
}
.noUi-tooltip {
border-color: #ccc;
border-radius: 10px;
padding: 10px;
}
.noUi-tooltip.first {
left: 0;
transform: unset;
}
.noUi-tooltip.last {
right: 0;
left: unset;
transform: unset;
}
.plan-name {
font-weight: bold;
margin-bottom: 10px;
}
.plan-link {
display: block;
text-decoration: none;
color: white;
font-weight: bold;
letter-spacing: 0.05rem;
font-size: 15px;
border-radius: 20px;
padding: 6px 16px;
margin-top: 15px;
background: linear-gradient(32deg, #03a9f4, transparent) #f441a5;
transition: background-color 1s;
}
.plan-link:hover,
.plan-link:focus {
background-color: #fdb900;
}
@media (max-width: 550px) {
body {
padding-bottom: 40px;
}
.static,
h1,
h2,
h3,
h4,
h5,
h6,
.col-lbl,
p,
.button-container,
#support-plans-slider {
max-width: 100%;
margin-left: 20px;
margin-right: 20px;
}
#map-container {
height: 300px;
}
}

View File

@@ -1,132 +0,0 @@
<div id="map-container">
<div id="mapbg-image">
<div class="mapbg-attrib">
<a href="https://openfreemap.org" target="_blank">OpenFreeMap</a>
<a href="https://www.openmaptiles.org/" target="_blank">© OpenMapTiles</a> Data from
<a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>
</div>
</div>
</div>
<p>Choose a style:</p>
<div class="button-container">
<button onclick="selectStyle(event, 'positron')" class="btn">Positron</button>
<button onclick="selectStyle(event, 'bright')" class="btn">Bright</button>
<button onclick="selectStyle(event, 'liberty')" class="btn selected">Liberty</button>
<button onclick="selectStyle(event, 'liberty-3d')" class="btn">3D</button>
</div>
<p>Use the following style in a MapLibre map:</p>
<pre><code class="lang-uri" id="style-url-code">https://tiles.openfreemap.org/styles/liberty</code></pre>
<input type="checkbox" id="col1" class="col-chk" />
<label for="col1" class="col-lbl">How to load MapLibre?</label>
<div class="col-cnt">
<p>
Include
<a href="https://maplibre.org/maplibre-gl-js/docs/" target="_blank">MapLibre GL JS</a>
in the <code>&lt;head&gt;</code>. If you are using npm, you can install the
<code>maplibre-gl</code> package. Make sure to import the CSS as well.
</p>
<pre><code class="lang-html">&lt;script src=&quot;https://unpkg.com/maplibre-gl/dist/maplibre-gl.js&quot;&gt;&lt;/script&gt;
&lt;link
href=&quot;https://unpkg.com/maplibre-gl/dist/maplibre-gl.css&quot;
rel=&quot;stylesheet&quot;
/&gt;
</code></pre>
<p>Initialize it to a div like this:</p>
<pre><code class="lang-html">&lt;div id=&quot;map&quot; style=&quot;width: 100%; height: 500px&quot;&gt;&lt;/div&gt;
&lt;script&gt;
const map = new maplibregl.Map({
style: 'https://tiles.openfreemap.org/styles/liberty',
center: [-0.114, 51.506],
zoom: 14.2,
container: 'map'
})
&lt;/script&gt;
</code></pre>
</div>
<div>
<input type="checkbox" id="col2" class="col-chk" />
<label for="col2" class="col-lbl">Using Mapbox?</label>
<div class="col-cnt">
<p>
If you are currently using Mapbox, please change your libraries to
<a href="https://maplibre.org/maplibre-gl-js/docs/" target="_blank">MapLibre GL JS</a>.
MapLibre is based on the last open-source version of Mapbox GL JS before it went
closed-source. Migrating should be as simple as changing the libraries, as long as you are not
using any features specific to the 2.x or later releases.
</p>
</div>
</div>
<div>
<input type="checkbox" id="col3" class="col-chk" />
<label for="col3" class="col-lbl">Using Leaflet?</label>
<div class="col-cnt">
<p>A Leaflet-based snippet is coming soon.</p>
</div>
</div>
<div>
<input type="checkbox" id="col4" class="col-chk" />
<label for="col4" class="col-lbl">Mobile Apps</label>
<div class="col-cnt">
<p>
For mobile apps, you can use the same styles with
<a href="https://maplibre.org/" target="_blank">MapLibre Native</a>.
</p>
</div>
</div>
<div>
<input type="checkbox" id="col6" class="col-chk" />
<label for="col6" class="col-lbl">Custom styles</label>
<div class="col-cnt">
<p>
You can customize the styles using the
<a href="https://maputnik.github.io/" target="_blank">Maputnik</a> editor. For example, you
can remove labels, POIs, or change colors.
</p>
<p>
When you use a customized style, you need to host the style JSON yourself and use its URL in
MapLibre.
</p>
<p>
<a
href="https://maputnik.github.io/editor?style=https://tiles.openfreemap.org/styles/bright"
target="_blank"
>Customize Bright</a
>
</p>
<p>
<a
href="https://maputnik.github.io/editor?style=https://tiles.openfreemap.org/styles/liberty"
target="_blank"
>Customize Liberty</a
>
</p>
<p>
<a
href="https://maputnik.github.io/editor?style=https://tiles.openfreemap.org/styles/positron"
target="_blank"
>Customize Positron</a
>
</p>
</div>
<div>
<input type="checkbox" id="col5" class="col-chk" />
<label for="col5" class="col-lbl">Self-hosting</label>
<div class="col-cnt">
<p>
You can also download our processed planet MBTiles and Btrfs images if you want to self-host
yourself. Details can be found on
<a href="https://github.com/hyperknot/openfreemap" target="_blank">GitHub</a>.
</p>
</div>
</div>
</div>
<div id="pricing"></div>

View File

@@ -1 +0,0 @@
<div id="support-plans-slider"></div>

View File

@@ -1,70 +0,0 @@
#!/usr/bin/env python
import json
import shutil
from pathlib import Path
import marko
OUT_DIR = Path('_out')
ASSETS_DIR = Path('assets')
def generate():
shutil.rmtree(OUT_DIR, ignore_errors=True)
OUT_DIR.mkdir()
template = open('template.html').read()
main_md = open('blocks/main.md').read()
main_html = marko.convert(main_md)
index_html = template.replace('{main}', main_html)
map_howto = open('blocks/map_howto.html').read()
index_html = index_html.replace('<!--map_howto-->', map_howto)
support_plans = open('blocks/support_plans.html').read()
index_html = index_html.replace('<!--support_plans-->', support_plans)
open(OUT_DIR / 'index.html', 'w').write(index_html)
pricing_json = json.load(open('assets/pricing.json'))
support_plans_js = open('assets/support_plans.js').read()
support_plans_js = support_plans_js.replace(
"'__PRICING_JSON__'", json.dumps(pricing_json, ensure_ascii=False)
)
open(OUT_DIR / 'support_plans.js', 'w').write(support_plans_js)
make_static_page('privacy', 'Privacy Policy')
make_static_page('tos', 'Terms of Services')
copy_assets()
def copy_assets():
for file in [
'style.css',
'map_howto.js',
'logo.jpg',
'favicon.ico',
'github.svg',
'x.svg',
'berlin.webp',
]:
shutil.copyfile(ASSETS_DIR / file, OUT_DIR / file)
def make_static_page(page_str, title):
page_md = open(f'blocks/{page_str}.md').read()
page_html = marko.convert(page_md)
template = open('template_static.html').read()
template = template.replace('{main}', page_html)
template = template.replace('{title}', title)
with open(OUT_DIR / f'{page_str}.html', 'w') as fp:
fp.write(template)
if __name__ == '__main__':
generate()

View File

@@ -1,51 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>OpenFreeMap</title>
<meta
name="description"
content="Open and free custom maps for your website and apps, based on OpenStreetMap."
/>
<!-- <meta property="og:title" content="" />-->
<!-- <meta property="og:type" content="" />-->
<!-- <meta property="og:url" content="" />-->
<!-- <meta property="og:image" content="" />-->
<!-- <link rel="icon" href="/favicon.ico" sizes="any" />-->
<link href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css" rel="stylesheet" />
<link href="https://unpkg.com/nouislider@15.7.1/dist/nouislider.min.css" rel="stylesheet" />
<link href="https://unpkg.com/prismjs@1.29.0/themes/prism.min.css" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<img src="logo.jpg" alt="logo" height="200" class="logo" />
<h1>OpenFreeMap</h1>
<div class="icons">
<a href="https://github.com/hyperknot/openfreemap" target="_blank"
><img src="github.svg" alt="github" height="28"
/></a>
<a href="https://x.com/hyperknot" target="_blank"><img src="x.svg" alt="x" height="28" /></a>
</div>
{main}
<div class="footer">
<a href="privacy">Privacy Policy</a>
<a href="tos">Terms of Service</a>
</div>
<script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
<script src="https://unpkg.com/nouislider@15.7.1/dist/nouislider.min.js"></script>
<script src="map_howto.js"></script>
<script src="support_plans.js"></script>
<script src="https://unpkg.com/prismjs@1.29.0/components/prism-core.min.js"></script>
<script src="https://unpkg.com/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
</body>
</html>

View File

@@ -1,13 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{title}</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="static">{main}</div>
</body>
</html>

View File

@@ -1,4 +1,4 @@
import { defineConfig } from 'astro/config';
import { defineConfig } from 'astro/config'
// https://astro.build/config
export default defineConfig({});
export default defineConfig({})

View File

@@ -12,4 +12,4 @@
"dependencies": {
"astro": "^4.10.2"
}
}
}

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 205 KiB

After

Width:  |  Height:  |  Size: 205 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

Before

Width:  |  Height:  |  Size: 749 B

View File

Before

Width:  |  Height:  |  Size: 829 B

After

Width:  |  Height:  |  Size: 829 B

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1,4 +1,54 @@
const pricingList = '__PRICING_JSON__'
const pricingList = [
{
price: 10,
name: 'Steel',
icon: '🗡️',
lm_url: 'af5553c6-f5fe-4253-b5d5-eb5531f8dcdf',
},
{
price: 20,
name: 'Bronze',
icon: '🗽',
lm_url: '9d2b0961-d8d2-4b10-94fc-5d7497baef40',
},
{
price: 40,
name: 'Copper',
icon: '🎷',
lm_url: '76d47d46-9ffa-411c-b6c3-96dd491631bc',
},
{
price: 75,
name: 'Silver',
icon: '🍴',
lm_url: 'df45c1e6-49dc-4494-9bdf-071d85e254a5',
},
{
price: 150,
name: 'Gold',
icon: '🏆',
lm_url: '30bf66e8-c9ff-4642-bb39-17a1dfe278f2',
},
{
price: 250,
name: 'Platinum',
icon: '🛰',
lm_url: 'c837df35-eb23-4206-a0b5-024a236077cb',
},
{
price: 500,
name: 'Sapphire',
icon: '💍',
lm_url: '5e5f0b42-b885-4bb6-a981-642d1e40d9ac',
},
{
price: 1000,
name: 'Diamond',
icon: '👑',
lm_url: '5c24c85b-cd08-42ff-9515-743e46f3e825',
},
]
const priceNumbers = pricingList.map(i => i.price)
const sliderDiv = document.getElementById('support-plans-slider')

View File

@@ -15,7 +15,7 @@ const berlin = {
function initMap() {
if (window.map) return
document.getElementById('mapbg-image').style.opacity = '0.2'
document.getElementById('mapbg-image').style.opacity = '0.5'
const map = new maplibregl.Map({
style: 'https://tiles.openfreemap.org/styles/liberty',
@@ -49,19 +49,7 @@ function initMap() {
new maplibregl.Marker().setLngLat([-0.119, 51.507]).addTo(map)
}
const mapDiv = document.getElementById('map-container')
mapDiv.onclick = function () {
initMap()
}
// initMap()
// let movedTo2d = false
function selectStyle(event, style) {
initMap()
toggleButtonSelection(event.target)
function selectStyle(style) {
const styleUrl = 'https://tiles.openfreemap.org/styles/' + style.split('-')[0]
map.setStyle(styleUrl)
@@ -80,10 +68,19 @@ function selectStyle(event, style) {
document.getElementById('style-url-code').innerText = styleUrl
}
function toggleButtonSelection(clickedButton) {
clickedButton.classList.add('selected')
// --- start
Array.from(clickedButton.parentElement.children)
.filter(child => child !== clickedButton)
.forEach(button => button.classList.remove('selected'))
}
const mapDiv = document.getElementById('map-container')
initMap()
const buttons = document.querySelectorAll('.button-container .btn')
buttons.forEach(button => {
button.addEventListener('click', function (event) {
buttons.forEach(button => button.classList.remove('selected'))
button.classList.add('selected')
const style = event.target.getAttribute('data-style')
selectStyle(style)
})
})

View File

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 348 B

View File

@@ -1,61 +1,61 @@
---
interface Props {
title: string;
body: string;
href: string;
title: string
body: string
href: string
}
const { href, title, body } = Astro.props;
const { href, title, body } = Astro.props
---
<li class="link-card">
<a href={href}>
<h2>
{title}
<span>&rarr;</span>
</h2>
<p>
{body}
</p>
</a>
<a href={href}>
<h2>
{title}
<span>&rarr;</span>
</h2>
<p>
{body}
</p>
</a>
</li>
<style>
.link-card {
list-style: none;
display: flex;
padding: 1px;
background-color: #23262d;
background-image: none;
background-size: 400%;
border-radius: 7px;
background-position: 100%;
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
}
.link-card > a {
width: 100%;
text-decoration: none;
line-height: 1.4;
padding: calc(1.5rem - 1px);
border-radius: 8px;
color: white;
background-color: #23262d;
opacity: 0.8;
}
h2 {
margin: 0;
font-size: 1.25rem;
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
p {
margin-top: 0.5rem;
margin-bottom: 0;
}
.link-card:is(:hover, :focus-within) {
background-position: 0;
background-image: var(--accent-gradient);
}
.link-card:is(:hover, :focus-within) h2 {
color: rgb(var(--accent-light));
}
.link-card {
list-style: none;
display: flex;
padding: 1px;
background-color: #23262d;
background-image: none;
background-size: 400%;
border-radius: 7px;
background-position: 100%;
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
}
.link-card > a {
width: 100%;
text-decoration: none;
line-height: 1.4;
padding: calc(1.5rem - 1px);
border-radius: 8px;
color: white;
background-color: #23262d;
opacity: 0.8;
}
h2 {
margin: 0;
font-size: 1.25rem;
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
p {
margin-top: 0.5rem;
margin-bottom: 0;
}
.link-card:is(:hover, :focus-within) {
background-position: 0;
background-image: var(--accent-gradient);
}
.link-card:is(:hover, :focus-within) h2 {
color: rgb(var(--accent-light));
}
</style>

View File

@@ -0,0 +1,99 @@
---
import { Content as DonateText } from '../content/index/donate.md'
---
<h2>How can I donate or support this project?</h2>
<p>
If this project helps you save on your map hosting costs, please subscribe to one of our support
plans here:
</p>
<div id="support-plans-slider"></div>
<DonateText />
<script is:inline src="https://unpkg.com/nouislider@15.7.1/dist/nouislider.min.js"></script>
<script is:inline src="/scripts/donate.js"></script>
<style>
#support-plans-slider {
max-width: 600px;
margin: 200px auto 150px;
}
@media (max-width: 550px) {
#support-plans-slider {
max-width: 98%;
margin: 170px auto 120px;
}
}
.noUi-connects {
cursor: pointer;
}
.noUi-value {
line-height: 0;
margin-top: 32px;
font-size: 30px;
transition: font-size 0.3s ease;
cursor: pointer;
}
.noUi-value.active {
font-size: 45px;
}
.noUi-marker-horizontal.noUi-marker-large {
height: 5px;
}
.noUi-marker-horizontal.noUi-marker {
margin-left: 0;
width: 1px;
}
.noUi-tooltip {
border-color: #ccc;
border-radius: 10px;
padding: 10px;
}
.noUi-tooltip.first {
left: 0;
transform: unset;
}
.noUi-tooltip.last {
right: 0;
left: unset;
transform: unset;
}
.plan-name {
font-weight: bold;
margin-bottom: 10px;
}
.plan-link {
display: block;
text-decoration: none;
color: white;
font-weight: bold;
letter-spacing: 0.05rem;
font-size: 15px;
border-radius: 20px;
padding: 6px 16px;
margin-top: 15px;
background: linear-gradient(32deg, #03a9f4, transparent) #f441a5;
transition: background-color 1s;
}
.plan-link:hover,
.plan-link:focus {
background-color: #fdb900;
}
</style>

View File

@@ -0,0 +1,31 @@
---
interface Props {
title: string
}
const { title } = Astro.props
---
<img src="/logo.jpg" alt="logo" height="200" class="logo" />
<h1>{title}</h1>
<div class="icons">
<a href="https://github.com/hyperknot/openfreemap" target="_blank"
><img src="/github.svg" alt="github" height="28" /></a
>
<a href="https://x.com/hyperknot" target="_blank"><img src="/x.svg" alt="x" height="28" /></a>
</div>
<style>
.logo {
margin: 0 auto;
}
.icons {
margin: 0 auto;
width: 80px;
display: flex;
justify-content: space-between;
}
</style>

View File

@@ -0,0 +1,100 @@
---
import StyleUrlBug from './StyleUrlBug.astro'
const { showStyleURL } = Astro.props
---
<div id="map-container">
<div id="mapbg-image">
<div class="mapbg-attrib">
<a href="https://openfreemap.org" target="_blank">OpenFreeMap</a>
<a href="https://www.openmaptiles.org/" target="_blank">© OpenMapTiles</a> Data from
<a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>
</div>
</div>
</div>
<div class="button-container">
<button data-style="positron" class="btn">Positron</button>
<button data-style="bright" class="btn">Bright</button>
<button data-style="liberty" class="btn selected">Liberty</button>
<button data-style="liberty-3d" class="btn">3D</button>
</div>
{showStyleURL && <StyleUrlBug />}
<script is:inline src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
<script is:inline src="/scripts/map.js"></script>
<style>
#map-container {
width: 100%;
height: 500px;
margin-bottom: 24px;
position: relative;
}
#mapbg-image {
width: 100%;
height: 100%;
position: absolute;
z-index: 1;
background-image: url('/berlin.webp');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
transition: opacity 3s;
}
.mapbg-attrib {
font:
12px / 20px Helvetica Neue,
Arial,
Helvetica,
sans-serif;
background-color: hsla(0, 0%, 100%, 0.5);
padding: 0 5px;
bottom: 0;
right: 0;
position: absolute;
}
.mapbg-attrib a {
color: rgba(0, 0, 0, 0.75);
text-decoration: none;
}
.mapbg-attrib a:hover {
text-decoration: underline;
}
.button-container {
margin: 0 auto 20px;
max-width: 600px;
display: flex;
flex-wrap: nowrap;
}
.btn {
border: 0;
border-radius: 0.25rem;
background: #2f5f8b;
color: white;
font-size: 1rem;
white-space: nowrap;
text-decoration: none;
padding: 0.25rem 0.5rem;
margin-right: 0.5rem;
cursor: pointer;
display: inline-flex;
align-items: center;
}
.btn.selected {
background: #4892d9;
}
.btn:hover {
background: #4892d9;
}
</style>

View File

@@ -0,0 +1,11 @@
<p>Use the following style in a MapLibre map:</p>
<pre
id="style-url-pre"><code id="style-url-code">https://tiles.openfreemap.org/styles/liberty</code></pre>
<style>
#style-url-pre {
background: #efefef;
padding: 14px;
font-weight: bold;
}
</style>

View File

@@ -0,0 +1,11 @@
## Custom styles
You can customize the styles using the [Maputnik](https://maputnik.github.io/) editor. For example, you can remove labels, POIs, or change colors.
When you use a customized style, you need to host the style JSON yourself and use its URL in MapLibre.
<a href="https://maputnik.github.io/editor?style=https://tiles.openfreemap.org/styles/bright" target="_blank">Customize Bright</a>
<a href="https://maputnik.github.io/editor?style=https://tiles.openfreemap.org/styles/liberty" target="_blank">Customize Liberty</a>
<a href="https://maputnik.github.io/editor?style=https://tiles.openfreemap.org/styles/positron" target="_blank">Customize Positron</a>

View File

@@ -0,0 +1,3 @@
## Using Leaflet?
A Leaflet-based snippet is coming soon.

View File

@@ -0,0 +1,3 @@
## Using Mapbox?
If you are currently using Mapbox, please change your libraries to [MapLibre GL JS](https://maplibre.org/maplibre-gl-js/docs/). MapLibre is based on the last open-source version of Mapbox GL JS before it went closed-source. Migrating should be as simple as changing the libraries, as long as you are not using any features specific to the 2.x or later releases.

View File

@@ -0,0 +1,22 @@
## How to load MapLibre?
Include <a href="https://maplibre.org/maplibre-gl-js/docs/" target="_blank">MapLibre GL JS</a> in the `<head>`. If you are using npm, you can install the `maplibre-gl` package. Make sure to import the CSS as well.
```html
<script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
<link href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css" rel="stylesheet" />
```
Initialize it to a div like this:
```html
<div id="map" style="width: 100%; height: 500px"></div>
<script>
const map = new maplibregl.Map({
style: 'https://tiles.openfreemap.org/styles/liberty',
center: [13.388, 52.517],
zoom: 9.5,
container: 'map',
})
</script>
```

View File

@@ -0,0 +1,3 @@
## Mobile Apps
For mobile apps, you can use the same styles with [MapLibre Native](https://maplibre.org/).

View File

@@ -0,0 +1,3 @@
## Self-hosting
You can also download our processed planet MBTiles and Btrfs images if you want to self-host yourself. Details can be found on [GitHub](https://github.com/hyperknot/openfreemap).

View File

@@ -0,0 +1,7 @@
On **Gold** level and above, we offer personalised technical support by email. Otherwise, support is via GitHub [Discussions](https://github.com/hyperknot/openfreemap/discussions).
If we ever receive a **Diamond** level supporter, we'll put their logo on this page.
When subscribing to a support plan, you receive an invoice for each of your payments.
Note: if you want to make a single donation, feel free to cancel after the first payment. However, please understand that the nature of this project needs recurring donations to cover the server costs.

View File

@@ -1,39 +1,15 @@
## What is OpenFreeMap?
OpenFreeMap provides free map hosting so you can display custom maps on your website and apps.
It is truly **free**: there are no limits on the number of map views or requests you can make, nor on how you use your map. There is no registration page, user database, API keys, or cookies.
It is truly **open-source**: everything, including the full production setup, is on [GitHub](https://github.com/hyperknot/openfreemap). Map data is from OpenStreetMap.
## How can I use it?
(Click below, it's interactive!)
<!--map_howto-->
## How can I donate or support this project?
If this project helps you save on your map hosting costs, please subscribe to one of our support plans here:
<!--support_plans-->
On **Gold** level and above, we offer personalised technical support by email. Otherwise, support is via GitHub [Discussions](https://github.com/hyperknot/openfreemap/discussions).
If we ever receive a **Diamond** level supporter, we'll put their logo on this page.
When subscribing to a support plan, you receive an invoice for each of your payments.
Note: if you want to make a single donation, feel free to cancel after the first payment. However, please understand that the nature of this project needs recurring donations to cover the server costs.
## Is commercial usage allowed?
Yes.
Yes
## Who is behind this project?
## Who is behind this project and how can I follow it?
I'm Zsolt Ero ([X](https://x.com/hyperknot), [blog](https://blog.hyperknot.com/), [email](mailto:zsolt@openfreemap.org)). I built [MapHub](https://maphub.net/) and have been running map hosting in production for 8 years.
X: [hyperknot](https://x.com/hyperknot) and [OpenFreeMapOrg](https://x.com/OpenFreeMapOrg)
GitHub: [openfreemap](https://github.com/hyperknot/openfreemap) and [openfreemap-styles](https://github.com/hyperknot/openfreemap-styles)
## Why did you build this project?
OpenStreetMap is one of the most important collective projects in history. It began 20 years ago, and today, 3 million edits are made each day!
@@ -48,21 +24,15 @@ I'll share more about the reasons in a future [blog post](https://blog.hyperknot
## How can this work? How can a one-person project offer unlimited map hosting for free?
There is no technical reason why map hosting costs as much as it does today. Vector tiles are just static files. Sure, serving 300 million files is not easy, but at the end of the day, they are just files.
There is no technical reason why map hosting costs as much as it does today. Vector tiles are just static files. It's true that serving hundreds of millions of files is not easy, but at the end of the day, they are just files.
Financially, the plan is to keep renting servers until they cover the bandwidth. I believe it can be self-sustainable if enough people subscribe to the support plans.
If this project helps you save on your map hosting costs, please consider subscribing to a support plan.
## How can I follow this project?
X: [hyperknot](https://x.com/hyperknot) and [OpenFreeMapOrg](https://x.com/OpenFreeMapOrg)
GitHub: [openfreemap](https://github.com/hyperknot/openfreemap) and [openfreemap-styles](https://github.com/hyperknot/openfreemap-styles)
## What is the tech stack?
There is no tile server running; only Btrfs partition images with 300 million hard-linked files. This was my idea; I haven't read about anyone else doing this in production, but it works really well. (You can read more about it on [GitHub](https://github.com/hyperknot/openfreemap).
There is no tile server running; only Btrfs partition images with 300 million hard-linked files. This was my idea; I haven't read about anyone else doing this in production, but it works really well. (You can read more about it on [GitHub](https://github.com/hyperknot/openfreemap).)
There is no cloud, just dedicated servers. The HTTPS server is nginx on Ubuntu.
@@ -73,6 +43,7 @@ The [styles](https://github.com/hyperknot/openfreemap-styles) are forked and hea
## Domains
`tiles.openfreemap.org` - Cloudflare proxied
`direct.openfreemap.org` - direct connection, Round-Robin DNS
## Attribution

View File

@@ -0,0 +1,7 @@
## What is OpenFreeMap?
OpenFreeMap provides free map hosting so you can display custom maps on your website and apps.
It is truly **free**: there are no limits on the number of map views or requests you can make, nor on how you use your map. There is no registration page, user database, API keys, or cookies.
It is truly **open-source**: everything, including the full production setup, is on [GitHub](https://github.com/hyperknot/openfreemap). Map data is from OpenStreetMap.

View File

@@ -1 +1,2 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />

View File

@@ -1,51 +1,43 @@
---
interface Props {
title: string;
title: string
}
const { title } = Astro.props;
const { title } = Astro.props
import '../styles/global.css'
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<slot />
</body>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{title}</title>
<meta
name="description"
content="Open and free custom maps for your website and apps, based on OpenStreetMap."
/>
<meta name="generator" content={Astro.generator} />
<link rel="icon" href="/favicon.ico" sizes="any" />
<!-- <meta property="og:title" content="" />-->
<!-- <meta property="og:type" content="" />-->
<!-- <meta property="og:url" content="" />-->
<!-- <meta property="og:image" content="" />-->
<link href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css" rel="stylesheet" />
<link href="https://unpkg.com/nouislider@15.7.1/dist/nouislider.min.css" rel="stylesheet" />
<!--<link href="https://unpkg.com/prismjs@1.29.0/themes/prism.min.css" rel="stylesheet" />-->
</head>
<body>
<slot />
<div class="footer">
<a href="/privacy">Privacy Policy</a>
<a href="/tos">Terms of Service</a>
</div>
</body>
</html>
<style is:global>
:root {
--accent: 136, 58, 234;
--accent-light: 224, 204, 250;
--accent-dark: 49, 10, 101;
--accent-gradient: linear-gradient(
45deg,
rgb(var(--accent)),
rgb(var(--accent-light)) 30%,
white 60%
);
}
html {
font-family: system-ui, sans-serif;
background: #13151a;
background-size: 224px;
}
code {
font-family:
Menlo,
Monaco,
Lucida Console,
Liberation Mono,
DejaVu Sans Mono,
Bitstream Vera Sans Mono,
Courier New,
monospace;
}
</style>

View File

@@ -1,123 +1,29 @@
---
import Layout from '../layouts/Layout.astro';
import Card from '../components/Card.astro';
import Layout from '../layouts/Layout.astro'
import Map from '../components/Map.astro'
import Logo from '../components/Logo.astro'
import Donate from '../components/Donate.astro'
import { Content as WhatisText } from '../content/index/whatis.md'
import { Content as RestText } from '../content/index/rest.md'
---
<Layout title="Welcome to Astro.">
<main>
<svg
class="astro-a"
width="495"
height="623"
viewBox="0 0 495 623"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M167.19 364.254C83.4786 364.254 0 404.819 0 404.819C0 404.819 141.781 19.4876 142.087 18.7291C146.434 7.33701 153.027 0 162.289 0H332.441C341.703 0 348.574 7.33701 352.643 18.7291C352.92 19.5022 494.716 404.819 494.716 404.819C494.716 404.819 426.67 364.254 327.525 364.254L264.41 169.408C262.047 159.985 255.147 153.581 247.358 153.581C239.569 153.581 232.669 159.985 230.306 169.408L167.19 364.254ZM160.869 530.172C160.877 530.18 160.885 530.187 160.894 530.195L160.867 530.181C160.868 530.178 160.868 530.175 160.869 530.172ZM136.218 411.348C124.476 450.467 132.698 504.458 160.869 530.172C160.997 529.696 161.125 529.242 161.248 528.804C161.502 527.907 161.737 527.073 161.917 526.233C165.446 509.895 178.754 499.52 195.577 500.01C211.969 500.487 220.67 508.765 223.202 527.254C224.141 534.12 224.23 541.131 224.319 548.105C224.328 548.834 224.337 549.563 224.347 550.291C224.563 566.098 228.657 580.707 237.264 593.914C245.413 606.426 256.108 615.943 270.749 622.478C270.593 621.952 270.463 621.508 270.35 621.126C270.045 620.086 269.872 619.499 269.685 618.911C258.909 585.935 266.668 563.266 295.344 543.933C298.254 541.971 301.187 540.041 304.12 538.112C310.591 533.854 317.059 529.599 323.279 525.007C345.88 508.329 360.09 486.327 363.431 457.844C364.805 446.148 363.781 434.657 359.848 423.275C358.176 424.287 356.587 425.295 355.042 426.275C351.744 428.366 348.647 430.33 345.382 431.934C303.466 452.507 259.152 455.053 214.03 448.245C184.802 443.834 156.584 436.019 136.218 411.348Z"
fill="url(#paint0_linear_1805_24383)"></path>
<defs>
<linearGradient
id="paint0_linear_1805_24383"
x1="247.358"
y1="0"
x2="247.358"
y2="622.479"
gradientUnits="userSpaceOnUse"
>
<stop stop-opacity="0.9"></stop>
<stop offset="1" stop-opacity="0.2"></stop>
</linearGradient>
</defs>
</svg>
<h1>Welcome to <span class="text-gradient">Astro</span></h1>
<p class="instructions">
To get started, open the directory <code>src/pages</code> in your project.<br />
<strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message above.
</p>
<ul role="list" class="link-card-grid">
<Card
href="https://docs.astro.build/"
title="Documentation"
body="Learn how Astro works and explore the official API docs."
/>
<Card
href="https://astro.build/integrations/"
title="Integrations"
body="Supercharge your project with new frameworks and libraries."
/>
<Card
href="https://astro.build/themes/"
title="Themes"
body="Explore a galaxy of community-built starter themes."
/>
<Card
href="https://astro.build/chat/"
title="Community"
body="Come say hi to our amazing Discord community. ❤️"
/>
</ul>
</main>
<Layout title="OpenFreeMap">
<Logo title="OpenFreeMap" />
<WhatisText />
<h2>How can I use it?</h2>
<Map />
<p>
Have a look at the default styles and read more about how to integrate it to your website or app
here:
</p>
<p style="margin: 20px auto;"><a href="/quick_start">Quick Start Guide</a></p>
<Donate />
<RestText />
<!--<script src="https://unpkg.com/prismjs@1.29.0/components/prism-core.min.js"></script>-->
<!--<script src="https://unpkg.com/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>-->
</Layout>
<style>
main {
margin: auto;
padding: 1rem;
width: 800px;
max-width: calc(100% - 2rem);
color: white;
font-size: 20px;
line-height: 1.6;
}
.astro-a {
position: absolute;
top: -32px;
left: 50%;
transform: translatex(-50%);
width: 220px;
height: auto;
z-index: -1;
}
h1 {
font-size: 4rem;
font-weight: 700;
line-height: 1;
text-align: center;
margin-bottom: 1em;
}
.text-gradient {
background-image: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 400%;
background-position: 0%;
}
.instructions {
margin-bottom: 2rem;
border: 1px solid rgba(var(--accent-light), 25%);
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
padding: 1.5rem;
border-radius: 8px;
}
.instructions code {
font-size: 0.8em;
font-weight: bold;
background: rgba(var(--accent-light), 12%);
color: rgb(var(--accent-light));
border-radius: 4px;
padding: 0.3em 0.4em;
}
.instructions strong {
color: rgb(var(--accent-light));
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 2rem;
padding: 0;
}
</style>

View File

@@ -1,3 +1,8 @@
---
layout: '../layouts/Layout.astro'
title: 'Privacy Policy'
---
# OpenFreeMap and your data
Version: 16th of Jan, 2024

View File

@@ -0,0 +1,68 @@
---
import Layout from '../layouts/Layout.astro'
import Map from '../components/Map.astro'
import { Content as MaplibreText } from '../content/how_to_use/maplibre.md'
import { Content as MapboxText } from '../content/how_to_use/mapbox.md'
import { Content as LeafletText } from '../content/how_to_use/leaflet.md'
import { Content as MobileText } from '../content/how_to_use/mobile.md'
import { Content as CustomStylesText } from '../content/how_to_use/custom_styles.md'
import { Content as SelfHostingText } from '../content/how_to_use/self_hosting.md'
import Logo from '../components/Logo.astro'
---
<Layout title="OpenFreeMap Quick Start Guide">
<Logo title="OpenFreeMap Quick Start Guide" />
<div style="margin-top:30px; margin-bottom: 30px;">
<p>
This guide provides step-by-step instructions for integrating OpenFreeMap into your website or
mobile application.
</p><p>
To get started, choose a style from the default styles provided below. Later, there'll be
options to use custom styles as well.
</p>
<p>(You can navigate the map, it's interactive!)</p>
</div>
<Map showStyleURL={true} />
<MaplibreText />
<MapboxText />
<LeafletText />
<MobileText />
<CustomStylesText />
<SelfHostingText />
</Layout>
<style>
.col-lbl {
display: block;
cursor: pointer;
color: #333;
}
.col-chk {
display: none;
}
.col-lbl:before {
content: '►';
margin-right: 1em;
color: #555;
font-size: 0.8em;
}
.col-cnt {
display: none;
margin: 1em 0 2em;
}
.col-chk:checked ~ .col-cnt {
display: block;
}
.col-chk:checked ~ .col-lbl:before {
content: '▼';
}
</style>

View File

@@ -1,3 +1,8 @@
---
layout: '../layouts/Layout.astro'
title: 'Terms of Services'
---
# TERMS OF SERVICES
Version: 16th of Jan, 2024

View File

@@ -0,0 +1,185 @@
/*
Josh's Custom CSS Reset
https://www.joshwcomeau.com/css/custom-css-reset/
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
* {
margin: 0;
}
img,
picture,
video,
canvas,
svg {
display: block;
max-width: 100%;
}
input,
button,
textarea,
select {
font: inherit;
}
/* normalize.css */
button {
font-family: inherit;
font-size: 100%;
line-height: 1.15;
overflow: visible;
text-transform: none;
-webkit-appearance: button;
}
button::-moz-focus-inner {
border-style: none;
padding: 0;
}
button:-moz-focusring {
outline: 1px dotted ButtonText;
}
/* --- start --- */
body {
padding-bottom: 100px;
line-height: 1.5;
font-size: 17px;
-webkit-font-smoothing: antialiased;
font-family: Avenir, Montserrat, Corbel, 'URW Gothic', source-sans-pro, sans-serif;
font-weight: normal;
color: #000;
}
.static,
h1,
h2,
h3,
h4,
h5,
h6,
.col-lbl,
p,
.button-container,
#support-plans-slider {
margin-left: 40px;
margin-right: 40px;
}
.static {
max-width: 600px;
margin: 0 auto;
}
h1,
h2,
h3,
h4,
h5,
h6,
.col-lbl {
color: #333;
max-width: 600px;
margin: 1em auto 0.5em;
line-height: 1.2;
font-family: Seravek, 'Gill Sans Nova', Ubuntu, Calibri, 'DejaVu Sans', source-sans-pro, sans-serif;
font-weight: bold;
}
p a {
color: #333;
font-weight: bold;
text-decoration: none;
box-shadow: 0 1px 0 #adc2ee;
transition: box-shadow 200ms ease 0s;
}
p a:hover {
box-shadow: 0 2px 0 #adc2ee;
}
strong {
color: #333;
}
h1 {
text-align: center;
}
/*.subtitle {*/
/* text-align: center;*/
/* font-style: italic;*/
/* color: #333;*/
/* margin-top: 1em;*/
/*}*/
.footer {
max-width: 600px;
margin: 3em auto 0;
display: flex;
justify-content: space-evenly;
}
.footer a {
color: #777;
text-decoration: none;
}
p,
ul {
max-width: 600px;
margin: 0 auto 0.6em;
}
pre {
max-width: 600px;
margin: 0 auto 0.6em;
font-size: 14px;
padding: 7px 14px;
}
code {
font-size: 14px;
}
hr {
border: 0;
height: 1px;
background-color: #555;
margin: 2em 0;
}
@media (max-width: 550px) {
body {
padding-bottom: 40px;
}
.static,
h1,
h2,
h3,
h4,
h5,
h6,
.col-lbl,
p,
.button-container,
#support-plans-slider {
max-width: 100%;
margin-left: 20px;
margin-right: 20px;
}
#map-container {
height: 300px;
}
}

View File

@@ -1,3 +1,3 @@
{
"extends": "astro/tsconfigs/base"
"extends": "astro/tsconfigs/base",
}