JavaScript must be enabled to play.
Browser lacks capabilities required to play.
Upgrade or switch to another browser.
Loading…
<<set $menuText = setup.text['StoryCaption'][1][setup.i18n.langs[settings.lang]]>> <<set $progressText = setup.text['StoryCaption'][2][setup.i18n.langs[settings.lang]]>> <<set $pointsText = setup.text['StoryCaption'][3][setup.i18n.langs[settings.lang]]>> <<set $pointsMaximum to 600>> <h1>$menuText</h1> <h5>$progressText</h5> <progress @value="$hotspot" max="10"></progress> <<if $isStoryteller>> <h5>$pointsText</h5> <h3>$points / $pointsMaximum</h3> <</if>>
-------------------------SETUP------------------------------- <<set $is_pwa to window.matchMedia('(display-mode: window-controls-overlay)').matches || window.matchMedia('(display-mode: fullscreen)').matches>> <<set $is_safari to navigator.userAgent.indexOf('Safari') > -1 && navigator.userAgent.indexOf('Chrome') <= -1 && navigator.userAgent.indexOf("Edg") <= -1 && navigator.userAgent.indexOf('SamsungBrowser') <= - 1>> <<set $is_chrome to navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf("Edg") <= -1 && navigator.userAgent.indexOf('SamsungBrowser') <= - 1>> -------------------------LANGUAGE------------------------------- <<widget "txt">> <<if ndef _txtCount>> <<set _txtCount = 0>> <</if>> <<if $args.raw === "">> <<set _txtOutput = setup.text[passage()][++_txtCount][setup.i18n.langs[settings.lang]]>> <<if def _txtOutput>> _txtOutput <<else>> <<= setup.text[passage()][_txtCount]["de"]>> <</if>> <<else>> <<set _txtOutput = setup.text[passage()][$args.raw][setup.i18n.langs[settings.lang]]>> <<if def _txtOutput>> _txtOutput <<else>> <<= setup.text[passage()][$args.raw]["de"]>> <</if>> <</if>> <</widget>> -------------------------VIDEO------------------------------- <<widget "video">> <<set $passage = passage()>> <<set $hasHotspot = $args.raw === "">> <<set $storyText = setup.text[passage()][State.variables.hasHotspot ? State.variables.hotspot : 1][setup.i18n.langs[settings.lang]]>> <<script>> const videoText = State.variables.storyText.split('§'); const videoTextDuration = 3000; let counter = 0; let videoTextTimeout; let timerOn = false; function timedVideoText() { if (counter < videoText.length) { document.getElementById("videoText").innerText = videoText[counter]; counter++; videoTextTimeout = setTimeout(timedVideoText, videoTextDuration); } } function startVideoText() { const videoTextElem = document.getElementById("videoText"); if (videoTextElem && !timerOn) { timerOn = true; timedVideoText(); } } function stopVideoText() { clearTimeout(videoTextTimeout); timerOn = false; } $(document).one(":passagedisplay", function() { const video = document.getElementById("video"); if (video) { const videoSource = State.variables.hasHotspot ? `videos/${State.variables.hotspot}.${State.variables.passage}.mp4` : `videos/${State.variables.passage}.mp4`; video.src = videoSource; video.load(); startVideoText(); video.play(); } }); $(document).one(":passageinit", stopVideoText); <</script>> <video autoplay muted id="video" playsinline loop> <source type="video/mp4"> </video> <div class="wrapper"> <p id="videoText"/> </div> <</widget>> <<widget "secret">> <div id="messageContainer" class="message"></div> <<script>> $(document).one(":passagedisplay", function() { const secretMessage = setup.text['secret'][1][setup.i18n.langs[settings.lang]]; const messageContainer = document.getElementById('messageContainer'); let lettersFound = []; State.variables.letter.forEach((isTrue, index) => { if (isTrue) { lettersFound.push(State.variables.runes[index][0]); lettersFound.push(State.variables.runes[index][1]); } }); for (let i = 0; i < secretMessage.length; i++) { const message = document.createElement('h2'); message.textContent = secretMessage[i]; const matchingLetter = lettersFound.find(pair => pair.includes(secretMessage[i].toLowerCase())); if (!secretMessage[i].includes(',','.','`') && !matchingLetter) { message.classList.add('p3'); } messageContainer.appendChild(message); }; }) <</script>> <</widget>> --------------------------AUDIO--------------------------------------- <<cacheaudio "click" "audio/click.mp3">> <<cacheaudio "ring" "audio/ring.mp3">> <<cacheaudio "right" "audio/right.mp3">> <<cacheaudio "wrong" "audio/wrong.mp3">> <<cacheaudio "bg.1" "audio/bg.1.mp3">> <<cacheaudio "bg.2" "audio/bg.2.mp3">> <<createaudiogroup ":bg">> <<track "bg.1">> <<track "bg.2">> <</createaudiogroup>> <<createplaylist "bg">> <<track "bg.1">> <<track "bg.2">> <</createplaylist>> <<script>> postdisplay["setupAudioOnClick"] = function () { const trackId = "click"; $("#story").find("a.link-internal,button.link-internal") .on("click", function () { new Wikifier(null, '<<audio "' + trackId + '" play>>'); }); }; <</script>> -------------------------STARTVARIABLEN------------------------------- <<set $hotspot to 0>> <<set $validFrequences = [101, 247, 404, 721, 333, 121, 911, 451, 143, 666]>> <<set $validGhostFrequences = [201, 723, 447, 304, 521, 656, 133, 421, 890, 667]>> <<set $validOutroFrequence = 999>> <<set $letter to [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]>> <<set $inventory to [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]>> <<set $enteredLocations to []>> <<set $runes to [ ["k", "p"], ["s", "u"], ["m", "l"], ["c", "h"], ["i", "a"], ["b", "f"], ["d", "y"], ["e", "j"], ["g", "r"], ["o", "q"], ["n", "v"], ["t", "w"], ]>> <<set $showMaptip to true>> <<set $setupCompleted to false>> <<set $introCompleted to false>> <<set $points to 0>> <<set $riddleCount to 1>> <<set $riddleCorrectCount to 0>> <<set $secretCorrect to 0>> <<set $isStoryteller to false>> <<set $isScanner to false>> <<set $isNavigator to false>> <<set $isNavigatorScanner to false>> <<set $playerCount to 1>>
<<if $playerCount === 1 || $isScanner || $isNavigatorScanner>> <<set $inventoryText = setup.text['StoryMenu'][1][setup.i18n.langs[settings.lang]]>> <<link [[$inventoryText|"Inventar"]]>><<addclass "#ui-bar" "stowed">><</link>> <</if>> <<set $helpText = setup.text['StoryMenu'][2][setup.i18n.langs[settings.lang]]>> <<link [[$helpText|"Hilfe"]]>><<addclass "#ui-bar" "stowed">><</link>>
<<set $legalText = setup.text['StoryMenu'][3][setup.i18n.langs[settings.lang]]>> <<link [[$legalText|"Impressum"]]>><<addclass "#ui-bar" "stowed">><</link>> <<set $legalText = setup.text['StoryMenu'][4][setup.i18n.langs[settings.lang]]>> <<link [[$legalText|"About"]]>><<addclass "#ui-bar" "stowed">><</link>> <<set $shortcutText = setup.text['StoryMenu'][5][setup.i18n.langs[settings.lang]]>> <<link [[$shortcutText|"Dev"]]>><<addclass "#ui-bar" "stowed">><<goto "Dev">><</link>>
<<script>> if (State.variables.is_pwa) { $.wiki('<<goto "setup.player">>') }; $('#story').attr('style', 'background-image:url(images/bg.jpg)'); window.addEventListener('beforeinstallprompt', (event) => { event.preventDefault(); /* console.log('👍', 'beforeinstallprompt', event); */ window.deferredPrompt = event; }); <</script>> <div class="wrapper"> <h1>Spook Tours</h1> <h2><<txt>></h2> <p class="p3">spui</p> </div> <div class="btn-group"> <button class="next">[[|setup.browsercheck]]</button> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); if (State.variables.is_safari || State.variables.is_chrome) { $.wiki('<<goto "setup.installation">>') }; <</script>> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> </div>
<<script>> $(document).one(":passagedisplay", function() { $('#story').attr('style', 'background-image:url(images/bg.jpg)'); const installBtn = document.querySelector('.install'); const iosHelp = document.querySelector('.iosHelp'); const androidHelp = document.querySelector('.androidHelp'); if (State.variables.is_safari) { installBtn.style.display = 'none'; androidHelp.style.display = 'none'; } else if (State.variables.is_chrome) { iosHelp.style.display = 'none'; }; installBtn.addEventListener('click', async () => { /* console.log('👍', 'installBtn-clicked'); */ const promptEvent = window.deferredPrompt; if (!promptEvent) { /* The deferred prompt isn't available. */ return; } /* Show the install prompt. */ promptEvent.prompt(); /* Log the result */ const result = await promptEvent.userChoice; /* console.log('👍', 'userChoice', result); */ /* Reset the deferred prompt variable, since */ /* prompt() can only be called once. */ window.deferredPrompt = null; }); window.addEventListener('appinstalled', (event) => { window.deferredPrompt = null; installBtn.style.display = 'none'; }); }); <</script>> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> <h2 class="iosHelp"><<txt>><img height="64" width="64" src="images/ios_share.svg" /><<txt>></h2> <h2 class="androidHelp"><<txt>><img src="images/android_install.svg" /><<txt>></h2> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="return">[[|setup.init]]</button> <button class="retry">[[|passage()]]</button> <button class="install"></button> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/setup.splash.jpg)'); <</script>> <div class="wrapper"> <br> <br> <br> <br> <br> <br> <br> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="next">[[|setup.music]]</button> </div>
<<playlist "bg" volume 0 fadeto 0.3>> <<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); <</script>> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|intro.2]]</button> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); <</script>> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> </div> <div class="btn-group"> <<button 1>> <<set $playerCount = 1>> <<set $isStoryteller = true>> <<goto "setup.location">> <</button>> <<button 2>> <<set $playerCount = 2>> <<goto "setup.storyteller">> <</button>> <<button 3>> <<set $playerCount = 3>> <<goto "setup.storyteller">> <</button>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/setup.storyteller.jpg)'); <</script>> <div class="wrapper"> <h1><<txt>></h1> </div> <div class="btn-group"> <h2><<txt>></h2> <button class="return">[[|setup.player]]</button> <<button OK>> <<set $isStoryteller = true>> <<script>> jQuery(Dialog .setup(setup.text[passage()][1][setup.i18n.langs[settings.lang]])) .append("<p>".concat(setup.text[passage()][3][setup.i18n.langs[settings.lang]],'</p><ul class="buttons">')+'<li><button id="restart-ok">' .concat(L10n.get(["restartOk","ok"]),"</button></li>")+'<li><button id="restart-cancel" class="ui-close">' .concat(L10n.get(["restartCancel","cancel"]),"</button></li>")+"</ul>") .find("#restart-ok") .ariaClick({one:!0},(function(){jQuery(document).one(":dialogclosed",(function(){return $.wiki('<<goto "intro.init" >>');})),Dialog.close()}) ),!0; Dialog.open(); <</script>> <</button>> <button class="next">[[|setup.navigator]]</button> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/setup.navigator.jpg)'); <</script>> <div class="wrapper"> <<if $playerCount === 2>> <h1><<txt 1>></h1> <<elseif $playerCount === 3>> <h1><<txt 3>></h1> <</if>> </div> <div class="btn-group"> <<if $playerCount === 2>> <h2><<txt 2>></h2> <<elseif $playerCount === 3>> <h2><<txt 4>></h2> <</if>> <button class="return">[[|setup.storyteller]]</button> <<button OK>> <<if $playerCount === 2>> <<set $isNavigatorScanner = true>> <<elseif $playerCount === 3>> <<set $isNavigator = true>> <</if>> <<script>> jQuery(Dialog .setup(setup.text[passage()][3][setup.i18n.langs[settings.lang]])) .append("<p>".concat(setup.text[passage()][5][setup.i18n.langs[settings.lang]],'</p><ul class="buttons">')+'<li><button id="restart-ok">' .concat(L10n.get(["restartOk","ok"]),"</button></li>")+'<li><button id="restart-cancel" class="ui-close">' .concat(L10n.get(["restartCancel","cancel"]),"</button></li>")+"</ul>") .find("#restart-ok") .ariaClick({one:!0},(function(){jQuery(document).one(":dialogclosed",(function(){return $.wiki('<<goto "setup.location" >>');})),Dialog.close()}) ),!0; Dialog.open(); <</script>> <</button>> <<if $playerCount === 3>> <button class="next">[[|setup.scanner]]</button> <<else>> <button class="next">[[|setup.storyteller]]</button> <</if>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/setup.scanner.jpg)'); <</script>> <div class="wrapper"> <h1><<txt>></h1> </div> <div class="btn-group"> <h2><<txt>></h2> <button class="return">[[|setup.navigator]]</button> <<button OK>> <<set $isScanner = true>> <<script>> jQuery(Dialog .setup(setup.text[passage()][1][setup.i18n.langs[settings.lang]])) .append("<p>".concat(setup.text[passage()][3][setup.i18n.langs[settings.lang]],'</p><ul class="buttons">')+'<li><button id="restart-ok">' .concat(L10n.get(["restartOk","ok"]),"</button></li>")+'<li><button id="restart-cancel" class="ui-close">' .concat(L10n.get(["restartCancel","cancel"]),"</button></li>")+"</ul>") .find("#restart-ok") .ariaClick({one:!0},(function(){jQuery(document).one(":dialogclosed",(function(){return $.wiki('<<goto "setup.camera" >>');})),Dialog.close()}) ),!0; Dialog.open(); <</script>> <</button>> <button class="next">[[|setup.storyteller]]</button> </div>
<div id="map"></div> <div class="wrapper"> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="geolocation"><<txt>></button> <button class="settings"><a href="x-apple.systempreferences:com.apple.preference.security?Privacy_LocationServices"><<txt>></a></button> <button class="help"></button> <button class="retry">[[|passage()]]</button> <<if $isNavigator>> <button class="next">[[|main.navigator.init]]</button> <<else>> <button class="next">[[|setup.camera]]</button> <</if>> </div> <<script>> $(document).one(":passagedisplay", function() { requestScriptLoad({ id : 'lib-mapbox-js', src : 'https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.js', onload : function (evt) { mapboxgl.accessToken = getAccessToken(); const map = new mapboxgl.Map({ container: 'map', style: getStyle() }); const geolocate = new mapboxgl.GeolocateControl(window.geolocation.getGeolocateControl()); map.addControl(geolocate); map.resize(); } }); const geolocationBtn = document.querySelector('.geolocation'); const settingsBtn = document.querySelector('.settings'); const helpBtn = document.querySelector('.help'); const nextBtn = document.querySelector('.next'); settingsBtn.style.display = 'none'; helpBtn.style.display = 'none'; nextBtn.style.display = 'none'; /* Create success callback to store values */ const positionSuccess = function(pos) { /* console.log('👍', 'Geolocation prompt successful', pos.coords); */ $(".mapboxgl-ctrl-geolocate").click(); geolocationBtn.style.display = 'none'; nextBtn.style.display = 'inline'; }; /* Create error callback */ const positionError = function(error) { alert('Bitte gib deinen Standort in den Systemeinstellungen frei'); if (State.variables.is_safari) { settingsBtn.style.display = 'inline'; } helpBtn.style.display = 'inline'; }; /* Create initial options */ const positionOptions = { enableHighAccuracy: false, maximumAge: 30000, timeout: 20000 }; function askGeolocationPermission() { navigator.permissions.query({name:'geolocation'}).then(function(result) { if (result.state == 'granted') { /* console.log('👍', 'Geolocation permission granted'); */ $(".mapboxgl-ctrl-geolocate").click(); geolocationBtn.style.display = 'none'; nextBtn.style.display = 'inline'; } else if (result.state == 'prompt') { /* Ask for location based on callbacks and options */ navigator.geolocation.getCurrentPosition(positionSuccess, positionError, positionOptions); } else if (result.state == 'denied') { helpBtn.style.display = 'inline'; } }); }; geolocationBtn.onclick = function() { if(window.geolocation.available()) { askGeolocationPermission(); } }; }); <</script>>
<<script>> $(document).one(":passagedisplay", function() { $('#story').attr('style', 'background-image:url(images/bg.jpg)'); const helpBtn = document.querySelector('.help'); helpBtn.style.display = 'none'; const nextBtn = document.querySelector('.next'); nextBtn.style.display = 'none'; const arBtn = document.querySelector('#ar-button'); arBtn.addEventListener('click', async () => { nextBtn.style.display = 'inline'; }); }); <</script>> <<set $setupCompleted to true>> <div class="wrapper"> <model-viewer id="model-viewer" ar auto-rotate src="models/setup/setup.camera.glb" ios-src="models/setup/setup.camera.usdz" poster="models/setup/setup.camera.webp" autoplay shadow-intensity="2" shadow-softness="0" camera-controls> <button slot="ar-button" id="ar-button"><<txt>></button> </model-viewer> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="help"></button> <button class="retry">[[|passage()]]</button> <<if $isNavigatorScanner>> <button class="next">[[|main.navigator]]</button> <<elseif $isScanner>> <button class="next">[[|main.scanner.init]]</button> <<else>> <button class="next">[[|intro.init]]</button> <</if>> </div>
<<audio ":playing:not(:bg)" stop>> <<if $setupCompleted and $introCompleted>> <<goto "main.storyteller">> <<else>> <<goto "intro.welcome">> <</if>>
<div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> <<if $playerCount === 2>> <h2><<txt 3>></h2> <<elseif $playerCount === 3>> <h2><<txt 4>></h2> <</if>> <h2><<txt 5>></h2> <h2><<txt 6>></h2> </div> <div class="btn-group"> <button class="help">[[|Hilfe]]</button> <button class="retry">[[|passage()]]</button> <button class="next">[[|intro.1]]</button> </div>
<script> $('#story').attr('style', 'background-image:url(images/intro.1.jpg)'); </script> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="return">[[|intro.welcome]]</button> <button class="retry">[[|passage()]]</button> <button class="next">[[|setup.music]]</button> </div>
<<audio ":playing:not(:bg)" stop>> <<video noHotspot>> <div class="btn-group"> <button class="return">[[|intro.1]]</button> <button class="retry">[[|passage()]]</button> <button class="next">[[|intro.3]]</button> </div>
<<audio "ring" play loop>> <script> $('#story').attr('style', 'background-image:url(images/intro.3.jpg)'); </script> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> <img src="images/holger.png" class="image-size-50" /> </div> <div class="btn-group"> <button class="return">[[|intro.2]]</button> <button class="retry">[[|passage()]]</button> <button class="next">[[|intro.4]]</button> </div>
<<audio ":playing:not(:bg)" stop>> <<video noHotspot>> <div class="btn-group"> <button class="return">[[|intro.3]]</button> <button class="retry">[[|passage()]]</button> <button class="next">[[|intro.5]]</button> </div>
<<video noHotspot>> <div class="btn-group"> <button class="return">[[|intro.4]]</button> <button class="retry">[[|passage()]]</button> <button class="next">[[|intro.6]]</button> </div>
<script> $('#story').attr('style', 'background-image:url(images/intro.6.jpg)'); </script> <div class="wrapper"> <h1><<txt>></h1> <br/> <<secret>> </div> <div class="btn-group"> <button class="return">[[|intro.5]]</button> <button class="retry">[[|passage()]]</button> <button class="next">[[|intro.7]]</button> </div>
<<video noHotspot>> <div class="btn-group"> <button class="return">[[|intro.6]]</button> <button class="retry">[[|passage()]]</button> <button class="next">[[|intro.8]]</button> </div>
<<set $introCompleted to true>> <<video noHotspot>> <div class="btn-group"> <button class="return">[[|intro.7]]</button> <button class="retry">[[|passage()]]</button> <<if $playerCount === 1>> <button class="next">[[|main.navigator]]</button> <<else>> <button class="next">[[|main.storyteller]]</button> <</if>> </div>
<div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|main.navigator]]</button> </div>
<div id="map"></div> <<audio ":playing:not(:bg)" stop>> <<script>> $(document).one(":passagedisplay", function() { requestScriptLoad({ id : 'lib-mapbox-js', src : 'https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.js', onload : function (evt) { mapboxgl.accessToken = getAccessToken(); const map = new mapboxgl.Map({ container: 'map', style: getStyle(), }); const geolocate = new mapboxgl.GeolocateControl(window.geolocation.getGeolocateControl()); map.addControl(geolocate); const locations = getLocations(); const remainingLocations = locations.filter(loc => !State.variables.enteredLocations.includes(loc.id)); const clickEventAdded = {}; geolocate.on('geolocate', ({ coords }) => { const lat = coords.latitude; const lon = coords.longitude; for (const location of remainingLocations) { if (window.geolocation.inside(location.latitude, location.longitude, location.radius, lat, lon)) { map.setPaintProperty(location.id, 'fill-color', '#9CF299'); if (!clickEventAdded[location.id]) { map.on('click', location.id, (e) => { State.variables.enteredLocations.push(location.id); $.wiki('<<set $hotspot++>>'); if (State.variables.isStoryteller) { $.wiki('<<goto "hotspot.splash">>'); } else { $.wiki('<<goto "hotspot.frequence">>'); } }); clickEventAdded[location.id] = true; } } else { map.setPaintProperty(location.id, 'fill-color', '#F299CA'); clickEventAdded[location.id] = false; } } }); map.on('load', () => { renderMap(); $(".mapboxgl-ctrl-geolocate").click(); }); function renderMap() { map.resize(); for (const location of remainingLocations) { map.addSource( location.id, window.geolocation.createGeoJSONCircle([ location.longitude, location.latitude], location.radius / 1000)); map.addLayer({ 'id': location.id, 'type': 'fill', 'source': location.id, 'paint': { 'fill-color': 'black', 'fill-opacity': 0.7 } }); } }; } }); }); <</script>> <div class="wrapper" style="z-index: unset"></div> <div class="btn-group"> <<if $showMaptip>> <span id="mapTip"> <<if $playerCount === 1>> <h2><<txt 2>></h2> <<button "OK">> <<replace "#mapTip">> <h2><<txt 3>></h2> <</replace>> <<set $showMaptip to false>> <</button>> <<else>> <h2><<txt>></h2> <<button "OK">> <<replace "#mapTip">> <h2><<txt>></h2> <<button "OK">> <<replace "#mapTip">> <h2><<txt>></h2> <</replace>> <</button>> <</replace>> <<set $showMaptip to false>> <</button>> <</if>> </span> <<else>> <<button "?">> <<set $showMaptip to true>> <<goto "main.navigator">> <</button>> <</if>> <button class="retry">[[|passage()]]</button> </div>
<<audio ":playing:not(:bg)" stop>> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|main.scanner]]</button> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/setup.scanner.jpg)'); <</script>> <<audio ":playing:not(:bg)" stop>> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> </div> <div class="btn-group"> <<if $hotspot >= 1>> <button class="return">[[|hotspot.ghost]]</button> <</if>> <<numberbox "_answer" 0>> <<button "Check">> <<if _answer is "">> <<script>>UI.alert(setup.text[passage()][3][setup.i18n.langs[settings.lang]]);<</script>> <<elseif $validFrequences.includes(_answer)>> <<set $hotspot = $validFrequences.indexOf(_answer) + 1>> <<goto "hotspot.ar">> <<else>> <<script>>UI.alert(setup.text[passage()][4][setup.i18n.langs[settings.lang]]);<</script>> <<goto "main.scanner">> <</if>> <</button>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/setup.scanner.jpg)'); <</script>> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="return">[[|hotspot.ar]]</button> <<numberbox "_answer" 0>> <<button "Check">> <<if _answer is "">> <<script>>UI.alert(setup.text[passage()][3][setup.i18n.langs[settings.lang]]);<</script>> <<elseif $validGhostFrequences.includes(_answer)>> <<set $hotspot = $validGhostFrequences.indexOf(_answer) + 1>> <<goto "hotspot.ghost">> <<else>> <<script>>UI.alert(setup.text[passage()][4][setup.i18n.langs[settings.lang]]);<</script>> <<goto "main.scanner.ghost">> <</if>> <</button>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/setup.storyteller.jpg)'); <</script>> <div class="wrapper"> <h1><<txt>></h1> </div> <div class="btn-group"> <h2><<txt>></h2> <<numberbox "_answer" 0 autofocus>> <<button "Check">> <<if _answer is "">> <<script>>UI.alert(setup.text[passage()][3][setup.i18n.langs[settings.lang]]);<</script>> <<elseif $validFrequences.includes(_answer)>> <<script>>UI.alert(setup.text[passage()][4][setup.i18n.langs[settings.lang]]);<</script>> <<set $hotspot = $validFrequences.indexOf(_answer) + 1>> <<goto "hotspot.splash">> <<else>> <<script>>UI.alert(setup.text[passage()][5][setup.i18n.langs[settings.lang]]);<</script>> <<goto "main.storyteller">> <</if>> <</button>> </div>
<<audio "ring" play loop>> <<script>> $('#story').attr('style', `background-image:url(images/hotspot.splash.jpg)`); <</script>> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> <img src="images/holger.png" class="image-size-50"> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|hotspot.intro]]</button> </div>
<<audio ":playing:not(:bg)" stop>> <<video>> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <<if $isNavigator>> <button class="next">[[|hotspot.frequence]]</button> <<elseif $isNavigatorScanner>> <button class="next">[[|hotspot.frequence]]</button> <<elseif $isScanner>> <button class="next">[[|hotspot.ar]]</button> <<elseif $playerCount === 1>> <button class="next">[[|hotspot.ar]]</button> <<else>> <<button OK>> <<script>> jQuery(Dialog .setup(setup.text[passage()][11][setup.i18n.langs[settings.lang]])) .append("<p>".concat(setup.text[passage()][12][setup.i18n.langs[settings.lang]],'</p><ul class="buttons">')+'<li><button id="restart-ok">' .concat(L10n.get(["restartOk","ok"]),"</button></li>")+'<li><button id="restart-cancel" class="ui-close">' .concat(L10n.get(["restartCancel","cancel"]),"</button></li>")+"</ul>") .find("#restart-ok") .ariaClick({one:!0},(function(){jQuery(document).one(":dialogclosed",(function(){return $.wiki('<<goto "hotspot.questions" >>');})),Dialog.close()}) ),!0; Dialog.open(); <</script>> <</button>> <</if>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); <</script>> <div class="wrapper"> <h1><<print $validFrequences[$hotspot-1]>></h1> <h2><<txt 1>></h2> <h2><<txt 2>></h2> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <<if $isNavigator>> <<set $riddleCount to 1>> <button class="next">[[|hotspot.questions]]</button> <<elseif $isNavigatorScanner>> <button class="next">[[|hotspot.ar]]</button> <</if>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); <</script>> <div class="wrapper"> <h1><<print $validGhostFrequences[$hotspot-1]>></h1> <h2><<txt 1>></h2> <h2><<txt 2>></h2> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|hotspot.rune]]</button> </div>
<script> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); </script> <<if $riddleCount <= 5>> <<set _riddles = getRiddles();>> <<set _riddle = _riddles[$hotspot - 1][$riddleCount - 1]>> <<set _question = _riddle.question[setup.i18n.langs[settings.lang]]>> <<set _answers = _riddle.answers>> <div class="wrapper"> <span id="heading"> <<if $isStoryteller and $playerCount === 3>> <<set $countdown = setup.text[passage()][8][setup.i18n.langs[settings.lang]]>> <<set $seconds to 30>> <h1 id="countdown">$seconds $countdown</h1> <h2><<txt 6>>$riddleCount</h2> <h2><<txt 7>></h2> <<silently>> <<repeat 1s>> <<set $seconds to $seconds - 1>> <<if $seconds gt 0>> <<replace "#countdown">>$seconds $countdown<</replace>> <<else>> <<replace "#countdown">><</replace>> <<set $riddleCount to $riddleCount + 1>> <<goto "hotspot.questions">> <<stop>> <</if>> <</repeat>> <</silently>> <<else>> <h1><<txt 1>> $riddleCount</h1> <h2>_question</h2> <</if>> </span> </div> <div class="btn-group"> <<if $isNavigator>> <<script>> $(document).one(":passagedisplay", function() { $('<button class="return" tabindex="0"><a class="link-internal" role="link" tabindex="0"></a></button>') .ariaClick((function(){return $.wiki('<<if $riddleCount === 2>><<goto "hotspot.frequence">><<else>><<set $riddleCount to $riddleCount - 2>><<goto "hotspot.questions">><</if>>');})) .prependTo('.btn-group'); }) <</script>> <<set $riddleCount to $riddleCount + 1>> <button class="next">[[|hotspot.questions]]</button> <<else>> <<set $resultTextCorrect = setup.text[passage()][2][setup.i18n.langs[settings.lang]]>> <<set $resultTextIncorrect = setup.text[passage()][3][setup.i18n.langs[settings.lang]]>> <<set $pointsTextCorrect = setup.text[passage()][4][setup.i18n.langs[settings.lang]]>> <<set $pointsTextIncorrect = setup.text[passage()][5][setup.i18n.langs[settings.lang]]>> <<for _data range _answers>> <<capture _data>> <<button _data[setup.i18n.langs[settings.lang]]>> <<set _resultText = _data.correct ? $resultTextCorrect : $resultTextIncorrect>> <<set _points = _data.points > 0 ? "+" + _data.points + $pointsTextCorrect : $pointsTextIncorrect>> <<replace "#heading">> <h1>_resultText</h1> <h2>_points</h2> <</replace>> <<timed 1s>> <<set $points to $points + _data.points>> <<set $riddleCount to $riddleCount + 1>> <<set $riddleCorrectCount = _data.correct && $riddleCorrectCount + 1 >> <<goto "hotspot.questions">> <</timed>> <</button>> <</capture>> <</for>> <</if>> </div> <<else>> <<if $isNavigator>> <<script>> jQuery(Dialog .setup(setup.text[passage()][9][setup.i18n.langs[settings.lang]])) .append("<p>".concat(setup.text[passage()][10][setup.i18n.langs[settings.lang]],'</p><ul class="buttons">')+'<li><button id="restart-ok">' .concat(L10n.get(["restartOk","ok"]),"</button></li>")+'<li><button id="restart-cancel" class="ui-close">' .concat(L10n.get(["restartCancel","cancel"]),"</button></li>")+"</ul>") .find("#restart-ok") .ariaClick({one:!0},(function(){jQuery(document).one(":dialogclosed",(function(){return $.wiki('<<if $hotspot === 10>><<goto "outro.navigator.init">><<else>><<goto "main.navigator">><</if>>');})),Dialog.close()})),!0; $("#restart-cancel") .ariaClick({one:!0},(function(){jQuery(document).one(":dialogclosed",(function(){return $.wiki('<<set $riddleCount to $riddleCount - 1>><<goto "hotspot.questions" >>');})),Dialog.close()})),!0; Dialog.open(); <</script>> <<else>> <<goto "hotspot.solution">> <</if>> <</if>>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); $(document).one(":passagedisplay", function() { const modelViewer = document.getElementById('model-viewer'); if (modelViewer){ modelViewer.src = `models/${State.variables.hotspot}.hotspot/${State.variables.hotspot}.hotspot.glb`; modelViewer.iosSrc = `models/${State.variables.hotspot}.hotspot/${State.variables.hotspot}.hotspot.usdz`; modelViewer.poster = `models/${State.variables.hotspot}.hotspot/${State.variables.hotspot}.hotspot.poster.webp`; } }) <</script>> <div class="wrapper"> <model-viewer id="model-viewer" ar auto-rotate autoplay shadow-intensity="2" shadow-softness="0" camera-controls> <button slot="ar-button" id="ar-button"><<txt>></button> </model-viewer> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <<if $isScanner>> <button class="next">[[|main.scanner.ghost]]</button> <<elseif $isNavigatorScanner>> <button class="next">[[|hotspot.ghost]]</button> <<else>> <<button OK>> <<script>> jQuery(Dialog .setup(setup.text[passage()][3][setup.i18n.langs[settings.lang]])) .append("<p>".concat(setup.text[passage()][4][setup.i18n.langs[settings.lang]],'</p><ul class="buttons">')+'<li><button id="restart-ok">' .concat(L10n.get(["restartOk","ok"]),"</button></li>")+'<li><button id="restart-cancel" class="ui-close">' .concat(L10n.get(["restartCancel","cancel"]),"</button></li>")+"</ul>") .find("#restart-ok") .ariaClick({one:!0},(function(){jQuery(document).one(":dialogclosed",(function(){return $.wiki('<<goto "hotspot.questions" >>');})),Dialog.close()}) ),!0; Dialog.open(); <</script>> <</button>> <</if>> </div>
<<script>> $(document).one(":passagedisplay", function() { const modelViewer = document.getElementById('model-viewer'); if (modelViewer){ modelViewer.src = `models/${State.variables.hotspot}.${passage().split(".")[0]}/${State.variables.hotspot}.${passage()}.glb`; modelViewer.iosSrc = `models/${State.variables.hotspot}.${passage().split(".")[0]}/${State.variables.hotspot}.${passage()}.usdz`; modelViewer.poster = `models/${State.variables.hotspot}.${passage().split(".")[0]}/${State.variables.hotspot}.${passage()}.poster.webp`; } }) <</script>> <div class="wrapper"> <model-viewer id="model-viewer" ar auto-rotate autoplay shadow-intensity="2" shadow-softness="0" camera-controls> <button slot="ar-button" id="ar-button"><<txt>></button> </model-viewer> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <<if $hotspot === 10 && ($isScanner || $isNavigatorScanner)>> <button class="next">[[|outro.scanner.init]]</button> <<elseif $isScanner>> <button class="next">[[|main.scanner]]</button> <<elseif $isNavigatorScanner>> <button class="next">[[|main.navigator]]</button> <<else>> <button class="next">[[|hotspot.rune]]</button> <</if>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); <</script>> <div class="wrapper"> <h1><<txt 11>></h1> <<set $headingText = setup.text[passage()][$hotspot][setup.i18n.langs[settings.lang]]>> <h2>$headingText</h2> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <<set $riddleCount to 1>> <<if $playerCount === 1>> /* Skip hotspot.solution passage */ <<goto "hotspot.ghost">> <button class="next">[[|hotspot.ghost]]</button> <<else>> /* Skip hotspot.solution passage */ <<goto "hotspot.frequence.ghost">> <button class="next">[[|hotspot.frequence.ghost]]</button> <</if>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); <</script>> <<audio ":playing:not(:bg)" stop>> <div class="wrapper"> <h1><<txt 11>></h1> <<if $riddleCorrectCount is 5>> <h2><<txt>></h2> <p class="p2">A</p> <<set $letter[$hotspot + 1] to 1>> <<else>> <h2><<txt 12>></h2> <</if>> </div> <div class="btn-group"> <<if $playerCount === 1>> <button class="return">[[|hotspot.ghost]]</button> <<else>> <button class="return">[[|hotspot.frequence.ghost]]</button> <</if>> <button class="retry">[[|passage()]]</button> <<set $riddleCorrectCount to 0>> <button class="next">[[|hotspot.secret]]</button> </div>
<script> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); </script> <div class="wrapper"> <h1><<txt>></h1> <br/> <<secret>> </div> <div class="btn-group"> <button class="return">[[|hotspot.rune]]</button> <button class="retry">[[|passage()]]</button> <button class="next">[[|hotspot.outro]]</button> </div>
<<video>> <div class="btn-group"> <button class="return">[[|hotspot.secret]]</button> <button class="retry">[[|passage()]]</button> <<if $hotspot === 10>> <button class="next">[[|outro.1]]</button> <<elseif $playerCount === 1>> <button class="next">[[|main.navigator]]</button> <<else>> <button class="next">[[|main.storyteller]]</button> <</if>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); <</script>> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> </div> <div class="btn-group"> <<numberbox "_answer" 0>> <<button "Check">> <<if _answer is "">> <<script>>UI.alert(setup.text[passage()][3][setup.i18n.langs[settings.lang]]);<</script>> <<elseif $validOutroFrequence === _answer>> <<goto "outro.8">> <<else>> <<script>>UI.alert(setup.text[passage()][4][setup.i18n.langs[settings.lang]]);<</script>> <<goto "outro.navigator.init">> <</if>> <</button>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); <</script>> <div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> </div> <div class="btn-group"> <<numberbox "_answer" 0>> <<button "Check">> <<if _answer is "">> <<script>>UI.alert(setup.text[passage()][3][setup.i18n.langs[settings.lang]]);<</script>> <<elseif $validOutroFrequence === _answer>> <<goto "outro.7">> <<else>> <<script>>UI.alert(setup.text[passage()][4][setup.i18n.langs[settings.lang]]);<</script>> <<goto "outro.scanner.init">> <</if>> <</button>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); <</script>> <div class="wrapper"> <h1><<print $validOutroFrequence>></h1> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|outro.8]]</button> </div>
<<audio ":playing:not(:bg)" stop>> <<video noHotspot>> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|outro.2]]</button> </div>
<<video noHotspot>> <div class="btn-group"> <button class="return">[[|outro.1]]</button> <button class="retry">[[|passage()]]</button> <button class="next">[[|outro.3]]</button> </div>
<script> $('#story').attr('style', 'background-image:url(images/outro.3.jpg)'); </script> <div class="wrapper"> <h2><<txt>></h2> <br/> <<secret>> </div> <div class="btn-group"> <<button setup.text['outro.3'][2][setup.i18n.langs[settings.lang]]>> <<script>> jQuery(Dialog .setup(setup.text[passage()][5][setup.i18n.langs[settings.lang]])) .append("<p>".concat(setup.text[passage()][6][setup.i18n.langs[settings.lang]],'</p><ul class="buttons">')+'<li><button id="restart-ok">' .concat(L10n.get(["restartOk","ok"]),"</button></li>")+'<li><button id="restart-cancel" class="ui-close">' .concat(L10n.get(["restartCancel","cancel"]),"</button></li>")+"</ul>") .find("#restart-ok") .ariaClick({one:!0},(function(){jQuery(document).one(":dialogclosed",(function(){return $.wiki('<<goto "outro.4.ball" >>');})),Dialog.close()}) ),!0; Dialog.open(); <</script>> <</button>> <<button setup.text['outro.3'][3][setup.i18n.langs[settings.lang]]>> <<script>> jQuery(Dialog .setup(setup.text[passage()][5][setup.i18n.langs[settings.lang]])) .append("<p>".concat(setup.text[passage()][6][setup.i18n.langs[settings.lang]],'</p><ul class="buttons">')+'<li><button id="restart-ok">' .concat(L10n.get(["restartOk","ok"]),"</button></li>")+'<li><button id="restart-cancel" class="ui-close">' .concat(L10n.get(["restartCancel","cancel"]),"</button></li>")+"</ul>") .find("#restart-ok") .ariaClick({one:!0},(function(){jQuery(document).one(":dialogclosed",(function(){return $.wiki('<<goto "outro.4.mask" >>');})),Dialog.close()}) ),!0; Dialog.open(); <</script>> <</button>> <<button setup.text['outro.3'][4][setup.i18n.langs[settings.lang]]>> <<script>> jQuery(Dialog .setup(setup.text[passage()][5][setup.i18n.langs[settings.lang]])) .append("<p>".concat(setup.text[passage()][6][setup.i18n.langs[settings.lang]],'</p><ul class="buttons">')+'<li><button id="restart-ok">' .concat(L10n.get(["restartOk","ok"]),"</button></li>")+'<li><button id="restart-cancel" class="ui-close">' .concat(L10n.get(["restartCancel","cancel"]),"</button></li>")+"</ul>") .find("#restart-ok") .ariaClick({one:!0},(function(){jQuery(document).one(":dialogclosed",(function(){return $.wiki('<<goto "outro.4.book" >>');})),Dialog.close()}) ),!0; Dialog.open(); <</script>> <</button>> </div>
<<video noHotspot>> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|outro.5.ball]]</button> </div>
<<video noHotspot>> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|outro.5.mask]]</button> </div>
<<video noHotspot>> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|outro.5.book]]</button> </div>
<<video noHotspot>> <<set $secretCorrect to 1>> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|outro.6]]</button> </div>
<<video noHotspot>> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|outro.6]]</button> </div>
<<video noHotspot>> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|outro.6]]</button> </div>
<<script>> if (State.variables.secretCorrect) { $('#story').attr('style', 'background-image:url(images/bg.jpg)'); } else { $('#story').attr('style', 'background-image:url(images/bg.jpg)'); }; <</script>> <div class="wrapper"> <<if $secretCorrect>> <h2><<txt 1>></h2> <h2><<txt 2>></h2> <<else>> <h2><<txt 3>></h2> <h2><<txt 4>></h2> <</if>> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <<if $playerCount === 1>> <button class="next">[[|outro.7]]</button> <<else>> <button class="next">[[|outro.storyteller.init]]</button> <</if>> </div>
<div class="wrapper"> <<script>> $(document).one(":passagedisplay", function() { $('#story').attr('style', 'background-image:url(images/outro.7.jpg)'); const modelViewer = document.querySelector("model-viewer"); window.switchSrc = (element, name) => { const base = `models/outro/outro.${name}`; modelViewer.src = base + '.glb'; modelViewer.iosSrc = base + '.usdz'; const slides = document.querySelectorAll(".slide"); slides.forEach((element) => {element.classList.remove("selected");}); element.classList.add("selected"); }; if (modelViewer) { document.querySelector(".slider").addEventListener('beforexrselect', (ev) => { ev.preventDefault(); }); } }) <</script>> <model-viewer id="model-viewer" ar auto-rotate src="models/outro/outro.7.team.glb" ios-src="models/outro/outro.7.team.usdz" poster="models/outro/outro.7.team.poster.webp" autoplay shadow-intensity="2" shadow-softness="0" camera-controls alt="A spook carousel"> <button slot="ar-button" id="ar-button"><<txt>></button> <div class="slider"> <div class="slides"> <button class="slide selected" onclick="switchSrc(this, '7.team')" style="background-image: url('models/outro/outro.7.team.poster.webp');"></button> <button class="slide" onclick="switchSrc(this, '7.guide')" style="background-image: url('models/outro/outro.7.guide.poster.webp');"></button> <button class="slide" onclick="switchSrc(this, '7.scanner')" style="background-image: url('models/outro/outro.7.scanner.poster.jpg');"></button> <button class="slide" onclick="switchSrc(this, '7.storyteller')" style="background-image: url('models/outro/outro.7.storyteller.poster.webp');"></button> </div> </div> </model-viewer> <h2><<txt>></h2> </div> <div class="btn-group"> <button class="retry">[[|passage()]]</button> <button class="next">[[|outro.8]]</button> </div>
<script> $('#story').attr('style', 'background-image:url(images/outro.8.jpg)'); </script> <div class="wrapper"> <h2><<txt>></h2> <h2><<txt>></h2> <h2><<txt>><a href="mailto:feedback@geomazing.com">"feedback@geomazing.com"</a><<txt>></h2> </div> <div class="btn-group"> <<if $playerCount === 1 || $isScanner || $isNavigatorScanner>> <button class="return">[[|outro.7]]</button> <<elseif $isStoryteller>> <button class="return">[[|outro.storyteller.init]]</button> <</if>> <button class="retry">[[|passage()]]</button> </div>
<div class="wrapper"> <h1><<txt 11>></h1> <h2><<txt 12>></h2> <br/> <br/> <div class="btn-group"> <<for _i to 1; _i lte 10; _i++>> <<capture _i>> <<set $chapterText = setup.text['Dev'][_i][setup.i18n.langs[settings.lang]]>> <<button $chapterText+$validFrequences[_i-1]>> <<set $hotspot to _i>> <<if $isStoryteller>> <<goto "hotspot.splash">> <<else>> <<goto "hotspot.frequence">> <</if>> <</button>> <</capture>> <</for>> <<button "Outro">> <<goto "outro.1">> <</button>> <<set $mapText = setup.text['Dev'][13][setup.i18n.langs[settings.lang]]>> <<button $mapText>> <<goto "main.navigator">> <</button>> </div> </div> <div class="btn-group"> <<return>> </div>
<div class="wrapper"> <h1><<txt>></h1> <h2><<txt>></h2> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <details> <summary> <h5><<txt>></h5> </summary> <div> <p><<txt>></p> </div> </details> <h2><<txt>> <a href="mailto:getlost@geomazing.com">getlost@geomazing.com</a></h2> </div> <div class="btn-group"> <<return>> </div>
<div class="wrapper"> <h1><<txt>></h1> <div> <br/> <h3><<txt>></h3> <br/> <p><<txt>></p> <p><<txt>></p> <p><<txt>></p> <p><<txt>></p> <p><<txt>></p> </div> <div> <br/> <h3><<txt>></h3> <br/> <p><<txt>></p> <p><<txt>></p> </div> <div> <br/> <h3><<txt>></h3> <p><<txt>></p> </div> <div> <br/> <h3><<txt>></h3> <p><<txt>></p> </div> <div> <br/> <h3><<txt>></h3> <p><<txt>></p> </div> <div> <br/> <h3><<txt>></h3> <p><<txt>></p> </div> <div> <br/> <h3><<txt>></h3> <p><<txt>></p> <p><<txt>></p> <p><<txt>></p> <p><<txt>></p> </div> </div> <div class="btn-group"> <<return>> </div>
<div class="wrapper"> <h1><<txt>></h1> <h2> <br/> <<txt>> <a target="_blank" href="https://www.geomazing.com/shop">GEOMAZING</a> <<txt>> <a target="_blank" href="https://digitalwarenkombinat.de/">Digitalwarenkombinat GbR</a> <<txt>> </h2> <div> <br/> <h3><<txt>></h3> <br/> <p><<txt>></p> </div> <div> <br/> <h3><<txt>></h3> <br/> <p><<txt>></p> </div> <div> <br/> <h3><<txt>></h3> <br/> <p><<txt>></p> </div> <div> <br/> <p><<txt>></p> <br/> <p><<txt>></p> <br/> <p><<txt>></p> </div> </div> <div class="btn-group"> <<return>> </div>
<<script>> $('#story').attr('style', 'background-image:url(images/bg.jpg)'); <</script>> <div class="wrapper"> <h1><<txt>></h1> <<script>> $(document).one(":passagedisplay", function() { const modelViewer = document.querySelector("model-viewer"); window.switchSrc = (element, name) => { const base = `models/${name}.hotspot/${name}.hotspot.ghost`; modelViewer.src = base + '.glb'; modelViewer.iosSrc = base + '.usdz'; const slides = document.querySelectorAll(".slide"); slides.forEach((element) => {element.classList.remove("selected");}); element.classList.add("selected"); }; if (modelViewer) { document.querySelector(".slider").addEventListener('beforexrselect', (ev) => { ev.preventDefault(); }); } }) <</script>> <<if $hotspot > 0>> <model-viewer id="model-viewer" ar auto-rotate src="models/1.hotspot/1.hotspot.ghost.glb" ios-src="models/1.hotspot/1.hotspot.ghost.glb" poster="models/1.hotspot/1.hotspot.ghost.poster.webp" autoplay shadow-intensity="2" shadow-softness="0" camera-controls alt="A spook carousel"> <button slot="ar-button" id="ar-button"><<txt 2>></button> <div class="slider"> <div class="slides"> <button class="slide selected" onclick="switchSrc(this, '1')" style="background-image: url('models/1.hotspot/1.hotspot.ghost.poster.webp');"></button> <<if $hotspot > 1>><button class="slide" onclick="switchSrc(this, '2')" style="background-image: url('models/2.hotspot/2.hotspot.ghost.poster.webp');"></button><</if>> <<if $hotspot > 2>><button class="slide" onclick="switchSrc(this, '3')" style="background-image: url('models/3.hotspot/3.hotspot.ghost.poster.webp');"></button><</if>> <<if $hotspot > 3>><button class="slide" onclick="switchSrc(this, '4')" style="background-image: url('models/4.hotspot/4.hotspot.ghost.poster.webp');"></button><</if>> <<if $hotspot > 4>><button class="slide" onclick="switchSrc(this, '5')" style="background-image: url('models/5.hotspot/5.hotspot.ghost.poster.webp');"></button><</if>> <<if $hotspot > 5>><button class="slide" onclick="switchSrc(this, '6')" style="background-image: url('models/6.hotspot/6.hotspot.ghost.poster.webp');"></button><</if>> <<if $hotspot > 6>><button class="slide" onclick="switchSrc(this, '7')" style="background-image: url('models/7.hotspot/7.hotspot.ghost.poster.webp');"></button><</if>> <<if $hotspot > 7>><button class="slide" onclick="switchSrc(this, '8')" style="background-image: url('models/8.hotspot/8.hotspot.ghost.poster.webp');"></button><</if>> <<if $hotspot > 8>><button class="slide" onclick="switchSrc(this, '9')" style="background-image: url('models/9.hotspot/9.hotspot.ghost.poster.webp');"></button><</if>> <<if $hotspot > 9>><button class="slide" onclick="switchSrc(this, '10')" style="background-image: url('models/10.hotspot/10.hotspot.ghost.poster.webp');"></button><</if>> </div> </div> </model-viewer> <</if>> <h2><<txt 3>></h2> </div> <div class="btn-group"> <<return>> </div>
/************ Configuration ************/ Config.saves.autosave = ["autosave"]; Config.passages.nobr = true; Config.ui.stowBarInitially = true; /************************** Internationalization (i18n) **************************/ settings.lang = "Deutsch"; setup.i18n = { /* Map of language labels to codes for all supported languages */ langs : { 'Deutsch' : 'de', 'English' : 'en', }, /* Utility methods */ codes : function () { return Object.keys(this.langs).map(function (label) { return this.langs[label]; }, this); }, labels : function () { return Object.keys(this.langs); }, labelFromCode : function (code) { let label = Object.keys(this.langs).find(function (label) { return this.langs[label] === code; }, this); if (!label) { throw new Error('unknown language code "' + code + '"'); } return label; } }; /* Language switching setting */ function initLanguage() { switch (setup.i18n.langs[settings.lang]) { case 'en': l10nStrings.identity="game",l10nStrings.aborting="Aborting",l10nStrings.cancel="Cancel",l10nStrings.close="Close",l10nStrings.ok="OK",l10nStrings.errorTitle="Error",l10nStrings.errorToggle="Toggle the error view",l10nStrings.errorNonexistentPassage='the passage "{passage}" does not exist',l10nStrings.errorSaveDiskLoadFailed="failed to load save file from disk",l10nStrings.errorSaveMissingData="save is missing required data. Either the loaded file is not a save or the save has become corrupted",l10nStrings.errorSaveIdMismatch="save is from the wrong {identity}",l10nStrings._warningIntroLacking="Your browser either lacks or has disabled",l10nStrings._warningOutroDegraded=", so this {identity} is running in a degraded mode. You may be able to continue, however, some parts may not work properly.",l10nStrings.warningNoWebStorage="{_warningIntroLacking} the Web Storage API{_warningOutroDegraded}",l10nStrings.warningDegraded="{_warningIntroLacking} some of the capabilities required by this {identity}{_warningOutroDegraded}",l10nStrings.debugBarToggle="Toggle the debug bar",l10nStrings.debugBarNoWatches="— no watches set —",l10nStrings.debugBarAddWatch="Add watch",l10nStrings.debugBarDeleteWatch="Delete watch",l10nStrings.debugBarWatchAll="Watch all",l10nStrings.debugBarWatchNone="Delete all",l10nStrings.debugBarLabelAdd="Add",l10nStrings.debugBarLabelWatch="Watch",l10nStrings.debugBarLabelTurn="Turn",l10nStrings.debugBarLabelViews="Views",l10nStrings.debugBarViewsToggle="Toggle the debug views",l10nStrings.debugBarWatchToggle="Toggle the watch panel",l10nStrings.uiBarToggle="Toggle the UI bar",l10nStrings.uiBarBackward="Go backward within the {identity} history",l10nStrings.uiBarForward="Go forward within the {identity} history",l10nStrings.uiBarJumpto="Jump to a specific point within the {identity} history",l10nStrings.jumptoTitle="Jump To",l10nStrings.jumptoTurn="Turn",l10nStrings.jumptoUnavailable="No jump points currently available…",l10nStrings.savesTitle="Saves",l10nStrings.savesDisallowed="Saving has been disallowed on this passage.",l10nStrings.savesIncapable="{_warningIntroLacking} the capabilities required to support saves, so saves have been disabled for this session.",l10nStrings.savesLabelAuto="Autosave",l10nStrings.savesLabelDelete="Delete",l10nStrings.savesLabelExport="Save to Disk…",l10nStrings.savesLabelImport="Load from Disk…",l10nStrings.savesLabelLoad="Load",l10nStrings.savesLabelClear="Delete All",l10nStrings.savesLabelSave="Save",l10nStrings.savesLabelSlot="Slot",l10nStrings.savesUnavailable="No save slots found…",l10nStrings.savesUnknownDate="unknown",l10nStrings.settingsTitle="Settings",l10nStrings.settingsOff="Off",l10nStrings.settingsOn="On",l10nStrings.settingsReset="Reset to Defaults",l10nStrings.restartTitle="Restart",l10nStrings.restartPrompt="Are you sure that you want to restart? Unsaved progress will be lost.",l10nStrings.shareTitle="Share",l10nStrings.alertTitle="Alert",l10nStrings.autoloadTitle="Autoload",l10nStrings.autoloadCancel="Go to start",l10nStrings.autoloadOk="Load autosave",l10nStrings.autoloadPrompt="An autosave exists. Load it now or go to the start?",l10nStrings.macroBackText="Back",l10nStrings.macroReturnText=""; break; default: l10nStrings.identity="spiel",l10nStrings.aborting="Vorzeitig abgebrochen",l10nStrings.cancel="Abbrechen",l10nStrings.close="Schließen",l10nStrings.ok="OK",l10nStrings.errorTitle="Fehler",l10nStrings.errorToggle="Fehleransicht umschalten",l10nStrings.errorNonexistentPassage='die Passage "{passage}" existiert nicht',l10nStrings.errorSaveMissingData="Im Speicherstand fehlen benötigte Daten. Entweder ist die geladene Datei kein Speicherstand oder er ist defekt",l10nStrings.errorSaveIdMismatch="Speicherstand ist vom falschen {identity}",l10nStrings._warningIntroLacking="Dein Browser kann folgendes nicht darstellen, oder es ist deaktiviert",l10nStrings._warningOutroDegraded="; darum läuft dieses {identity} in einem heruntergesetzten Modus. Du kannst zwar fortfahren, aber manche Teile funktionieren vielleicht nicht richtig.",l10nStrings.warningNoWebStorage="{_warningIntroLacking} Das Web Storage API{_warningOutroDegraded}",l10nStrings.warningDegraded="{_warningIntroLacking} Manche Features die für dieses {identity} benötigt werden{_warningOutroDegraded}",l10nStrings.debugBarToggle="Fehlersuche-Leiste umschalten",l10nStrings.debugBarNoWatches="— kein Beobachtungswert aktiv —",l10nStrings.debugBarAddWatch="Beobachtungswert hinzufügen",l10nStrings.debugBarDeleteWatch="Beobachtungswert löschen",l10nStrings.debugBarWatchAll="Alle beobachten",l10nStrings.debugBarWatchNone="Alle löschen",l10nStrings.debugBarLabelAdd="Hinzufügen",l10nStrings.debugBarLabelWatch="Beobachten",l10nStrings.debugBarLabelTurn="Zug",l10nStrings.debugBarLabelViews="Ansichten",l10nStrings.debugBarViewsToggle="Fehlersuche-Ansichten umschalten",l10nStrings.debugBarWatchToggle="Beobachtungs-Feld umschalten",l10nStrings.uiBarToggle="Menüleiste umschalten",l10nStrings.uiBarBackward="Einen Schritt im {identity}-Ablauf zurück",l10nStrings.uiBarForward="Einen Schritt im {identity}-Ablauf nach vor",l10nStrings.uiBarJumpto="Zu einem bestimmten Punkt im {identity}-Ablauf springen",l10nStrings.jumptoTitle="Springe zu",l10nStrings.jumptoTurn="Zug",l10nStrings.jumptoUnavailable="Keine Sprungmarken verfügbar…",l10nStrings.savesTitle="Speicherstände",l10nStrings.savesDisallowed="Speichern ist in dieser Passage nicht erlaubt.",l10nStrings.savesIncapable="{_warningIntroLacking} Zum Speichern benötigte Features, darum ist es in dieser Sitzung nicht möglich, den Spielstand zu speichern.",l10nStrings.savesLabelAuto="Auto-Speicherstand",l10nStrings.savesLabelDelete="Löschen",l10nStrings.savesLabelExport="Auf Datenträger speichern…",l10nStrings.savesLabelImport="Von Datenträger laden…",l10nStrings.savesLabelLoad="Laden",l10nStrings.savesLabelClear="Alle löschen",l10nStrings.savesLabelSave="Speichern",l10nStrings.savesLabelSlot="Slot",l10nStrings.savesUnavailable="Keine Speicherslots gefunden…",l10nStrings.savesUnknownDate="unbekannt",l10nStrings.settingsTitle="Einstellungen",l10nStrings.settingsOff="Aus",l10nStrings.settingsOn="Ein",l10nStrings.settingsReset="Auf Standardwerte zurücksetzen",l10nStrings.restartTitle="Neustart",l10nStrings.restartPrompt="Bist du sicher, dass du neu starten möchtest? Nicht gespeicherter Fortschritt ginge damit verloren.",l10nStrings.shareTitle="Teilen",l10nStrings.autoloadTitle="Automatisches Laden",l10nStrings.autoloadCancel="Gehe zum Start",l10nStrings.autoloadOk="Auto-Speicherstand laden",l10nStrings.autoloadPrompt="Ein Auto-Speicherstand existiert bereits. Laden oder zurück an den Start?",l10nStrings.macroBackText="Zurück",l10nStrings.macroReturnText=""; } $('html').attr('lang', setup.i18n.langs[settings.lang]); } function changeLanguage() { /* Reload the application to ensure that proper localizations are loaded */ window.location.reload(); } Setting.addList('lang', { label : 'Language/Sprachen', list : setup.i18n.labels(), default : setup.i18n.labelFromCode('de'), onInit : initLanguage, onChange : changeLanguage }); setup.text = getTranslations(); var settingMusic = function () { SimpleAudio.select(":playing:not(bg)").mute((!settings.music)); }; Setting.addToggle("music", { label : "Music", default : true, onInit : settingMusic, onChange : settingMusic }); /************* Mapbox imports *************/ importStyles("https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.css"); /***************** Window Geolocation *****************/ (function () { window.geolocation = { available: function() { return ("geolocation" in navigator && typeof navigator.geolocation.getCurrentPosition === "function"); }, /* Optionen für Mapbox Geolocation */ getGeolocateControl: function() { return { positionOptions: { enableHighAccuracy: true }, trackUserLocation: true, showUserHeading: true } }, /* Test ob eine Location innerhalb der aktuellen Geokoordinaten ist */ inside: function(lat1, lon1, radius, lat2, lon2) { const R = 6371; const dLat = (lat2-lat1) * Math.PI / 180; const dLon = (lon2-lon1) * Math.PI / 180; const a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) * Math.sin(dLon/2) * Math.sin(dLon/2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); const distance = R * c * 1000; return distance < radius; }, /* Erstellt einen sichtbaren Kreis um eine Location */ createGeoJSONCircle: function(center, radius) { const points = 64; const coords = { latitude: center[1], longitude: center[0] }; let ret = []; const distanceX = radius / (111.320 * Math.cos(coords.latitude * Math.PI / 180)); const distanceY = radius / 110.574; var theta, x, y; for (var i = 0; i < points; i++) { theta = (i / points) * (2 * Math.PI); x = distanceX * Math.cos(theta); y = distanceY * Math.sin(theta); ret.push([coords.longitude + x, coords.latitude + y]); } ret.push(ret[0]); return { "type": "geojson", "data": { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [ret] } }] } }; } }; /*********** Window Video ***********/ window.video = { showButtonsOnVideoEnd: function() { $(document).on(":passagedisplay", function() { const video = document.querySelector('video'); if (video) { const btnGroup = document.querySelector('.btn-group'); if (btnGroup) btnGroup.style.display = 'none'; video.onended = (event) => { if (btnGroup) btnGroup.style.display = 'inline'; }; }; }); } } window.player = { setPlayerRole: function(role) { State.setVar("$isStoryteller", role === 'Storyteller'); State.setVar("$isScanner", role === 'Scanner'); State.setVar("$isNavigator", role === 'Navigator'); State.setVar("$isNavigatorScanner", role === 'NavigatorScanner'); }, setPlayerCount: function(count) { if (count >= 1 && count <= 3) { State.setVar("$playerCount", count); } else { console.log('Invalid player count'); } } } /***************************** External script loading module *****************************/ window.requestScriptLoad = function (options) { if (options == null || typeof options !== 'object' || !options.src) { return; } let opts = Object.assign({ parent : document.head }, options); let script = document.createElement('script'); function onLoadOnce(evt) { opts.onload.call(evt.target, evt); script.removeEventListener('load', onLoadOnce); } script.id = opts.id; script.src = opts.src; script.type = 'text/javascript'; if (typeof opts.onload === 'function') { script.addEventListener('load', onLoadOnce, false); } opts.parent.appendChild(script); }; }());
:root { /* Primäre Farben */ --primary-color: #F299CA; --primary-dark-color: #9CF299; /* Sekundäre Farben */ --secondary-color: #9CF299; --secondary-dark-color: #68A683; /* Hintergrundfarben */ --background-color: #000000; --background-light-color: #FFFFFF; --background-darken-color: #00000070; --background-dark-color: #44444470; /* Textfarben */ --button-color: #26262670; --text-color: #323140; --text-hover-color: #FFFFFF; --text-light-color: #FFFFFF; } @font-face { font-family: Creepster; src: url(fonts/Creepster/Creepster-Regular.ttf); } @font-face { font-family: Averia Serif Libre; src: url(fonts/Averia_Serif_Libre/AveriaSerifLibre-Bold.ttf); } @font-face { font-family: para; src: url(fonts/para.otf); } @-webkit-keyframes fade-out { 0% {opacity: 1;} 100% {opacity: 0;} } @keyframes fade-out { 0% {opacity: 1;} 100% {opacity: 0;} } /* ####################HTML ELEMENTS#################### */ html { height: 100%; } html * { box-sizing: border-box; } body { background-color: var(--background-color); color: var(--text-light-color); font-family: 'Averia Serif Libre', serif; font-size: 16px; height: 100%; margin: 0; padding: 0; width: 100%; } audio, canvas, progress, video { max-width: none; vertical-align: middle; } h1 { font-family: "Creepster", sans-serif; font-size: 6vh; font-style: normal; font-weight: 400; line-height: 8vh; margin-bottom: 1rem; margin-left: 2vw; margin-right: 2vw; text-align: center; letter-spacing: 8px; word-break: break-word; color: #ffffff00; -webkit-text-stroke: 2px var(--text-light-color); /* text-shadow: 0 0 20px var(--text-light-color); */ } h2 { color: var(--text-light-color); font-family: 'Averia Serif Libre', serif; font-size: 3vh; font-style: normal; font-weight: 700; line-height: 4vh; margin-left: 20px; margin-right: 30px; text-align: center; text-shadow: 3px 3px 1px black; word-break: break-word; } h3 { color: var(--text-light-color); font-family: 'Averia Serif Libre', serif; font-size: 4vh; font-weight: 900; line-height: 4vh; margin: 0; text-align: center; word-break: break-word; } h4 { color: var(--text-light-color); font-family: 'Averia Serif Libre', serif; line-height: 1.5vh; margin-bottom: -5vh; margin-left: 1.5vw; margin-right: 2vw; text-align: center; word-break: break-word; } h5 { color: var(--text-light-color); font-family: 'Averia Serif Libre', serif; font-size: 2vh; line-height: 2vh; margin-bottom: 0vh; margin-left: 2vw; margin-right: 2vw; text-align: center; word-break: break-word; } h6 { color: #F2F2F2; font-family: 'Caveat Brush', cursive; font-size: 15vh; font-weight: normal; line-height: 12vh; margin-bottom: 0; margin-bottom: 1rem; margin-left: 10vw; margin-right: 10vw; margin-top: 0; text-align: center; word-break: break-word; } p { color: var(--text-light-color); font-family: 'Averia Serif Libre', serif; font-size: 3vh; font-style: normal; font-weight: 700; line-height: 4vh; margin-left: 20px; margin-right: 30px; text-align: center; text-shadow: 3px 3px 1px black; word-break: break-word; } a { color: var(--secondary-color); } a:hover { color: var(--secondary-color); text-decoration: none; } button { border-radius: 4px; background-color: var(--background-color); border: 2px solid #000000; display: inline-block; color: var(--secondary-color); font-family: 'Averia Serif Libre', serif; font-size: 3vh; font-weight: 400; line-height: 4vh; margin-top: 1vh; text-align: center; text-decoration: none; } button:hover { background-color: var(--text-hover-color); border-color: var(--text-hover-color); } details { width: 80%; margin: 0 auto ; background: var(--button-color); margin-bottom: .5rem; box-shadow: 0 .1rem 1rem -.5rem rgba(0,0,0,.4); border-radius: 5px; overflow: hidden; } summary { padding: 1rem; display: block; background: var(--background-dark-color); padding-left: 2.2rem; position: relative; cursor: pointer; } summary h5 { margin-top: 0vh; } summary:before { content: ''; border-width: .4rem; border-style: solid; border-color: transparent transparent transparent var(--background-light-color); position: absolute; top: 1.5rem; left: 1rem; transform: rotate(0); transform-origin: .2rem 50%; transition: .25s transform ease; } details[open] > summary:before { transform: rotate(90deg); } details summary::-webkit-details-marker { display:none; } details > ul { padding-bottom: 1rem; margin-bottom: 0; } input[type=text] { min-width: 1em } progress[value] { -webkit-appearance: none; appearance: none; width: 100%; height: 20px; } progress[value]::-webkit-progress-bar { background-color: var(--background-light-color); border-radius: 2px; } progress[value]::-webkit-progress-value { background-color: var(--secondary-color); border-radius: 2px; } /* ####################SUGARCUBE#################### */ #ui-bar { background-color: transparent; border-right: 0; } #ui-bar-body { background-color: var(--background-color); background-image: url('images/setup.storyteller.jpg'); background-position: center; background-size: cover; border-right: solid 2px var(--secondary-color); height: 100%; margin: 0; width: 34vh; position: relative; } #ui-bar-body #title { position: absolute; bottom: 0; width: 100%; left: 0; padding-left: 1rem; padding-right: 1rem; } #ui-bar-tray { z-index: 10; } #ui-bar-toggle { border: none; color: var(--text-light-color); font-size: 4vh; left:0; position: fixed; right: unset; top: 4vh; } #ui-bar-toggle:before { color: var(--secondary-color); content: "\e804"; text-shadow: 1px 1px 20px var(--secondary-color); } #ui-bar-toggle:hover { background-color: transparent; border: none; } #ui-bar-history { display: none; } #ui-bar.stowed~#story { margin-left: 0; } #ui-bar.stowed #ui-bar-toggle:before { color: var(--secondary-color); content: "\e82e"; } #ui-dialog-title { color: var(--text-light-color); font-family: 'Averia Serif Libre', serif; font-weight: 900; line-height: 4vh; word-break: break-word; -webkit-text-stroke: inherit; } #ui-dialog-body ul { display: flex; justify-content: center; } #ui-dialog { border: 2px solid var(--secondary-color); } #menu-item-share, #menu-item-saves { display: none; } #menu ul { border: none; margin: 0; } #menu-core { /* position: fixed; bottom: 2em; */ } #menu-story li:first-child { margin-bottom: 12rem; } #menu li a { border-radius: 4px; /* border: 2px solid var(--secondary-color); */ color: var(--secondary-color); font-family: 'Averia Serif Libre', serif; font-size: 3vh; font-weight: 400; line-height: 4vh; margin-bottom: 1vh; text-transform: none; text-shadow: 1px 1px 20px var(--secondary-color); } #menu li:not(:first-child) { border: none; } /* ####################STORY PASSAGE#################### */ #story { background-position: center; background-repeat: no-repeat; background-size: cover; height: 100%; margin: 0; padding: 4vh 0; } #story-title { display: none; } #story-subtitle { width: 100%; display: flex; justify-content: space-between; } #story-subtitle a:last-child{ color: var(--text-light-color); } #passages { height: 100%; } .passage { display: flex; flex-direction: column; height: 100%; justify-content: space-between; } /* ####################WRAPPER BUTTONS#################### */ .wrapper { flex-grow: 1; height: 100%; overflow: auto; z-index: 20; margin: 5vw; } .btn-group { margin: 0 auto 2vh; text-align: center; z-index: 20; } .btn-group button { /* text-shadow: 0 0 0.5rem #fff, 0 0 1.5rem #fff, 0 0 1rem #fff, 0 0 2rem var(--secondary-color), 0 0 4rem var(--secondary-color), 0 0 5.5rem var(--secondary-color); */ background: none; border: none; color: var(--secondary-color); font-family: 'Averia Serif Libre', serif; font-size: 4vh; font-weight: 400; line-height: 4vh; margin: 1vh; text-shadow: 1px 1px 20px var(--secondary-color); } .macro-return { text-shadow: 1px 1px 20px var(--secondary-color); color: var(--secondary-color); font-family: 'Averia Serif Libre', serif; font-size: 4vh; font-weight: 400; margin: 1vh; padding: 0.4em; } .macro-return:before, .return a:before { content: "\e821\00a0"; font-family: tme-fa-icons; padding-left: 4px; } .next a:before { content: "\e822\00a0"; font-family: tme-fa-icons; padding-left: 8px; } .retry a:before { content: "\e824\00a0"; font-family: tme-fa-icons; padding-left: 8px; } .help a:before { content: "\e808\00a0"; font-family: tme-fa-icons; padding-left: 8px; } .install::before { content: "\e829\00a0"; font-family: tme-fa-icons; padding-left: 8px; } /* ####################MAP#################### */ /* dvh = Dynamic View High um die komplette Höhe der Navigation Bar zu nutzen */ #map { bottom: 0; height: 100vh; height: 100dvh; position: absolute; top: 0; width: 100%; } /* Macht den Geolocate-Button unsichtbar */ .mapboxgl-ctrl-group button.mapboxgl-ctrl-geolocate ,.mapboxgl-ctrl-bottom-right{ display: none; } /* ####################MODEL VIEWER#################### */ model-viewer { /* background-color: rgba(0, 0, 0, 0.75); */ background-color: transparent; height: 50vh; margin: 0 2vw; width: 90%; } .slider { width: 100%; text-align: center; overflow: hidden; position: absolute; top: 16px; } .slides { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; -webkit-overflow-scrolling: touch; } .slide { scroll-snap-align: start; flex-shrink: 0; width: 50px; height: 50px; background-size: contain; background-repeat: no-repeat; background-position: center; background-color: var(--background-color); margin-right: 10px; border-radius: 10px; border: none; display: flex; } .slide.selected { background-color: var(--background-color); border: 2px solid var(--primary-dark-color); } .slide:focus { outline: none; } .slide:focus-visible { outline: 1px solid var(--primary-dark-color); } .Hotspot { background: #fff; border-radius: 32px; border: 0; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25); box-sizing: border-box; cursor: pointer; height: 24px; padding: 8px; position: relative; transition: opacity 0.3s; width: 24px; } .Hotspot:not([data-visible]) { background: transparent; border: 4px solid #fff; box-shadow: none; height: 32px; pointer-events: none; width: 32px; } .Hotspot:focus { border: 4px solid rgb(0, 128, 200); height: 32px; outline: none; width: 32px; } .Hotspot > * { opacity: 1; transform: translateY(-50%); } .HotspotAnnotation { background: #fff; border-radius: 4px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25); color: rgba(0, 0, 0, 0.8); display: block; font-family: Futura, Helvetica Neue, sans-serif; font-size: 18px; font-weight: 700; left: calc(100% + 1em); max-width: 128px; overflow-wrap: break-word; padding: 0.5em 1em; position: absolute; top: 50%; width: max-content; } .Hotspot:not([data-visible]) > * { opacity: 0; pointer-events: none; transform: translateY(calc(-50% + 4px)); transition: transform 0.3s, opacity 0.3s; } #ar-button { background-image: url(./images/ar_icon.png); background-repeat: no-repeat; background-size: 20px 20px; background-position: 12px 50%; background-color: var(--background-color); position: absolute; left: 50%; transform: translateX(-50%); white-space: nowrap; bottom: 16px; padding: 0px 16px 0px 40px; font-size: 14px; color: var(--secondary-color); height: 36px; line-height: 36px; border-radius: 18px; border: 2px solid var(--secondary-color); text-shadow: 1px 1px 20px var(--secondary-color); font-family: 'Averia Serif Libre'; } #ar-button:active { background-color: #E8EAED; } #ar-button:focus { outline: none; } #ar-button:focus-visible { outline: 1px solid #4285f4; } /* ####################PASSAGE ELEMENTS#################### */ #video { bottom: 0; height: 100%; left: 0; margin-left: 50vw; position: fixed; transform: translate(-50%); width: auto; z-index: 10; } #videoText { color: var(--text-light-color); font-family: 'Averia Serif Libre', serif; font-size: 4vh; font-style: normal; font-weight: 700; line-height: 5vh; /* margin-left: 20px; margin-right: 30px; margin-top: 10vh; */ text-align: center; text-shadow: 3px 3px 1px black; word-break: break-word; } .image-size-33 { display: block; margin: 0 auto; width: 33%; } .image-size-50 { display: block; margin: 0 auto; width: 50%; margin-bottom: -10vw; } .image-size-80 { display: block; margin: 0 auto; width: 80%; } tw-hook[name="fade-out"] { -webkit-animation-name: fade-out; -webkit-animation-duration: 10s; -webkit-animation-fill-mode: both; animation-name: fade-out; animation-duration: 10s; animation-fill-mode: both; } .p1 { display: inherit; font-family: para; font-size: 4vh; margin-top: 1vh; } .p2 { color: var(--primary-color); display: inherit; font-family: para; font-size: 10vh; line-height: 10vh; margin-left: 5vw; margin-right: 5vw; } .p3 { color: var(--primary-color); display: inherit; font-family: para; font-size: 4vh; letter-spacing: 3vw; line-height: 0vh; text-shadow: 3px 3px 1px black; } .hide { display: none; } .bild_ort { display: block; margin-left: auto; margin-right: auto; width: 50%; } .message { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; } .message h2 { /* color: var(--text-light-color); */ letter-spacing: normal; margin: 8px; } #numberbox--answer { border: 2px solid var(--secondary-color); background-color: var(--text-light-color); color: black; font-size: 6vw; margin-left: 5vw; margin-right: 5vw; max-width: 33%; }