Compare commits

..

10 Commits

Author SHA1 Message Date
Chandler Swift 74c070215c
Put boring colors last in the list 2024-10-19 20:32:29 -05:00
Chandler Swift 3ca2cd0f7d
Improve layer color UI
- Add color picker
 - Default colorpicker to nice value from list
 - Make sure it doesn't overlap with an already-chosen color
2024-10-19 20:32:16 -05:00
Chandler Swift 54620a68fc
Use hex color format; add color picker input 2024-10-19 20:26:10 -05:00
Chandler Swift 26c5b56d58
Display color next to layer name
This should make it easier to disambiguate layers that are otherwise hard to tell apart.
2024-10-19 19:25:49 -05:00
Chandler Swift 1ad82c55ee
Use predefined color from list to ensure uniqueness 2024-10-19 19:25:49 -05:00
Chandler Swift 502de00933
Add customLayer URL param
This includes a switch to `qs` for querystring parsing, since the
browser builtin won't automatically extract out objects inside arrays.
2024-10-19 19:25:49 -05:00
Chandler Swift 13eb66570a
Warn if custom layer source may not be GeoJSON 2024-10-19 19:10:38 -05:00
Chandler Swift 13855a9a38
Add custom GeoJSON layer functionality 2024-10-19 19:10:38 -05:00
Chandler Swift 35e92304c5
Fix Culvers FOTD URL 2024-10-19 16:19:02 -05:00
Chandler Swift 46735e5c31
Tweak styles: less list padding; limit cursor:pointer 2024-10-19 15:53:48 -05:00
6 changed files with 358 additions and 7 deletions

13
generic-pin.svg 100644
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 384 512"
width="40px"
height="30px"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<path
d="m 384,192 c 0,87.4 -117,243 -168.3,307.2 -12.3,15.3 -35.1,15.3 -47.4,0 C 116.1,435 0,279.4 0,192 0,85.96 85.96,0 192,0 245.96029,0 294.73775,22.275796 329.62577,58.136607 363.27205,92.721042 384,139.94065 384,192 Z"
style="fill:#fff;fill-opacity:1" />
</svg>

After

Width:  |  Height:  |  Size: 667 B

View File

@ -35,7 +35,7 @@ vectorLayer.customPopupCallback = async function(feature) {
fotd_parent.append(fotd_child, fotd_image); fotd_parent.append(fotd_child, fotd_image);
const [long, lat] = toLonLat(feature.getGeometry().getCoordinates()); const [long, lat] = toLonLat(feature.getGeometry().getCoordinates());
const res = await fetch(`https://corsproxy.io/?${encodeURIComponent(`https://www.culvers.com/api/restaurants/getLocations?lat=${lat}&long=${long}&limit=1&t=${Date.now()}`)}`) const res = await fetch(`https://corsproxy.io/?${encodeURIComponent(`https://www.culvers.com/api/locator/getLocations?lat=${lat}&long=${long}&limit=1&t=${Date.now()}`)}`)
const res_data = await res.json(); const res_data = await res.json();
fotd_child.innerHTML = res_data.data.geofences[0].metadata.flavorOfDayName; fotd_child.innerHTML = res_data.data.geofences[0].metadata.flavorOfDayName;
fotd_image.src = `https://cdn.culvers.com/menu-item-detail/${res_data.data.geofences[0].metadata.flavorOfDaySlug}`; fotd_image.src = `https://cdn.culvers.com/menu-item-detail/${res_data.data.geofences[0].metadata.flavorOfDaySlug}`;

125
main.js
View File

@ -11,6 +11,16 @@ import ToggleMenuControl from './ui/controls.js';
import layerCategories from './layers/index.js'; import layerCategories from './layers/index.js';
import VectorLayer from 'ol/layer/Vector';
import {Vector as VectorSource} from 'ol/source.js';
import GeoJSON from 'ol/format/GeoJSON.js';
import {Style} from 'ol/style.js';
import Icon from 'ol/style/Icon.js';
import qs from 'qs';
import pin from './generic-pin.svg?url';
// from https://openlayers.org/en/latest/examples/popup.html // from https://openlayers.org/en/latest/examples/popup.html
const container = document.getElementById('popup'); const container = document.getElementById('popup');
const content = document.getElementById('popup-content'); const content = document.getElementById('popup-content');
@ -119,8 +129,8 @@ for (let category of layerCategories) {
document.querySelector("aside").appendChild(catDiv); document.querySelector("aside").appendChild(catDiv);
} }
const urlParams = new URLSearchParams(window.location.search); const urlParams = qs.parse(window.location.search, { ignoreQueryPrefix: true });
const urlLayers = urlParams.getAll('layer'); const urlLayers = urlParams.layer ?? [];
for (let category of layerCategories) { for (let category of layerCategories) {
for (let layer of category.layers) { for (let layer of category.layers) {
@ -140,6 +150,117 @@ for (let category of layerCategories) {
} }
} }
const customLayerDiv = document.createElement("div");
customLayerDiv.innerHTML = `
<details>
<summary>Custom</summary>
<label>Layer Name: <input type="text"></label><br>
<label>Layer URL: <input type="url"></label><br>
<label>Color (optional): <input type="color" value="#AA5AF0"></label><br>
<button>Add</button>
<small>(must be in GeoJSON format)</small>
<ul></ul>
</details>`;
const labelInput = customLayerDiv.querySelector('input[type=text]');
const sourceInput = customLayerDiv.querySelector('input[type=url]');
const colorInput = customLayerDiv.querySelector('input[type=color]');
customLayerDiv.querySelector("button").addEventListener("click", function(){
if (!sourceInput.value.toLowerCase().endsWith(".geojson")) {
if (!confirm("Input URL doesn't end in .geojson, so is probably not a valid GeoJSON file. Do you want to continue anyway?")) {
return;
}
}
newCustomLayer(labelInput.value, sourceInput.value, colorInput.value.substring(1));
});
document.querySelector("aside").appendChild(customLayerDiv);
// borrowed from https://github.com/ChartsCSS/charts.css/blob/main/src/general/_variables.scss#L7; randomly ordered
let colors = [
[170, 90, 240],
[90, 165, 255],
[100, 210, 80],
[255, 180, 50],
[240, 50, 50],
[130, 50, 20],
[255, 220, 90],
[180, 180, 180],
[170, 150, 110],
[110, 110, 110],
];
let used_colors = [];
// HACK
// TIL that [1,1] != [1,1], since arrays are objects, and objects are equal iff
// they are the same object.
Array.prototype.equals = function(other) {
return this.length == other.length && this.every((e, i) => e === other[i]);
};
function newCustomLayer(name, sourceURL, colorString) {
let color;
if (colorString) {
color = [
parseInt(colorString.substr(0,2),16),
parseInt(colorString.substr(2,2),16),
parseInt(colorString.substr(4,2),16),
];
if (color.length != 3 || color.some(Number.isNaN)) {
alert("Invalid color provided; using random color instead.");
color = null;
}
}
if (!color) {
let available_colors = colors.filter(c => !used_colors.some(i => i.equals(c)));
if (available_colors) {
color = available_colors[0];
} else {
color = [0, 0, 0]; // If we run out of colors, fall back to black
}
}
used_colors.push(color);
const li = document.createElement("li");
const layer = new VectorLayer({
source: new VectorSource({
// In case people put in layers that don't serve proper CORS headers, we
// wrap them in this proxy so they Just Work.
url: `https://corsproxy.io/?${encodeURIComponent(sourceURL)}`,
format: new GeoJSON,
}),
style: new Style({
image: new Icon({
anchor: [0.5, 1],
src: pin,
color: color,
}),
}),
});
li.innerHTML = `
<label><input type="checkbox" checked><div class="color-badge" style="background-color: rgb(${color.join(', ')});"></div> ${name}</label>
`;
li.querySelector("input").addEventListener("change", function(e){
if (e.target.checked) {
map.getLayers().push(layer);
} else {
map.getLayers().remove(layer);
}
});
map.getLayers().push(layer);
customLayerDiv.querySelector("ul").appendChild(li);
// Update input to make sure it's not suggesting an already-used color
let available_colors = colors.filter(c => !used_colors.some(i => i.equals(c)));
available_colors.push([0, 0, 0]); // Ensure we always have at least one color available
document.querySelector('input[type=color]').value = '#' + available_colors[0].map(x => x.toString(16).padStart(2, '0')).join('');
}
if (urlParams.customLayer) {
for (let customLayer of urlParams.customLayer) {
newCustomLayer(customLayer['name'], customLayer['url'], customLayer['color'])
}
}
let location_set = false; let location_set = false;
if (urlLayers.length > 0) { if (urlLayers.length > 0) {

210
package-lock.json generated
View File

@ -11,7 +11,8 @@
"hls.js": "^1.5.2", "hls.js": "^1.5.2",
"ol": "latest", "ol": "latest",
"ol-contextmenu": "^5.3.0", "ol-contextmenu": "^5.3.0",
"proj4": "2.9.0" "proj4": "2.9.0",
"qs": "^6.13.0"
}, },
"devDependencies": { "devDependencies": {
"vite": "^4.3.9" "vite": "^4.3.9"
@ -379,6 +380,25 @@
"resolved": "https://registry.npmjs.org/@types/rbush/-/rbush-3.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/rbush/-/rbush-3.0.4.tgz",
"integrity": "sha512-knSt9cCW8jj1ZSFcFeBZaX++OucmfPxxHiRwTahZfJlnQsek7O0bazTJHWD2RVj9LEoejUYF2de3/stf+QXcXw==" "integrity": "sha512-knSt9cCW8jj1ZSFcFeBZaX++OucmfPxxHiRwTahZfJlnQsek7O0bazTJHWD2RVj9LEoejUYF2de3/stf+QXcXw=="
}, },
"node_modules/call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/color-name": { "node_modules/color-name": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.0.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-2.0.0.tgz",
@ -409,11 +429,49 @@
"resolved": "https://registry.npmjs.org/color-space/-/color-space-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-space/-/color-space-2.0.1.tgz",
"integrity": "sha512-nKqUYlo0vZATVOFHY810BSYjmCARrG7e5R3UE3CQlyjJTvv5kSSmPG1kzm/oDyyqjehM+lW1RnEt9It9GNa5JA==" "integrity": "sha512-nKqUYlo0vZATVOFHY810BSYjmCARrG7e5R3UE3CQlyjJTvv5kSSmPG1kzm/oDyyqjehM+lW1RnEt9It9GNa5JA=="
}, },
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/earcut": { "node_modules/earcut": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz", "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz",
"integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==" "integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg=="
}, },
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"license": "MIT",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.18.20", "version": "0.18.20",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
@ -465,6 +523,15 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0" "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
} }
}, },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/geotiff": { "node_modules/geotiff": {
"version": "2.1.3", "version": "2.1.3",
"resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.1.3.tgz", "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.1.3.tgz",
@ -483,6 +550,85 @@
"node": ">=10.19" "node": ">=10.19"
} }
}, },
"node_modules/get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"license": "MIT",
"dependencies": {
"get-intrinsic": "^1.1.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/hls.js": { "node_modules/hls.js": {
"version": "1.5.15", "version": "1.5.15",
"resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.15.tgz", "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.15.tgz",
@ -516,6 +662,18 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
} }
}, },
"node_modules/object-inspect": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/ol": { "node_modules/ol": {
"version": "10.1.0", "version": "10.1.0",
"resolved": "https://registry.npmjs.org/ol/-/ol-10.1.0.tgz", "resolved": "https://registry.npmjs.org/ol/-/ol-10.1.0.tgz",
@ -618,6 +776,21 @@
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
"integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw=="
}, },
"node_modules/qs": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/quick-lru": { "node_modules/quick-lru": {
"version": "6.1.2", "version": "6.1.2",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz",
@ -666,6 +839,41 @@
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"license": "MIT",
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/side-channel": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/source-map-js": { "node_modules/source-map-js": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",

View File

@ -13,6 +13,7 @@
"hls.js": "^1.5.2", "hls.js": "^1.5.2",
"ol": "latest", "ol": "latest",
"ol-contextmenu": "^5.3.0", "ol-contextmenu": "^5.3.0",
"proj4": "2.9.0" "proj4": "2.9.0",
"qs": "^6.13.0"
} }
} }

View File

@ -60,8 +60,7 @@ aside .close {
display: none; display: none;
} }
aside details { aside details summary {
margin-bottom: 2em;
cursor: pointer; cursor: pointer;
} }
@ -71,6 +70,15 @@ aside summary {
font-weight: bold; font-weight: bold;
} }
.color-badge {
display: inline-block;
height: 1em;
width: 2em;
vertical-align: middle;
border: 1px #444 solid;
border-radius: 4px;
}
@media (max-width: 400px) { @media (max-width: 400px) {
.nav-open #map { .nav-open #map {
left: 100%; left: 100%;