{"id":47,"date":"2026-09-03T20:28:38","date_gmt":"2026-09-03T20:28:38","guid":{"rendered":"https:\/\/itdd.au.dk\/the-house\/?page_id=47"},"modified":"2026-11-03T18:31:15","modified_gmt":"2026-11-03T18:31:15","slug":"frontpage","status":"publish","type":"page","link":"https:\/\/itdd.au.dk\/the-house\/","title":{"rendered":""},"content":{"rendered":"\n<!-- THE HOUSE \u2014 COMPLETE HOMEPAGE ENTRANCE -->\n<div id=\"th-home-entrance\">\n\n  <!-- THE GATE -->\n  <div class=\"th-gate-layer\">\n    <img\n      class=\"th-gate-image\"\n      src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/Victorian-Gothic-Welcome-Gate-Overlay.png\"\n      alt=\"Welcome to The House \u2014 Victorian wrought-iron gate\"\n      decoding=\"async\"\n    >\n\n    <!-- LEFT LANTERN -->\n    <button\n      type=\"button\"\n      class=\"th-lantern th-lantern-left\"\n      aria-label=\"Light the left lantern\"\n      aria-pressed=\"false\"\n    >\n      <span class=\"th-light-halo\"><\/span>\n      <span class=\"th-light-core\"><\/span>\n    <\/button>\n\n    <!-- RIGHT LANTERN -->\n    <button\n      type=\"button\"\n      class=\"th-lantern th-lantern-right\"\n      aria-label=\"Light the right lantern\"\n      aria-pressed=\"false\"\n    >\n      <span class=\"th-light-halo\"><\/span>\n      <span class=\"th-light-core\"><\/span>\n    <\/button>\n  <\/div>\n\n  <!-- ENTRANCE BUTTONS -->\n  <div class=\"th-home-buttons\">\n\n    <!-- HOW TO PLAY -->\n    <div id=\"th-howto-repair\">\n      <button\n        type=\"button\"\n        class=\"th-open\"\n        aria-label=\"Open How to Play\"\n      >\n        <img decoding=\"async\"\n          src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/Ornate-Antique-How-to-Play-Banner.png\"\n          alt=\"How to Play\"\n        >\n      <\/button>\n    <\/div>\n\n    <!-- I ENTER THE HOUSE -->\n    <div class=\"th-enter-wrap\">\n      <a\n        id=\"th-enter-link\"\n        class=\"th-enter-link\"\n        href=\"https:\/\/itdd.au.dk\/the-house\/frontdoor\/\"\n        aria-label=\"I Enter The House\"\n      >\n        <img decoding=\"async\"\n          src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/Haunted-Gothic-House-Entrance-Plaque.png\"\n          alt=\"I Enter The House\"\n          loading=\"eager\"\n        >\n      <\/a>\n\n      <audio\n        id=\"th-enter-steps\"\n        preload=\"auto\"\n        src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/dragon-studio-footsteps-on-gravel-2-397986.mp3\"\n      ><\/audio>\n    <\/div>\n\n  <\/div>\n<\/div>\n\n<!-- PARCHMENT POPUP OUTSIDE THE GATE -->\n<div id=\"th-guide-overlay\" aria-hidden=\"true\">\n  <section\n    class=\"th-dialog\"\n    role=\"dialog\"\n    aria-modal=\"true\"\n    aria-label=\"A Guide to The House\"\n    tabindex=\"-1\"\n  >\n    <button\n      type=\"button\"\n      class=\"th-close\"\n      aria-label=\"Close guide\"\n    >\u00d7<\/button>\n\n    <div class=\"th-paper\">\n      <img decoding=\"async\"\n        class=\"th-parchment\"\n        src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/Ornate-Parchment-House-Guide-Transparent.png\"\n        alt=\"A Guide to The House. Read the instructions for puzzles, sound, the menu and commenting.\"\n      >\n\n      <button\n        class=\"th-play\"\n        type=\"button\"\n        aria-label=\"Play or pause Jonathan's recording\"\n      ><\/button>\n\n      <input\n        class=\"th-seek\"\n        type=\"range\"\n        min=\"0\"\n        max=\"1000\"\n        value=\"0\"\n        aria-label=\"Seek through Jonathan's recording\"\n      >\n\n      <span class=\"th-time\" aria-hidden=\"true\">\n        0:00 \/ 0:00\n      <\/span>\n\n      <button\n        class=\"th-mute\"\n        type=\"button\"\n        aria-label=\"Mute or unmute Jonathan's recording\"\n      ><\/button>\n\n      <a\n        class=\"th-music\"\n        href=\"https:\/\/www.youtube.com\/watch?v=SZW6swHagm8&amp;t=60s\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        aria-label=\"Open background music on YouTube in a new tab\"\n      ><\/a>\n    <\/div>\n\n    <audio\n      class=\"th-audio\"\n      preload=\"metadata\"\n      src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/20260915_212557.mp3\"\n    ><\/audio>\n  <\/section>\n<\/div>\n\n<style>\n\/* ========================================\n   1. FULL-WIDTH GATE\n   ======================================== *\/\n\n#th-home-entrance {\n  position: relative;\n  width: 100vw;\n  max-width: none;\n  margin-left: calc(50% - 50vw);\n  margin-right: calc(50% - 50vw);\n  padding: 0;\n  isolation: isolate;\n  line-height: normal;\n\n  \/* Lantern positioning *\/\n  --th-lamp-top: 8%;\n}\n\n#th-home-entrance .th-gate-layer {\n  position: relative;\n  width: 100%;\n  line-height: 0;\n  z-index: 1;\n}\n\n#th-home-entrance .th-gate-image {\n  display: block;\n  width: 100%;\n  max-width: none;\n  height: auto;\n  background: transparent;\n  pointer-events: none;\n  user-select: none;\n}\n\n\/* ========================================\n   2. LANTERNS \u2014 NO VISIBLE CLICK CIRCLES\n   ======================================== *\/\n\n#th-home-entrance button.th-lantern {\n  position: absolute;\n  z-index: 5;\n  top: var(--th-lamp-top);\n  width: 10%;\n  height: 17%;\n\n  margin: 0 !important;\n  padding: 0 !important;\n\n  border: 0 !important;\n  border-radius: 0 !important;\n  outline: 0;\n  box-shadow: none !important;\n\n  background: none !important;\n  background-color: transparent !important;\n  background-image: none !important;\n\n  appearance: none;\n  -webkit-appearance: none;\n\n  cursor: pointer;\n  touch-action: manipulation;\n  overflow: visible;\n  line-height: 0;\n}\n\n#th-home-entrance .th-lantern-left {\n  left: 3.8%;\n}\n\n#th-home-entrance .th-lantern-right {\n  right: 3.8%;\n}\n\n\/* Remove mouse-click focus rings *\/\n#th-home-entrance button.th-lantern:hover,\n#th-home-entrance button.th-lantern:active,\n#th-home-entrance button.th-lantern:focus:not(:focus-visible) {\n  border: 0 !important;\n  outline: 0 !important;\n  box-shadow: none !important;\n  background: none !important;\n}\n\n\/* Preserve keyboard accessibility *\/\n#th-home-entrance button.th-lantern:focus-visible {\n  outline: 2px solid #e8bd74 !important;\n  outline-offset: 3px;\n  box-shadow: none !important;\n  background: none !important;\n}\n\n\/* Soft amber light *\/\n#th-home-entrance .th-light-halo {\n  position: absolute;\n  top: 17%;\n  left: -30%;\n  width: 160%;\n  height: 115%;\n  border-radius: 50%;\n\n  background: radial-gradient(\n    ellipse at center,\n    rgba(255,220,143,.8) 0%,\n    rgba(255,169,45,.48) 22%,\n    rgba(255,128,18,.18) 46%,\n    transparent 74%\n  );\n\n  filter: blur(12px);\n  opacity: 0;\n  pointer-events: none;\n  transition: opacity .35s ease;\n}\n\n\/* Bright centre positioned lower *\/\n#th-home-entrance .th-light-core {\n  position: absolute;\n  top: 58%;\n  left: 43%;\n  width: 14%;\n  height: 20%;\n  border-radius: 50%;\n\n  background: #ffe5a0;\n  filter: blur(4px);\n\n  box-shadow:\n    0 0 12px 5px rgba(255,203,91,.9),\n    0 0 28px 13px rgba(255,155,35,.6);\n\n  opacity: 0;\n  pointer-events: none;\n  transition: opacity .3s ease;\n}\n\n\/* Lantern stays illuminated *\/\n#th-home-entrance .th-lantern.is-on .th-light-halo {\n  opacity: 1;\n}\n\n#th-home-entrance .th-lantern.is-on .th-light-core {\n  opacity: .95;\n}\n\n\/* Flicker only when switched on *\/\n#th-home-entrance .th-lantern.is-lighting .th-light-halo,\n#th-home-entrance .th-lantern.is-lighting .th-light-core {\n  animation: th-ignite .85s linear both;\n}\n\n@keyframes th-ignite {\n  0%   { opacity: 0; }\n  12%  { opacity: .85; }\n  22%  { opacity: .12; }\n  34%  { opacity: 1; }\n  44%  { opacity: .3; }\n  57%  { opacity: .95; }\n  67%  { opacity: .5; }\n  80%  { opacity: 1; }\n  100% { opacity: 1; }\n}\n\n\/* ========================================\n   3. ENTRANCE BUTTONS\n   YOUR 95% ADJUSTMENT IS PRESERVED\n   ======================================== *\/\n\n#th-home-entrance .th-home-buttons {\n  position: absolute;\n  z-index: 3;\n\n  \/* YOUR PREFERRED POSITION *\/\n  top: 95%;\n\n  left: 50%;\n  width: min(35%, 455px);\n  transform: translate(-50%, -50%);\n\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: clamp(12px, 2vw, 28px);\n}\n\n\/* HOW TO PLAY *\/\n#th-home-entrance #th-howto-repair {\n  width: 100%;\n}\n\n#th-home-entrance .th-open {\n  display: block;\n  width: 100%;\n  margin: 0;\n  padding: 0;\n  border: 0;\n  background: transparent;\n  cursor: pointer;\n  transition: filter .2s, transform .2s;\n}\n\n#th-home-entrance .th-open img {\n  display: block;\n  width: 100%;\n  height: auto;\n}\n\n#th-home-entrance .th-open:hover {\n  filter: drop-shadow(\n    0 0 13px rgba(230,166,74,.7)\n  );\n  transform: scale(1.015);\n}\n\n\/* I ENTER THE HOUSE *\/\n#th-home-entrance .th-enter-wrap {\n  width: 100%;\n  text-align: center;\n}\n\n#th-home-entrance .th-enter-link {\n  display: block;\n  width: 100%;\n  cursor: pointer;\n  transition: filter .25s, transform .25s;\n}\n\n#th-home-entrance .th-enter-link img {\n  display: block;\n  width: 100%;\n  height: auto;\n}\n\n#th-home-entrance .th-enter-link:hover {\n  filter: drop-shadow(\n    0 0 12px rgba(196,123,40,.65)\n  );\n  transform: scale(1.025);\n}\n\n\/* ========================================\n   4. HOW TO PLAY \u2014 RESPONSIVE PARCHMENT\n   ======================================== *\/\n\n#th-guide-overlay {\n  display: none !important;\n  position: fixed !important;\n  inset: 0 !important;\n  z-index: 2147483000 !important;\n\n  background: rgba(7,4,3,.88);\n  overflow-y: auto;\n  box-sizing: border-box;\n\n  padding: 16px;\n  align-items: center;\n  justify-content: center;\n}\n\n#th-guide-overlay.th-is-open {\n  display: flex !important;\n}\n\n#th-guide-overlay .th-dialog {\n  position: relative;\n  width: min(100%, 720px);\n  max-width: 100%;\n  margin: auto;\n  outline: none;\n}\n\n#th-guide-overlay .th-paper {\n  position: relative;\n  width: 100%;\n  line-height: 0;\n}\n\n#th-guide-overlay .th-parchment {\n  display: block;\n  width: 100%;\n  height: auto;\n  max-height: calc(100dvh - 60px);\n  object-fit: contain;\n  margin: 0 auto;\n  user-select: none;\n}\n\n#th-guide-overlay .th-close {\n  position: absolute;\n  z-index: 8;\n  top: 0;\n  right: 0;\n\n  width: 42px;\n  height: 42px;\n  border-radius: 50%;\n\n  border: 1px solid #c49b62;\n  background: #23150d;\n  color: #e7c38b;\n  font: 30px Georgia, serif;\n  cursor: pointer;\n}\n\n\/* Audio controls remain aligned to parchment *\/\n#th-guide-overlay .th-play,\n#th-guide-overlay .th-mute {\n  position: absolute;\n  z-index: 4;\n  background: transparent;\n  border: 0;\n  padding: 0;\n  cursor: pointer;\n  touch-action: manipulation;\n}\n\n#th-guide-overlay .th-play {\n  left: 20%;\n  top: 29.5%;\n  width: 9.5%;\n  height: 6%;\n  border-radius: 50%;\n}\n\n#th-guide-overlay .th-seek {\n  position: absolute;\n  z-index: 4;\n  left: 31%;\n  top: 31.6%;\n  width: 30.5%;\n  height: 1.6%;\n  opacity: 0;\n  cursor: pointer;\n  margin: 0;\n}\n\n#th-guide-overlay .th-time {\n  position: absolute;\n  left: 64%;\n  top: 31.5%;\n  width: 11.5%;\n  height: 2.2%;\n\n  display: flex;\n  align-items: center;\n  justify-content: center;\n\n  font: clamp(7px,1.5vw,12px) Georgia, serif;\n  color: #d7b46d;\n  background: #201209;\n  white-space: nowrap;\n  pointer-events: none;\n}\n\n#th-guide-overlay .th-mute {\n  left: 75.3%;\n  top: 30.6%;\n  width: 5.5%;\n  height: 3.6%;\n}\n\n#th-guide-overlay .th-music {\n  position: absolute;\n  z-index: 4;\n  left: 22%;\n  top: 44.1%;\n  width: 56%;\n  height: 5.9%;\n  border-radius: 10px;\n  cursor: pointer;\n}\n\n#th-guide-overlay .th-music:hover {\n  box-shadow: 0 0 14px rgba(234,178,84,.5);\n}\n\n\/* ========================================\n   5. MOBILE AND ACCESSIBILITY\n   ======================================== *\/\n\n#th-home-entrance .th-open:focus-visible,\n#th-home-entrance .th-enter-link:focus-visible,\n#th-guide-overlay button:focus-visible,\n#th-guide-overlay a:focus-visible {\n  outline: 2px solid #e8bd74;\n  outline-offset: 4px;\n}\n\n@media (max-width: 700px) {\n  #th-home-entrance .th-home-buttons {\n    width: 52%;\n\n    \/* Keep your 95% position *\/\n    top: 95%;\n\n    gap: 12px;\n  }\n\n  #th-home-entrance .th-light-halo {\n    filter: blur(6px);\n  }\n\n  #th-home-entrance .th-light-core {\n    filter: blur(2px);\n  }\n\n  #th-guide-overlay {\n    padding: 42px 8px 12px;\n  }\n\n  #th-guide-overlay .th-dialog {\n    width: min(100%, 540px);\n  }\n\n  #th-guide-overlay .th-parchment {\n    max-height: calc(100dvh - 75px);\n  }\n\n  #th-guide-overlay .th-close {\n    width: 34px;\n    height: 34px;\n    top: -36px;\n    right: 7px;\n    font-size: 25px;\n  }\n\n  #th-guide-overlay .th-time {\n    font-size: clamp(5px,1.6vw,9px);\n  }\n}\n\n@media (prefers-reduced-motion: reduce) {\n  #th-home-entrance .th-lantern.is-lighting .th-light-halo,\n  #th-home-entrance .th-lantern.is-lighting .th-light-core {\n    animation: none;\n  }\n\n  #th-home-entrance .th-open,\n  #th-home-entrance .th-enter-link {\n    transition: none;\n  }\n}\n<\/style>\n\n<script>\n(function () {\n  function initHouseEntrance() {\n    var root = document.getElementById('th-home-entrance');\n    var guide = document.getElementById('th-guide-overlay');\n\n    if (!root || !guide || root.dataset.ready === 'yes') {\n      return;\n    }\n\n    root.dataset.ready = 'yes';\n\n    \/* ==================================\n       LANTERN CONTROLS\n       ================================== *\/\n\n    var lanterns = root.querySelectorAll('.th-lantern');\n\n    lanterns.forEach(function(lamp) {\n      var side = lamp.classList.contains('th-lantern-left')\n        ? 'left'\n        : 'right';\n\n      var flickerTimer = null;\n\n      lamp.addEventListener('click', function() {\n        var nowOn = !lamp.classList.contains('is-on');\n\n        clearTimeout(flickerTimer);\n        lamp.classList.remove('is-lighting');\n\n        if (nowOn) {\n          lamp.classList.add('is-on');\n\n          if (!window.matchMedia(\n            '(prefers-reduced-motion: reduce)'\n          ).matches) {\n            void lamp.offsetWidth;\n            lamp.classList.add('is-lighting');\n\n            flickerTimer = window.setTimeout(function() {\n              lamp.classList.remove('is-lighting');\n            }, 900);\n          }\n        } else {\n          lamp.classList.remove('is-on');\n        }\n\n        lamp.setAttribute('aria-pressed', String(nowOn));\n        lamp.setAttribute(\n          'aria-label',\n          (nowOn ? 'Extinguish' : 'Light') +\n          ' the ' + side + ' lantern'\n        );\n      });\n    });\n\n    \/* ==================================\n       HOW TO PLAY GUIDE\n       ================================== *\/\n\n    var openGuideButton = root.querySelector('.th-open');\n    var closeGuideButton = guide.querySelector('.th-close');\n    var dialog = guide.querySelector('.th-dialog');\n\n    var audio = guide.querySelector('.th-audio');\n    var play = guide.querySelector('.th-play');\n    var mute = guide.querySelector('.th-mute');\n    var seek = guide.querySelector('.th-seek');\n    var time = guide.querySelector('.th-time');\n\n    var previousBodyOverflow = '';\n\n    function formatTime(seconds) {\n      if (!isFinite(seconds)) return '0:00';\n\n      var minutes = Math.floor(seconds \/ 60);\n      var remaining = Math.floor(seconds % 60);\n\n      return minutes + ':' +\n        ('0' + remaining).slice(-2);\n    }\n\n    function refreshAudio() {\n      time.textContent =\n        formatTime(audio.currentTime) +\n        ' \/ ' +\n        formatTime(audio.duration);\n\n      if (isFinite(audio.duration) && audio.duration > 0) {\n        seek.value = Math.round(\n          audio.currentTime \/ audio.duration * 1000\n        );\n      }\n\n      play.setAttribute(\n        'aria-pressed',\n        String(!audio.paused)\n      );\n\n      mute.setAttribute(\n        'aria-pressed',\n        String(audio.muted)\n      );\n    }\n\n    function openGuide() {\n      \/* Avoid clipping caused by WordPress containers *\/\n      if (guide.parentNode !== document.body) {\n        document.body.appendChild(guide);\n      }\n\n      previousBodyOverflow = document.body.style.overflow;\n      document.body.style.overflow = 'hidden';\n\n      guide.classList.add('th-is-open');\n      guide.setAttribute('aria-hidden', 'false');\n      dialog.focus();\n    }\n\n    function closeGuide() {\n      guide.classList.remove('th-is-open');\n      guide.setAttribute('aria-hidden', 'true');\n\n      document.body.style.overflow = previousBodyOverflow;\n      audio.pause();\n      openGuideButton.focus();\n    }\n\n    openGuideButton.addEventListener('click', openGuide);\n    closeGuideButton.addEventListener('click', closeGuide);\n\n    guide.addEventListener('click', function(event) {\n      if (event.target === guide) {\n        closeGuide();\n      }\n    });\n\n    document.addEventListener('keydown', function(event) {\n      if (\n        event.key === 'Escape' &&\n        guide.classList.contains('th-is-open')\n      ) {\n        closeGuide();\n      }\n    });\n\n    play.addEventListener('click', function() {\n      if (audio.paused) {\n        audio.play().catch(function(error) {\n          console.error(\n            'Audio playback failed:',\n            error\n          );\n        });\n      } else {\n        audio.pause();\n      }\n    });\n\n    mute.addEventListener('click', function() {\n      audio.muted = !audio.muted;\n      refreshAudio();\n    });\n\n    seek.addEventListener('input', function() {\n      if (isFinite(audio.duration) && audio.duration > 0) {\n        audio.currentTime =\n          (Number(seek.value) \/ 1000) * audio.duration;\n      }\n    });\n\n    [\n      'loadedmetadata',\n      'durationchange',\n      'timeupdate',\n      'play',\n      'pause',\n      'ended',\n      'volumechange'\n    ].forEach(function(eventName) {\n      audio.addEventListener(eventName, refreshAudio);\n    });\n\n    refreshAudio();\n\n    \/* ==================================\n       ENTER THE HOUSE \u2014 FOOTSTEPS\n       ================================== *\/\n\n    var enterLink = root.querySelector('#th-enter-link');\n    var steps = root.querySelector('#th-enter-steps');\n    var entering = false;\n\n    enterLink.addEventListener('click', function(event) {\n      if (\n        event.defaultPrevented ||\n        event.button !== 0 ||\n        event.ctrlKey ||\n        event.metaKey ||\n        event.shiftKey ||\n        event.altKey\n      ) {\n        return;\n      }\n\n      event.preventDefault();\n\n      if (entering) return;\n      entering = true;\n\n      var destination = enterLink.href;\n      var finished = false;\n\n      function go() {\n        if (finished) return;\n        finished = true;\n\n        steps.pause();\n        window.location.assign(destination);\n      }\n\n      try {\n        steps.currentTime = 0;\n\n        var playback = steps.play();\n\n        if (\n          playback &&\n          typeof playback.catch === 'function'\n        ) {\n          playback.catch(go);\n        }\n      } catch (error) {\n        go();\n        return;\n      }\n\n      window.setTimeout(go, 2000);\n    });\n  }\n\n  if (document.readyState === 'loading') {\n    document.addEventListener(\n      'DOMContentLoaded',\n      initHouseEntrance\n    );\n  } else {\n    initHouseEntrance();\n  }\n})();\n<\/script>\n\n\n\n<h2 class=\"wp-block-heading has-text-align-center\"><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-base-color\">Welcome the House<\/mark><\/h2>\n\n\n\n<!-- =========================================\n THE HOUSE \u2014 HAUNTED VICTORIAN SPYGLASS\n Real PNG Ghost Edition \u2014 complete replacement\n========================================= -->\n\n<div id=\"th-spyglass-activity\">\n\n  <!-- ANTIQUE SPYGLASS BUTTON -->\n  <button id=\"th-spyglass-open\" type=\"button\" aria-label=\"Look through the antique spyglass\" title=\"Look through the spyglass\">\n    <img decoding=\"async\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/Antique-Brass-Spyglass-with-Engravings.png\" alt=\"Antique brass Victorian spyglass\">\n  <\/button>\n\n  <!-- FULLSCREEN MANSION VIEWER -->\n  <div id=\"th-spyglass-viewer\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Explore the haunted mansion\" aria-hidden=\"true\">\n\n    <img decoding=\"async\" id=\"th-spyglass-photo\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/nathan-mcdine-Sz2UlMzTv4I-unsplash-1-scaled.jpg\" alt=\"A Gothic mansion surrounded by trees\">\n\n    <div class=\"th-spyglass-darkness\"><\/div>\n\n    <!-- MOVABLE MAGNIFYING LENS -->\n    <div id=\"th-spyglass-lens\" aria-hidden=\"true\">\n      <div id=\"th-spyglass-magnified\">\n        <img decoding=\"async\" id=\"th-spyglass-lens-photo\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/nathan-mcdine-Sz2UlMzTv4I-unsplash-1-scaled.jpg\" alt=\"\">\n        <div id=\"th-spyglass-ghost-layer\"><\/div>\n      <\/div>\n    <\/div>\n\n    <p class=\"th-spyglass-hint\">\n      Look carefully at the windows&#8230;\n      Someone may be watching.\n    <\/p>\n\n    <button id=\"th-spyglass-close\" type=\"button\" aria-label=\"Close spyglass\">\u00d7<\/button>\n\n  <\/div>\n\n  <!-- FOREST AMBIENCE -->\n  <audio id=\"th-spyglass-audio\" preload=\"none\" loop=\"\">\n    <source src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/810428__klankbeeld__park-forest-loonse-en-drunense-duinen-netherlands-1125-am-150410_0602.flac\" type=\"audio\/flac\">\n  <\/audio>\n\n<\/div>\n\n<style>\n\/* ========================================\n   SPYGLASS BUTTON\n======================================== *\/\n\n#th-spyglass-open {\n  display: block;\n  width: 170px;\n  height: auto;\n  margin: 20px auto;\n  padding: 0;\n  border: 0 !important;\n  background: transparent !important;\n  box-shadow: none !important;\n  cursor: pointer;\n  transform: rotate(-8deg);\n  transition: transform .25s ease,\n              filter .25s ease;\n}\n\n#th-spyglass-open img {\n  display: block;\n  width: 100%;\n  height: auto;\n  max-width: none;\n}\n\n#th-spyglass-open:hover {\n  transform: rotate(-8deg) scale(1.08);\n  filter: drop-shadow(\n    0 0 12px rgba(215,167,75,.7)\n  );\n}\n\n#th-spyglass-open:focus:not(:focus-visible) {\n  outline: none;\n}\n\n#th-spyglass-open:focus-visible {\n  outline: 2px solid #d6ad69;\n  outline-offset: 5px;\n}\n\n\/* ========================================\n   FULLSCREEN VIEWER\n======================================== *\/\n\n#th-spyglass-viewer {\n  display: none;\n  position: fixed;\n  inset: 0;\n  width: 100%;\n  height: 100vh;\n  height: 100dvh;\n  z-index: 2147483100;\n  overflow: hidden;\n  background: #000;\n  cursor: none;\n  touch-action: none;\n}\n\n#th-spyglass-viewer.th-active {\n  display: block;\n}\n\n#th-spyglass-photo {\n  position: absolute;\n  inset: 0;\n  display: block;\n  width: 100%;\n  height: 100%;\n  max-width: none;\n  object-fit: cover;\n  object-position: center;\n  pointer-events: none;\n  user-select: none;\n}\n\n#th-spyglass-viewer .th-spyglass-darkness {\n  position: absolute;\n  inset: 0;\n  background: rgba(0,0,0,.78);\n  pointer-events: none;\n}\n\n\/* ========================================\n   BRASS MAGNIFYING LENS\n======================================== *\/\n\n#th-spyglass-lens {\n  position: absolute;\n  left: 50%;\n  top: 50%;\n  width: 150px;\n  height: 150px;\n  box-sizing: border-box;\n  border: 4px solid #b89a5e;\n  border-radius: 50%;\n  overflow: hidden;\n  pointer-events: none;\n  transform: translate(-50%,-50%);\n  background: #080706;\n  box-shadow:\n    0 0 0 3px #21160d,\n    0 0 0 5px rgba(208,167,89,.4),\n    0 0 26px rgba(0,0,0,.95);\n  z-index: 20;\n}\n\n#th-spyglass-magnified {\n  position: absolute;\n  left: 0;\n  top: 0;\n  pointer-events: none;\n}\n\n#th-spyglass-lens-photo {\n  display: block;\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  max-width: none;\n  pointer-events: none;\n  user-select: none;\n}\n\n#th-spyglass-ghost-layer {\n  position: absolute;\n  inset: 0;\n  overflow: hidden;\n  pointer-events: none;\n}\n\n\/* ========================================\n   GHOST WINDOWS AND SILHOUETTES\n======================================== *\/\n\n#th-spyglass-ghost-layer .th-ghost-window {\n  position: absolute;\n  overflow: hidden;\n  pointer-events: none;\n}\n\n#th-spyglass-ghost-layer .th-ghost-figure {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  opacity: 0;\n  transform: translateY(6%);\n  transition:\n    opacity 1.6s ease,\n    transform 2s ease;\n  filter:\n    blur(.3px)\n    drop-shadow(0 0 2px rgba(225,231,235,.45));\n}\n\n#th-spyglass-ghost-layer\n.th-ghost-window.th-haunted .th-ghost-figure {\n  opacity: .9;\n  transform: translateY(0);\n}\n\n#th-spyglass-ghost-layer .th-ghost-figure img {\n  display: block;\n  width: 100%;\n  height: 100%;\n  max-width: none;\n  object-fit: contain;\n  object-position: center bottom;\n  filter: grayscale(1) brightness(1.22);\n}\n\n\/* ========================================\n   HINT AND CLOSE BUTTON\n======================================== *\/\n\n#th-spyglass-viewer .th-spyglass-hint {\n  position: absolute;\n  bottom: 20px;\n  left: 50%;\n  width: max-content;\n  max-width: calc(100% - 30px);\n  margin: 0;\n  transform: translateX(-50%);\n  color: #c5ae87;\n  font: italic 15px Georgia, serif;\n  text-align: center;\n  text-shadow: 0 2px 5px #000;\n  pointer-events: none;\n  z-index: 25;\n}\n\n#th-spyglass-close {\n  position: absolute;\n  top: 20px;\n  right: 24px;\n  width: 48px;\n  height: 48px;\n  padding: 0;\n  border: 1px solid #a88754;\n  border-radius: 50%;\n  background: rgba(20,12,8,.9);\n  color: #e6c38b;\n  font: 32px\/46px Georgia, serif;\n  text-align: center;\n  cursor: pointer;\n  z-index: 50;\n}\n\n#th-spyglass-close:hover {\n  background: #50311b;\n}\n\n#th-spyglass-close:focus-visible {\n  outline: 2px solid #f2d49b;\n  outline-offset: 3px;\n}\n\n\/* ========================================\n   MOBILE\n======================================== *\/\n\n@media (max-width:700px) {\n  #th-spyglass-open {\n    width: 145px;\n  }\n\n  #th-spyglass-lens {\n    width: 110px;\n    height: 110px;\n  }\n\n  #th-spyglass-close {\n    top: 12px;\n    right: 12px;\n  }\n\n  #th-spyglass-viewer .th-spyglass-hint {\n    bottom: 12px;\n    font-size: 12px;\n  }\n}\n\n@media (prefers-reduced-motion:reduce) {\n  #th-spyglass-ghost-layer .th-ghost-figure {\n    transition: none;\n  }\n}\n<\/style>\n\n<script>\n(function () {\n  function init() {\n    var button = document.getElementById('th-spyglass-open');\n    var viewer = document.getElementById('th-spyglass-viewer');\n    var close = document.getElementById('th-spyglass-close');\n    var lens = document.getElementById('th-spyglass-lens');\n    var magnified = document.getElementById('th-spyglass-magnified');\n    var photo = document.getElementById('th-spyglass-photo');\n    var ghosts = document.getElementById('th-spyglass-ghost-layer');\n    var audio = document.getElementById('th-spyglass-audio');\n    if (!button || !viewer || !close || !lens || !magnified || !photo || !ghosts) return;\n    if (button.dataset.spyglassReady === 'yes') return;\n    button.dataset.spyglassReady = 'yes';\n\n    var zoom = 3.5, opened = false, interval = null, hide = null;\n    var previousOverflow = '', lastWindow = -1, lastShape = -1;\n    var lastX = 0, lastY = 0;\n\n    \/\/ Locations in the original photograph, as percentages.\n    var windows = [\n      [38.3,49.0,1.8,2.5], [40.6,49.0,1.8,2.5],\n      [38.3,53.8,1.8,3.0], [40.6,53.8,1.8,3.0],\n      [46.5,50.4,2.0,2.7], [48.8,50.4,2.0,2.7]\n    ];\n\n    \/\/ Ten approved Victorian ghost PNGs from the WordPress Media Library.\n    var ghostImages = [\n      'https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/01_two_girls.png',\n      'https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/02_woman_fan.png',\n      'https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/03_man_top_hat.png',\n      'https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/04_old_woman.png',\n      'https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/05_man_broom.png',\n      'https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/06_candle_maid.png',\n      'https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/07_man_holding_head.png',\n      'https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/08_mother_and_baby.png',\n      'https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/09_crying_woman.png',\n      'https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/10_veiled_figure.png'\n    ];\n    \/\/ Preload them when the page is ready, so their appearances are smooth.\n    ghostImages.forEach(function (url) { var preload = new Image(); preload.src = url; });\n    var windowNodes = windows.map(function (p) {\n      var w = document.createElement('div');\n      w.className = 'th-ghost-window';\n      w.style.left = p[0] + '%'; w.style.top = p[1] + '%';\n      w.style.width = p[2] + '%'; w.style.height = p[3] + '%';\n      var f = document.createElement('div');\n      f.className = 'th-ghost-figure';\n      w.appendChild(f); ghosts.appendChild(w);\n      return w;\n    });\n    function different(n, last) {\n      var choice = Math.floor(Math.random() * n);\n      if (n > 1 && choice === last) choice = (choice + 1 + Math.floor(Math.random() * (n - 1))) % n;\n      return choice;\n    }\n    function clearGhosts() {\n      clearInterval(interval); clearTimeout(hide);\n      interval = null; hide = null;\n      windowNodes.forEach(function (w) { w.classList.remove('th-haunted'); });\n    }\n    function showGhost() {\n      if (!opened) return;\n      windowNodes.forEach(function (w) { w.classList.remove('th-haunted'); });\n      clearTimeout(hide);\n      var wi = different(windowNodes.length, lastWindow);\n      var si = different(ghostImages.length, lastShape);\n      lastWindow = wi; lastShape = si;\n      var w = windowNodes[wi];\n      var ghostImage = w.firstChild.querySelector('img');\n      if (!ghostImage) {\n        ghostImage = document.createElement('img');\n        ghostImage.alt = '';\n        ghostImage.setAttribute('aria-hidden', 'true');\n        ghostImage.decoding = 'async';\n        w.firstChild.appendChild(ghostImage);\n      }\n      ghostImage.src = ghostImages[si];\n      \/\/ Restart the fade cleanly on the new silhouette.\n      void w.offsetWidth;\n      w.classList.add('th-haunted');\n      hide = setTimeout(function () { w.classList.remove('th-haunted'); }, 4600);\n    }\n    function move(clientX, clientY) {\n      if (!opened) return;\n      var r = viewer.getBoundingClientRect();\n      var x = Math.max(0, Math.min(clientX - r.left, r.width));\n      var y = Math.max(0, Math.min(clientY - r.top, r.height));\n      lastX = x; lastY = y;\n      lens.style.left = x + 'px'; lens.style.top = y + 'px';\n      var aspect = (photo.naturalWidth || 1100) \/ (photo.naturalHeight || 1376);\n      var coverW = Math.max(r.width, r.height * aspect);\n      var coverH = coverW \/ aspect;\n      var cropX = (r.width - coverW) \/ 2;\n      var cropY = (r.height - coverH) \/ 2;\n      var bigW = coverW * zoom, bigH = coverH * zoom;\n      magnified.style.width = bigW + 'px';\n      magnified.style.height = bigH + 'px';\n      magnified.style.left = (lens.clientWidth \/ 2 - ((x - cropX) \/ coverW) * bigW) + 'px';\n      magnified.style.top = (lens.clientHeight \/ 2 - ((y - cropY) \/ coverH) * bigH) + 'px';\n    }\n    function openViewer() {\n      if (opened) return;\n      opened = true;\n      if (viewer.parentNode !== document.body) document.body.appendChild(viewer);\n      previousOverflow = document.body.style.overflow;\n      viewer.style.display = 'block';\n      viewer.classList.add('th-active');\n      viewer.setAttribute('aria-hidden', 'false');\n      document.body.style.overflow = 'hidden';\n      move(window.innerWidth \/ 2, window.innerHeight \/ 2);\n      clearGhosts();\n      \/\/ First ghost after 10 seconds, then one every 10 seconds.\n      interval = setInterval(showGhost, 10000);\n      if (audio) {\n        try {\n          audio.currentTime = 0;\n          var playing = audio.play();\n          if (playing && playing.catch) playing.catch(function () {});\n        } catch (e) {}\n      }\n    }\n    function closeViewer() {\n      if (!opened) return;\n      opened = false;\n      clearGhosts();\n      viewer.classList.remove('th-active');\n      viewer.style.display = 'none';\n      viewer.setAttribute('aria-hidden', 'true');\n      document.body.style.overflow = previousOverflow;\n      if (audio) { audio.pause(); try { audio.currentTime = 0; } catch (e) {} }\n      if (document.fullscreenElement === viewer && document.exitFullscreen) {\n        try { var exit = document.exitFullscreen(); if (exit && exit.catch) exit.catch(function () {}); } catch (e) {}\n      }\n    }\n    button.addEventListener('click', openViewer);\n    close.addEventListener('click', closeViewer);\n    viewer.addEventListener('pointermove', function (e) { move(e.clientX, e.clientY); });\n    viewer.addEventListener('pointerdown', function (e) { move(e.clientX, e.clientY); });\n    viewer.addEventListener('touchmove', function (e) {\n      if (!e.touches.length) return;\n      e.preventDefault(); move(e.touches[0].clientX, e.touches[0].clientY);\n    }, {passive:false});\n    window.addEventListener('resize', function () { if (opened) move(lastX, lastY); });\n    photo.addEventListener('load', function () { if (opened) move(lastX, lastY); });\n    document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeViewer(); });\n  }\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);\n  else init();\n})();\n<\/script>\n\n\n<style>\n.house-side-menu {\n  position: fixed;\n  left: 18px;\n  top: 50%;\n  transform: translateY(-50%);\n  display: flex;\n  flex-direction: column;\n  gap: 11px;\n  padding-left: 10px;\n  z-index: 999990;\n}\n\n.house-side-menu::before {\n  content: \"\";\n  position: absolute;\n  left: 0;\n  top: 0;\n  bottom: 0;\n  width: 2px;\n  background: rgba(255,255,255,0.35);\n}\n\n.house-menu-button {\n  position: relative;\n  width: 70.5px;\n  height: 70.5px;\n  padding: 0;\n  margin: 0;\n  border: 0;\n  background: transparent;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  z-index: 2;\n}\n\n.house-menu-button img {\n  width: 64.5px;\n  height: 64.5px;\n  object-fit: contain;\n  display: block;\n  transition: transform 0.18s ease, filter 0.18s ease;\n}\n\n.house-menu-button.house-ear img {\n  width: 60px;\n  height: 69px;\n}\n\n.house-menu-button.house-eye img {\n  width: 120px;\n  height: 136.5px;\n}\n\n.house-menu-button:hover img {\n  transform: translateX(5px) scale(1.08);\n  filter: brightness(1.08);\n}\n\n.house-menu-label {\n  position: absolute;\n  left: 53px;\n  top: 50%;\n  transform: translateY(-50%);\n  white-space: nowrap;\n  font-family: Georgia, \"Times New Roman\", serif;\n  font-size: 14px;\n  line-height: 1;\n  color: #fff;\n  opacity: 0;\n  pointer-events: none;\n  transition: opacity 0.18s ease;\n}\n\n.house-menu-button:hover .house-menu-label {\n  opacity: 1;\n}\n\n\n\/* =========================================================\n   HELP POP-OUT\n   ========================================================= *\/\n\n.house-help-box {\n  position: fixed;\n  left: 82px;\n  top: 50%;\n  transform: translateY(-50%);\n\n  width: 240px;\n  max-width: calc(100vw - 110px);\n\n  padding: 18px 20px 20px;\n\n  background: rgba(245, 238, 216, 0.97);\n  color: #222;\n\n  border: 1px solid rgba(70, 55, 35, 0.45);\n  box-shadow: 0 5px 18px rgba(0,0,0,0.28);\n\n  font-family: Georgia, \"Times New Roman\", serif;\n  font-size: 15px;\n  line-height: 1.45;\n\n  z-index: 999995;\n\n  display: none;\n}\n\n.house-help-box.is-open {\n  display: block;\n}\n\n.house-help-close {\n  position: absolute;\n  top: 5px;\n  right: 8px;\n\n  border: 0;\n  background: transparent;\n\n  color: #333;\n  font-family: Arial, sans-serif;\n  font-size: 20px;\n  line-height: 1;\n\n  padding: 0;\n  cursor: pointer;\n}\n\n.house-help-close:hover {\n  opacity: 0.55;\n}\n\n.house-help-text {\n  padding-right: 12px;\n}\n\n\n\/* =========================================================\n   PAPER NOTE BOXES\n   ========================================================= *\/\n\n.house-note-box,\n.house-notes-box {\n  position: fixed;\n\n  left: 82px;\n  top: 50%;\n  transform: translateY(-50%);\n\n  width: 285px;\n  max-width: calc(100vw - 115px);\n\n  background: rgba(245, 238, 216, 0.98);\n  color: #222;\n\n  border: 1px solid rgba(70, 55, 35, 0.45);\n  box-shadow: 0 5px 20px rgba(0,0,0,0.30);\n\n  font-family: Georgia, \"Times New Roman\", serif;\n\n  z-index: 999996;\n\n  display: none;\n}\n\n.house-note-box.is-open,\n.house-notes-box.is-open {\n  display: block;\n}\n\n.house-note-header,\n.house-notes-header {\n  position: relative;\n\n  padding: 13px 38px 10px 17px;\n\n  border-bottom: 1px solid rgba(70,55,35,0.25);\n\n  font-size: 16px;\n  line-height: 1.2;\n}\n\n.house-note-close,\n.house-notes-close {\n  position: absolute;\n\n  top: 5px;\n  right: 8px;\n\n  border: 0;\n  background: transparent;\n\n  color: #333;\n\n  font-family: Arial, sans-serif;\n  font-size: 20px;\n  line-height: 1;\n\n  padding: 0;\n  cursor: pointer;\n}\n\n.house-note-close:hover,\n.house-notes-close:hover {\n  opacity: 0.55;\n}\n\n\n\/* =========================================================\n   NOTE FORM\n   ========================================================= *\/\n\n.house-note-content {\n  padding: 15px 17px 17px;\n}\n\n.house-note-content label {\n  display: block;\n  margin-bottom: 5px;\n  font-size: 14px;\n}\n\n.house-note-content input,\n.house-note-content textarea {\n  box-sizing: border-box;\n\n  width: 100%;\n\n  border: 1px solid rgba(70,55,35,0.35);\n\n  background: rgba(255,255,255,0.72);\n\n  color: #222;\n\n  font-family: Georgia, \"Times New Roman\", serif;\n  font-size: 14px;\n\n  padding: 8px;\n\n  outline: none;\n}\n\n.house-note-content input:focus,\n.house-note-content textarea:focus {\n  border-color: rgba(70,55,35,0.7);\n}\n\n.house-note-content textarea {\n  min-height: 105px;\n  resize: vertical;\n}\n\n.house-note-field {\n  margin-bottom: 12px;\n}\n\n.house-note-submit {\n  border: 1px solid rgba(70,55,35,0.45);\n\n  background: rgba(70,55,35,0.12);\n\n  color: #222;\n\n  font-family: Georgia, \"Times New Roman\", serif;\n  font-size: 14px;\n\n  padding: 7px 13px;\n\n  cursor: pointer;\n}\n\n.house-note-submit:hover {\n  background: rgba(70,55,35,0.20);\n}\n\n.house-note-submit:disabled {\n  opacity: 0.55;\n  cursor: wait;\n}\n\n.house-note-status {\n  margin-top: 10px;\n\n  font-size: 13px;\n  line-height: 1.4;\n}\n\n.house-note-status.success {\n  color: #315b35;\n}\n\n.house-note-status.error {\n  color: #8a3028;\n}\n\n\n\/* =========================================================\n   PAPER NOTES LIST\n   ========================================================= *\/\n\n.house-notes-content {\n  padding: 14px 17px 17px;\n  max-height: 55vh;\n  overflow-y: auto;\n}\n\n.house-notes-intro {\n  margin-bottom: 12px;\n\n  font-size: 13px;\n  line-height: 1.4;\n\n  opacity: 0.75;\n}\n\n.house-single-note {\n  padding: 10px 0;\n\n  border-bottom: 1px solid rgba(70,55,35,0.22);\n}\n\n.house-single-note:last-child {\n  border-bottom: 0;\n}\n\n.house-single-note-author {\n  margin-bottom: 4px;\n\n  font-size: 13px;\n  font-weight: bold;\n}\n\n.house-single-note-date {\n  margin-bottom: 6px;\n\n  font-size: 11px;\n\n  opacity: 0.6;\n}\n\n.house-single-note-text {\n  font-size: 14px;\n  line-height: 1.45;\n\n  white-space: pre-wrap;\n}\n\n.house-no-notes {\n  font-size: 14px;\n  line-height: 1.45;\n  opacity: 0.75;\n}\n\n\n\/* =========================================================\n   ARTWORK\n   ========================================================= *\/\n\n#house-art-overlay {\n  position: fixed;\n  inset: 0;\n  z-index: 999999;\n\n  display: none;\n\n  align-items: center;\n  justify-content: center;\n\n  background: rgba(0,0,0,0.96);\n}\n\n#house-art-overlay img {\n  max-width: 96vw;\n  max-height: 94vh;\n\n  width: auto;\n  height: auto;\n\n  object-fit: contain;\n\n  display: block;\n}\n\n#house-art-close {\n  position: absolute;\n\n  top: 16px;\n  right: 22px;\n\n  border: 0;\n  background: transparent;\n\n  color: #fff;\n\n  font-family: Arial, sans-serif;\n  font-size: 32px;\n  line-height: 1;\n\n  cursor: pointer;\n\n  z-index: 2;\n}\n\n#house-art-close:hover {\n  opacity: 0.7;\n}\n\n\n\/* =========================================================\n   MOBILE\n   ========================================================= *\/\n\n@media (max-width: 700px) {\n\n  .house-side-menu {\n    left: 6px;\n    gap: 7px;\n    padding-left: 7px;\n  }\n\n  .house-menu-button {\n    width: 54px;\n    height: 54px;\n  }\n\n  .house-menu-button img {\n    width: 48px;\n    height: 48px;\n  }\n\n  .house-menu-button.house-ear img {\n    width: 45px;\n    height: 51px;\n  }\n\n  .house-menu-button.house-eye img {\n    width: 91.5px;\n    height: 105px;\n  }\n\n  .house-menu-label {\n    display: none;\n  }\n\n  .house-help-box,\n  .house-note-box,\n  .house-notes-box {\n    left: 51px;\n    top: 50%;\n\n    width: 220px;\n    max-width: calc(100vw - 65px);\n  }\n\n  .house-help-box {\n    padding: 16px 17px 18px;\n    font-size: 14px;\n  }\n\n  .house-note-header,\n  .house-notes-header {\n    font-size: 15px;\n  }\n\n  .house-note-content {\n    padding: 14px;\n  }\n\n  .house-notes-content {\n    max-height: 52vh;\n  }\n\n  #house-art-overlay img {\n    max-width: 94vw;\n    max-height: 90vh;\n  }\n\n  #house-art-close {\n    top: 10px;\n    right: 14px;\n    font-size: 28px;\n  }\n}\n<\/style>\n\n\n<!-- =========================================================\n     THE HOUSE SIDE MENU\n     ========================================================= -->\n\n<div id=\"house-side-menu\" class=\"house-side-menu\">\n\n  <button type=\"button\" class=\"house-menu-button house-story\" aria-label=\"Listen to the Story\">\n\n    <img decoding=\"async\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/Antik-blomsterknap-100px.png\" alt=\"\">\n\n    <span class=\"house-menu-label\">\n      Listen to the Story\n    <\/span>\n\n  <\/button>\n\n\n  <button type=\"button\" class=\"house-menu-button house-eye\" aria-label=\"See the Art\">\n\n    <img decoding=\"async\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/eye_pendant-removebg-preview.png\" alt=\"\">\n\n    <span class=\"house-menu-label\">\n      See the Art\n    <\/span>\n\n  <\/button>\n\n\n  <button type=\"button\" class=\"house-menu-button house-ear\" aria-label=\"Listen to the House\">\n\n    <img decoding=\"async\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/ear-removebg-preview.png\" alt=\"\">\n\n    <span class=\"house-menu-label\">\n      Listen to the House\n    <\/span>\n\n  <\/button>\n\n\n  <button type=\"button\" class=\"house-menu-button house-help\" aria-label=\"Get Help\">\n\n    <img decoding=\"async\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/questionmark-removebg-preview-1.png\" alt=\"\">\n\n    <span class=\"house-menu-label\">\n      Get Help\n    <\/span>\n\n  <\/button>\n\n\n  <button type=\"button\" class=\"house-menu-button house-note\" aria-label=\"Leave a note behind\">\n\n    <img decoding=\"async\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/Inkpot-removebg-preview.png\" alt=\"\">\n\n    <span class=\"house-menu-label\">\n      leave a note behind\n    <\/span>\n\n  <\/button>\n\n\n  <button type=\"button\" class=\"house-menu-button house-notes\" aria-label=\"Search for paper notes\">\n\n    <img decoding=\"async\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/Louope-removebg-preview.png\" alt=\"\">\n\n    <span class=\"house-menu-label\">\n      search for paper notes\n    <\/span>\n\n  <\/button>\n\n<\/div>\n\n\n<!-- =========================================================\n     HELP\n     ========================================================= -->\n\n<div id=\"house-help-box\" class=\"house-help-box\" role=\"dialog\" aria-hidden=\"true\">\n\n  <button type=\"button\" id=\"house-help-close\" class=\"house-help-close\" aria-label=\"Close help\">\n    \u00d7\n  <\/button>\n\n  <div id=\"house-help-text\" class=\"house-help-text\">\n  <\/div>\n\n<\/div>\n\n\n<!-- =========================================================\n     LEAVE A NOTE\n     ========================================================= -->\n\n<div id=\"house-note-box\" class=\"house-note-box\" role=\"dialog\" aria-hidden=\"true\">\n\n  <div class=\"house-note-header\">\n\n    Leave a note behind\n\n    <button type=\"button\" id=\"house-note-close\" class=\"house-note-close\" aria-label=\"Close note box\">\n      \u00d7\n    <\/button>\n\n  <\/div>\n\n\n  <div class=\"house-note-content\">\n\n    <form id=\"house-note-form\">\n\n      <div class=\"house-note-field\">\n\n        <label for=\"house-note-author\">\n          Name\n        <\/label>\n\n        <input type=\"text\" id=\"house-note-author\" name=\"author\" maxlength=\"245\" autocomplete=\"name\" required=\"\">\n\n      <\/div>\n\n\n      <div class=\"house-note-field\">\n\n        <label for=\"house-note-email\">\n          Email\n        <\/label>\n\n        <input type=\"email\" id=\"house-note-email\" name=\"email\" autocomplete=\"email\" required=\"\">\n\n      <\/div>\n\n\n      <div class=\"house-note-field\">\n\n        <label for=\"house-note-comment\">\n          Note\n        <\/label>\n\n        <textarea id=\"house-note-comment\" name=\"comment\" required=\"\"><\/textarea>\n\n      <\/div>\n\n\n      <button type=\"submit\" id=\"house-note-submit\" class=\"house-note-submit\">\n        Leave note\n      <\/button>\n\n\n      <div id=\"house-note-status\" class=\"house-note-status\"><\/div>\n\n    <\/form>\n\n  <\/div>\n\n<\/div>\n\n\n<!-- =========================================================\n     SHOW PAPER NOTES\n     ========================================================= -->\n\n<div id=\"house-notes-box\" class=\"house-notes-box\" role=\"dialog\" aria-hidden=\"true\">\n\n  <div class=\"house-notes-header\">\n\n    Paper notes\n\n    <button type=\"button\" id=\"house-notes-close\" class=\"house-notes-close\" aria-label=\"Close paper notes\">\n      \u00d7\n    <\/button>\n\n  <\/div>\n\n\n  <div id=\"house-notes-content\" class=\"house-notes-content\">\n\n    <div class=\"house-notes-intro\">\n      Notes left behind on this page:\n    <\/div>\n\n    <div id=\"house-notes-list\">\n      Loading\u2026\n    <\/div>\n\n  <\/div>\n\n<\/div>\n\n\n<!-- =========================================================\n     ARTWORK\n     ========================================================= -->\n\n<div id=\"house-art-overlay\">\n\n  <button id=\"house-art-close\" type=\"button\" aria-label=\"Close artwork\">\n    \u00d7\n  <\/button>\n\n  <img decoding=\"async\" id=\"house-art-image\" src=\"\" alt=\"\">\n\n<\/div>\n\n\n<script>\n(function () {\n\n  function initHouseMenu() {\n\n    const menu =\n      document.getElementById(\"house-side-menu\");\n\n    if (!menu) {\n      return;\n    }\n\n    if (menu.dataset.houseMenuReady === \"true\") {\n      return;\n    }\n\n    menu.dataset.houseMenuReady = \"true\";\n\n\n    \/* =======================================================\n       PAGE SETTINGS\n       ======================================================= *\/\n\n    function getFiles() {\n\n      return window.houseMenuFiles || {\n\n        story: \"\",\n        art: \"\",\n        house: \"\",\n        help: \"\"\n\n      };\n\n    }\n\n\n    \/* =======================================================\n       CURRENT WORDPRESS PAGE \/ POST ID\n       ======================================================= *\/\n\n    let currentPostId = null;\n\n\n    \/*\n     * WordPress normally places one of these classes\n     * on the <body> element:\n     *\n     * page-id-123\n     * postid-123\n     *\n     * We support both.\n     *\/\n\n    function findPostIdFromBody() {\n\n      const bodyClasses =\n        document.body.className || \"\";\n\n\n      \/*\n       * Regular WordPress Page\n       *\/\n\n      const pageMatch =\n        bodyClasses.match(\n          \/(?:^|\\s)page-id-(\\d+)(?:\\s|$)\/\n        );\n\n\n      if (pageMatch && pageMatch[1]) {\n\n        return parseInt(\n          pageMatch[1],\n          10\n        );\n\n      }\n\n\n      \/*\n       * Regular WordPress Post\n       *\/\n\n      const postMatch =\n        bodyClasses.match(\n          \/(?:^|\\s)postid-(\\d+)(?:\\s|$)\/\n        );\n\n\n      if (postMatch && postMatch[1]) {\n\n        return parseInt(\n          postMatch[1],\n          10\n        );\n\n      }\n\n\n      return null;\n\n    }\n\n\n    \/*\n     * Find the current WordPress Page\/Post ID.\n     *\n     * The body class is the preferred method.\n     *\n     * REST API URL matching is retained as a fallback\n     * for unusual WordPress templates.\n     *\/\n\n    async function findCurrentPostId() {\n\n      if (currentPostId) {\n\n        return currentPostId;\n\n      }\n\n\n      \/* -----------------------------------------------------\n         FIRST: BODY CLASS\n         ----------------------------------------------------- *\/\n\n      const bodyId =\n        findPostIdFromBody();\n\n\n      if (bodyId) {\n\n        currentPostId =\n          bodyId;\n\n        return currentPostId;\n\n      }\n\n\n      \/* -----------------------------------------------------\n         SECOND: CURRENT URL \u2192 WORDPRESS PAGES\n         ----------------------------------------------------- *\/\n\n      const currentUrl =\n        window.location.href.split(\"#\")[0];\n\n      const cleanCurrentUrl =\n        currentUrl.replace(\/\\\/$\/, \"\");\n\n\n      try {\n\n        const pageResponse =\n          await fetch(\n            \"\/the-house\/wp-json\/wp\/v2\/pages\" +\n            \"?per_page=100\" +\n            \"&status=publish\",\n            {\n              credentials: \"same-origin\"\n            }\n          );\n\n\n        if (pageResponse.ok) {\n\n          const pages =\n            await pageResponse.json();\n\n\n          if (Array.isArray(pages)) {\n\n            const matchingPage =\n              pages.find(function (page) {\n\n                if (!page.link) {\n                  return false;\n                }\n\n                return (\n                  page.link.replace(\/\\\/$\/, \"\") ===\n                  cleanCurrentUrl\n                );\n\n              });\n\n\n            if (matchingPage) {\n\n              currentPostId =\n                parseInt(\n                  matchingPage.id,\n                  10\n                );\n\n              return currentPostId;\n\n            }\n\n          }\n\n        }\n\n      } catch (error) {\n\n        console.warn(\n          \"Could not identify the current WordPress page.\",\n          error\n        );\n\n      }\n\n\n      \/* -----------------------------------------------------\n         THIRD: CURRENT URL \u2192 WORDPRESS POSTS\n         ----------------------------------------------------- *\/\n\n      try {\n\n        const postResponse =\n          await fetch(\n            \"\/the-house\/wp-json\/wp\/v2\/posts\" +\n            \"?per_page=100\" +\n            \"&status=publish\",\n            {\n              credentials: \"same-origin\"\n            }\n          );\n\n\n        if (postResponse.ok) {\n\n          const posts =\n            await postResponse.json();\n\n\n          if (Array.isArray(posts)) {\n\n            const matchingPost =\n              posts.find(function (post) {\n\n                if (!post.link) {\n                  return false;\n                }\n\n                return (\n                  post.link.replace(\/\\\/$\/, \"\") ===\n                  cleanCurrentUrl\n                );\n\n              });\n\n\n            if (matchingPost) {\n\n              currentPostId =\n                parseInt(\n                  matchingPost.id,\n                  10\n                );\n\n              return currentPostId;\n\n            }\n\n          }\n\n        }\n\n      } catch (error) {\n\n        console.warn(\n          \"Could not identify the current WordPress post.\",\n          error\n        );\n\n      }\n\n\n      return null;\n\n    }\n\n\n    \/* =======================================================\n       AUDIO\n       ======================================================= *\/\n\n    let storyAudio = null;\n    let houseAudio = null;\n\n\n    function toggleAudio(type) {\n\n      const files =\n        getFiles();\n\n\n      const source =\n        type === \"story\"\n          ? files.story\n          : files.house;\n\n\n      if (!source) {\n        return;\n      }\n\n\n      let audio;\n\n\n      if (type === \"story\") {\n\n        if (!storyAudio) {\n\n          storyAudio =\n            new Audio(source);\n\n          storyAudio.loop =\n            false;\n\n        }\n\n        audio =\n          storyAudio;\n\n      } else {\n\n        if (!houseAudio) {\n\n          houseAudio =\n            new Audio(source);\n\n          houseAudio.loop =\n            false;\n\n        }\n\n        audio =\n          houseAudio;\n\n      }\n\n\n      \/*\n       * Only one house\/story audio track\n       * should play at a time.\n       *\/\n\n      if (\n        type === \"story\" &&\n        houseAudio\n      ) {\n\n        houseAudio.pause();\n\n        houseAudio.currentTime =\n          0;\n\n      }\n\n\n      if (\n        type === \"house\" &&\n        storyAudio\n      ) {\n\n        storyAudio.pause();\n\n        storyAudio.currentTime =\n          0;\n\n      }\n\n\n      if (audio.paused) {\n\n        audio.play()\n          .catch(function (error) {\n\n            console.warn(\n              \"Audio could not be played.\",\n              error\n            );\n\n          });\n\n      } else {\n\n        audio.pause();\n\n        audio.currentTime =\n          0;\n\n      }\n\n    }\n\n\n    \/* =======================================================\n       HELP\n       ======================================================= *\/\n\n    const helpBox =\n      document.getElementById(\n        \"house-help-box\"\n      );\n\n    const helpText =\n      document.getElementById(\n        \"house-help-text\"\n      );\n\n    const helpClose =\n      document.getElementById(\n        \"house-help-close\"\n      );\n\n\n    function openHelp() {\n\n      const files =\n        getFiles();\n\n\n      if (\n        !helpBox ||\n        !helpText\n      ) {\n        return;\n      }\n\n\n      helpText.textContent =\n        files.help ||\n        \"There is nothing for you to find here right now.\";\n\n\n      helpBox.classList.add(\n        \"is-open\"\n      );\n\n\n      helpBox.setAttribute(\n        \"aria-hidden\",\n        \"false\"\n      );\n\n    }\n\n\n    function closeHelp() {\n\n      if (!helpBox) {\n        return;\n      }\n\n\n      helpBox.classList.remove(\n        \"is-open\"\n      );\n\n\n      helpBox.setAttribute(\n        \"aria-hidden\",\n        \"true\"\n      );\n\n    }\n\n\n    if (helpClose) {\n\n      helpClose.addEventListener(\n        \"click\",\n        function (event) {\n\n          event.stopPropagation();\n\n          closeHelp();\n\n        }\n      );\n\n    }\n\n\n    \/* =======================================================\n       NOTE FORM\n       ======================================================= *\/\n\n    const noteBox =\n      document.getElementById(\n        \"house-note-box\"\n      );\n\n    const noteClose =\n      document.getElementById(\n        \"house-note-close\"\n      );\n\n    const noteForm =\n      document.getElementById(\n        \"house-note-form\"\n      );\n\n    const noteAuthor =\n      document.getElementById(\n        \"house-note-author\"\n      );\n\n    const noteComment =\n      document.getElementById(\n        \"house-note-comment\"\n      );\n\n    const noteSubmit =\n      document.getElementById(\n        \"house-note-submit\"\n      );\n\n    const noteStatus =\n      document.getElementById(\n        \"house-note-status\"\n      );\n\n\n    function openNoteBox() {\n\n      if (!noteBox) {\n        return;\n      }\n\n\n      if (noteStatus) {\n\n        noteStatus.textContent =\n          \"\";\n\n        noteStatus.className =\n          \"house-note-status\";\n\n      }\n\n\n      noteBox.classList.add(\n        \"is-open\"\n      );\n\n\n      noteBox.setAttribute(\n        \"aria-hidden\",\n        \"false\"\n      );\n\n\n      setTimeout(function () {\n\n        if (noteAuthor) {\n\n          noteAuthor.focus();\n\n        }\n\n      }, 50);\n\n    }\n\n\n    function closeNoteBox() {\n\n      if (!noteBox) {\n        return;\n      }\n\n\n      noteBox.classList.remove(\n        \"is-open\"\n      );\n\n\n      noteBox.setAttribute(\n        \"aria-hidden\",\n        \"true\"\n      );\n\n    }\n\n\n    if (noteClose) {\n\n      noteClose.addEventListener(\n        \"click\",\n        function (event) {\n\n          event.stopPropagation();\n\n          closeNoteBox();\n\n        }\n      );\n\n    }\n\n\n    \/* =======================================================\n       SAVE NOTE TO WORDPRESS COMMENTS\n       ======================================================= *\/\n\n    if (noteForm) {\n\n      noteForm.addEventListener(\n        \"submit\",\n        async function (event) {\n\n          event.preventDefault();\n\n          if (noteSubmit) {\n            noteSubmit.disabled = true;\n            noteSubmit.textContent = \"Finding page\u2026\";\n          }\n\n          if (noteStatus) {\n            noteStatus.textContent = \"Finding this page\u2026\";\n            noteStatus.className = \"house-note-status\";\n          }\n\n          try {\n\n            const postId = await findCurrentPostId();\n\n            if (!postId) {\n              throw new Error(\n                \"I couldn't identify this WordPress page. Please try refreshing the page.\"\n              );\n            }\n\n            const author = noteAuthor ? noteAuthor.value.trim() : \"\";\n            const comment = noteComment ? noteComment.value.trim() : \"\";\n            const emailField = document.getElementById(\"house-note-email\");\n            const email = emailField ? emailField.value.trim() : \"\";\n\n            if (!author) {\n              throw new Error(\"Please add your name.\");\n            }\n\n            if (!email) {\n              throw new Error(\"Please add your email address.\");\n            }\n\n            if (!emailField || !emailField.checkValidity()) {\n              throw new Error(\"Please enter a valid email address.\");\n            }\n\n            if (!comment) {\n              throw new Error(\"Please add your note.\");\n            }\n\n            if (noteStatus) {\n              noteStatus.textContent = \"Leaving your note\u2026\";\n              noteStatus.className = \"house-note-status\";\n            }\n\n            if (noteSubmit) {\n              noteSubmit.textContent = \"Leaving note\u2026\";\n            }\n\n            \/*\n             * Use WordPress's normal comment form endpoint rather than the\n             * REST API. This allows the site's existing anonymous-comment\n             * settings and moderation rules to handle the note.\n             *\n             * The form is submitted into a hidden same-origin iframe so the\n             * visitor stays on the current page.\n             *\/\n\n            let commentFrame = document.getElementById(\"house-comment-frame\");\n\n            if (!commentFrame) {\n              commentFrame = document.createElement(\"iframe\");\n              commentFrame.id = \"house-comment-frame\";\n              commentFrame.name = \"house-comment-frame\";\n              commentFrame.title = \"\";\n              commentFrame.setAttribute(\"aria-hidden\", \"true\");\n              commentFrame.style.position = \"fixed\";\n              commentFrame.style.width = \"1px\";\n              commentFrame.style.height = \"1px\";\n              commentFrame.style.border = \"0\";\n              commentFrame.style.opacity = \"0\";\n              commentFrame.style.pointerEvents = \"none\";\n              document.body.appendChild(commentFrame);\n            }\n\n            let postIdField = noteForm.querySelector('input[name=\"comment_post_ID\"]');\n            if (!postIdField) {\n              postIdField = document.createElement(\"input\");\n              postIdField.type = \"hidden\";\n              postIdField.name = \"comment_post_ID\";\n              noteForm.appendChild(postIdField);\n            }\n            postIdField.value = String(postId);\n\n            let parentField = noteForm.querySelector('input[name=\"comment_parent\"]');\n            if (!parentField) {\n              parentField = document.createElement(\"input\");\n              parentField.type = \"hidden\";\n              parentField.name = \"comment_parent\";\n              noteForm.appendChild(parentField);\n            }\n            parentField.value = \"0\";\n\n            let urlField = noteForm.querySelector('input[name=\"url\"]');\n            if (!urlField) {\n              urlField = document.createElement(\"input\");\n              urlField.type = \"hidden\";\n              urlField.name = \"url\";\n              noteForm.appendChild(urlField);\n            }\n            urlField.value = \"\";\n\n            noteForm.action = \"\/the-house\/wp-comments-post.php\";\n            noteForm.method = \"post\";\n            noteForm.target = \"house-comment-frame\";\n\n            \/*\n             * Submit the form into the hidden iframe. We wait for the\n             * WordPress response and inspect its URL\/body before telling\n             * the visitor that the note was saved.\n             *\/\n            const handleCommentResponse = function () {\n              try {\n                const frameWindow = commentFrame.contentWindow;\n                const currentUrl = frameWindow.location.href || \"\";\n\n                if (\n                  !currentUrl ||\n                  currentUrl === \"about:blank\" ||\n                  currentUrl.indexOf(\"about:blank\") === 0\n                ) {\n                  return;\n                }\n\n                const frameText = frameWindow.document.body\n                  ? frameWindow.document.body.innerText || \"\"\n                  : \"\";\n\n                const lowerUrl = currentUrl.toLowerCase();\n                const lowerText = frameText.toLowerCase();\n\n                \/*\n                 * WordPress sends the visitor to an error page when the\n                 * comment cannot be accepted. Catch that before success.\n                 *\/\n                if (\n                  lowerUrl.indexOf(\"wp-comments-post.php\") !== -1 &&\n                  (\n                    lowerUrl.indexOf(\"error\") !== -1 ||\n                    lowerText.indexOf(\"error:\") !== -1 ||\n                    lowerText.indexOf(\"sorry\") !== -1\n                  )\n                ) {\n                  const lines = frameText\n                    .split(\/\\r?\\n\/)\n                    .map(function (line) { return line.trim(); })\n                    .filter(Boolean);\n\n                  throw new Error(\n                    lines.length\n                      ? lines[0]\n                      : \"WordPress could not save the note.\"\n                  );\n                }\n\n                if (noteStatus) {\n                  noteStatus.textContent =\n                    \"Your note has been submitted. It may need approval before it appears in Paper notes.\";\n                  noteStatus.className = \"house-note-status success\";\n                }\n\n                if (noteComment) {\n                  noteComment.value = \"\";\n                }\n\n                if (notesBox && notesBox.classList.contains(\"is-open\")) {\n                  loadPageNotes();\n                }\n\n                setTimeout(function () {\n                  closeNoteBox();\n                }, 2200);\n\n              } catch (responseError) {\n                console.error(\"House note response error:\", responseError);\n\n                if (noteStatus) {\n                  noteStatus.textContent =\n                    responseError.message || \"WordPress could not save the note.\";\n                  noteStatus.className = \"house-note-status error\";\n                }\n              } finally {\n                commentFrame.removeEventListener(\"load\", handleCommentResponse);\n              }\n            };\n\n            commentFrame.addEventListener(\"load\", handleCommentResponse);\n\n            \/*\n             * HTMLFormElement.submit() sends the exact fields assembled\n             * above without triggering this submit listener again.\n             *\/\n            HTMLFormElement.prototype.submit.call(noteForm);\n\n          } catch (error) {\n\n            console.error(\"House note error:\", error);\n\n            if (noteStatus) {\n              noteStatus.textContent =\n                error.message || \"The note could not be saved.\";\n              noteStatus.className = \"house-note-status error\";\n            }\n\n          } finally {\n\n            if (noteSubmit) {\n              noteSubmit.disabled = false;\n              noteSubmit.textContent = \"Leave note\";\n            }\n\n          }\n\n        }\n      );\n\n    }\n\n\n    \/* =======================================================\n       SHOW PAPER NOTES\n       ======================================================= *\/\n\n    const notesBox =\n      document.getElementById(\n        \"house-notes-box\"\n      );\n\n    const notesClose =\n      document.getElementById(\n        \"house-notes-close\"\n      );\n\n    const notesList =\n      document.getElementById(\n        \"house-notes-list\"\n      );\n\n\n    function openNotesBox() {\n\n      if (!notesBox) {\n        return;\n      }\n\n\n      notesBox.classList.add(\n        \"is-open\"\n      );\n\n\n      notesBox.setAttribute(\n        \"aria-hidden\",\n        \"false\"\n      );\n\n\n      loadPageNotes();\n\n    }\n\n\n    function closeNotesBox() {\n\n      if (!notesBox) {\n        return;\n      }\n\n\n      notesBox.classList.remove(\n        \"is-open\"\n      );\n\n\n      notesBox.setAttribute(\n        \"aria-hidden\",\n        \"true\"\n      );\n\n    }\n\n\n    if (notesClose) {\n\n      notesClose.addEventListener(\n        \"click\",\n        function (event) {\n\n          event.stopPropagation();\n\n          closeNotesBox();\n\n        }\n      );\n\n    }\n\n\n    \/* =======================================================\n       LOAD WORDPRESS COMMENTS FOR CURRENT PAGE\n       ======================================================= *\/\n\n    async function loadPageNotes() {\n\n      if (!notesList) {\n        return;\n      }\n\n\n      notesList.innerHTML =\n        '<div class=\"house-no-notes\">' +\n        'Finding the notes\u2026' +\n        '<\/div>';\n\n\n      try {\n\n        \/*\n         * Find the same WordPress page ID\n         * used when saving the note.\n         *\/\n\n        const postId =\n          await findCurrentPostId();\n\n\n        if (!postId) {\n\n          throw new Error(\n            \"I couldn't identify this page.\"\n          );\n\n        }\n\n\n        \/*\n         * Ask WordPress for comments belonging\n         * specifically to this page.\n         *\n         * status=approve means we only show\n         * comments that WordPress has made public.\n         *\/\n\n        let comments = [];\n\n        \/*\n         * First try the WordPress REST API.\n         * This is the cleanest way to get only comments\n         * attached to the current page.\n         *\/\n        try {\n\n          const response =\n            await fetch(\n              \"\/the-house\/wp-json\/wp\/v2\/comments\" +\n              \"?post=\" +\n              encodeURIComponent(\n                postId\n              ) +\n              \"&status=approve\" +\n              \"&per_page=100\" +\n              \"&orderby=date\" +\n              \"&order=desc\",\n              {\n                method: \"GET\",\n                credentials: \"same-origin\"\n              }\n            );\n\n\n          if (response.ok) {\n\n            const data =\n              await response.json();\n\n            if (Array.isArray(data)) {\n              comments = data;\n            }\n\n          }\n\n        } catch (error) {\n\n          console.warn(\n            \"The WordPress comments API could not be read.\",\n            error\n          );\n\n        }\n\n\n        \/*\n         * Fallback: WordPress also prints approved comments\n         * directly into the page. If the REST API is blocked\n         * by the site's configuration, read those visible\n         * comments instead. This still keeps the notes limited\n         * to the current page.\n         *\/\n        if (comments.length === 0) {\n\n          const nativeComments =\n            Array.from(\n              document.querySelectorAll(\n                \"#comments li.comment, .comment-list li.comment, li.comment\"\n              )\n            );\n\n\n          comments = nativeComments.map(function (item) {\n\n            const authorElement =\n              item.querySelector(\n                \".comment-author, .fn, .commentmetadata .fn\"\n              );\n\n            const dateElement =\n              item.querySelector(\n                \"time, .comment-metadata, .comment-meta\"\n              );\n\n            const contentElement =\n              item.querySelector(\n                \".comment-content\"\n              );\n\n            return {\n              author_name: authorElement\n                ? authorElement.textContent.trim()\n                : \"Anonymous\",\n              date: dateElement\n                ? (dateElement.getAttribute(\"datetime\") || dateElement.textContent.trim())\n                : \"\",\n              content: {\n                rendered: contentElement\n                  ? contentElement.innerHTML\n                  : item.textContent\n              }\n            };\n\n          });\n\n        }\n\n\n        \/*\n         * No approved comments.\n         *\/\n\n        if (\n          !Array.isArray(\n            comments\n          ) ||\n          comments.length === 0\n        ) {\n\n          notesList.innerHTML =\n            '<div class=\"house-no-notes\">' +\n            'No paper notes have been left on this page yet.' +\n            '<\/div>';\n\n          return;\n\n        }\n\n\n        \/*\n         * Empty the loading message.\n         *\/\n\n        notesList.innerHTML =\n          \"\";\n\n\n        \/*\n         * Build each paper note safely\n         * using textContent rather than injecting\n         * comment HTML directly.\n         *\/\n\n        comments.forEach(\n          function (comment) {\n\n            const note =\n              document.createElement(\n                \"div\"\n              );\n\n            note.className =\n              \"house-single-note\";\n\n\n            const author =\n              document.createElement(\n                \"div\"\n              );\n\n            author.className =\n              \"house-single-note-author\";\n\n\n            author.textContent =\n              comment.author_name ||\n              \"Anonymous\";\n\n\n            const date =\n              document.createElement(\n                \"div\"\n              );\n\n            date.className =\n              \"house-single-note-date\";\n\n\n            if (comment.date) {\n\n              const parsedDate =\n                new Date(\n                  comment.date\n                );\n\n\n              if (\n                !isNaN(\n                  parsedDate.getTime()\n                )\n              ) {\n\n                date.textContent =\n                  parsedDate.toLocaleDateString(\n                    undefined,\n                    {\n                      year:\n                        \"numeric\",\n\n                      month:\n                        \"long\",\n\n                      day:\n                        \"numeric\"\n                    }\n                  );\n\n              }\n\n            }\n\n\n            const text =\n              document.createElement(\n                \"div\"\n              );\n\n            text.className =\n              \"house-single-note-text\";\n\n\n            \/*\n             * WordPress gives us rendered HTML\n             * for comment.content.\n             *\n             * We convert it to plain text so that\n             * visitors' comments cannot inject\n             * arbitrary HTML into the menu.\n             *\/\n\n            if (\n              comment.content &&\n              comment.content.rendered\n            ) {\n\n              text.textContent =\n                stripHtml(\n                  comment.content.rendered\n                );\n\n            } else {\n\n              text.textContent =\n                \"\";\n\n            }\n\n\n            note.appendChild(\n              author\n            );\n\n\n            if (\n              date.textContent\n            ) {\n\n              note.appendChild(\n                date\n              );\n\n            }\n\n\n            note.appendChild(\n              text\n            );\n\n\n            notesList.appendChild(\n              note\n            );\n\n          }\n        );\n\n\n      } catch (error) {\n\n        console.error(\n          \"House notes error:\",\n          error\n        );\n\n\n        notesList.innerHTML =\n          '<div class=\"house-no-notes\">' +\n          'The paper notes could not be loaded right now.' +\n          '<\/div>';\n\n      }\n\n    }\n\n\n    \/* =======================================================\n       REMOVE HTML FROM WORDPRESS COMMENT CONTENT\n       ======================================================= *\/\n\n    function stripHtml(html) {\n\n      const temporary =\n        document.createElement(\n          \"div\"\n        );\n\n\n      temporary.innerHTML =\n        html;\n\n\n      return (\n        temporary.textContent ||\n        temporary.innerText ||\n        \"\"\n      );\n\n    }\n\n\n    \/* =======================================================\n       ARTWORK\n       ======================================================= *\/\n\n    const artOverlay =\n      document.getElementById(\n        \"house-art-overlay\"\n      );\n\n    const artImage =\n      document.getElementById(\n        \"house-art-image\"\n      );\n\n    const artClose =\n      document.getElementById(\n        \"house-art-close\"\n      );\n\n\n    function openArtwork() {\n\n      const files =\n        getFiles();\n\n\n      if (\n        !files.art ||\n        !artOverlay ||\n        !artImage\n      ) {\n\n        return;\n\n      }\n\n\n      artImage.src =\n        files.art;\n\n\n      artOverlay.style.display =\n        \"flex\";\n\n\n      if (\n        artOverlay.requestFullscreen\n      ) {\n\n        artOverlay\n          .requestFullscreen()\n          .catch(function () {});\n\n      } else if (\n        artOverlay.webkitRequestFullscreen\n      ) {\n\n        artOverlay.webkitRequestFullscreen();\n\n      }\n\n    }\n\n\n    function closeArtwork() {\n\n      if (!artOverlay) {\n        return;\n      }\n\n\n      artOverlay.style.display =\n        \"none\";\n\n\n      if (artImage) {\n\n        artImage.src =\n          \"\";\n\n      }\n\n\n      if (\n        document.fullscreenElement\n      ) {\n\n        document\n          .exitFullscreen()\n          .catch(function () {});\n\n      } else if (\n        document.webkitFullscreenElement\n      ) {\n\n        document.webkitExitFullscreen();\n\n      }\n\n    }\n\n\n    if (artClose) {\n\n      artClose.addEventListener(\n        \"click\",\n        function (event) {\n\n          event.stopPropagation();\n\n          closeArtwork();\n\n        }\n      );\n\n    }\n\n\n    if (artOverlay) {\n\n      artOverlay.addEventListener(\n        \"click\",\n        function (event) {\n\n          if (\n            event.target ===\n            artOverlay\n          ) {\n\n            closeArtwork();\n\n          }\n\n        }\n      );\n\n    }\n\n\n    \/* =======================================================\n       ESCAPE KEY\n       ======================================================= *\/\n\n    document.addEventListener(\n      \"keydown\",\n      function (event) {\n\n        if (\n          event.key !==\n          \"Escape\"\n        ) {\n\n          return;\n\n        }\n\n\n        closeHelp();\n\n        closeNoteBox();\n\n        closeNotesBox();\n\n\n        if (\n          artOverlay &&\n          artOverlay.style.display ===\n          \"flex\"\n        ) {\n\n          closeArtwork();\n\n        }\n\n      }\n    );\n\n\n    \/* =======================================================\n       MENU BUTTONS\n       ======================================================= *\/\n\n    menu.addEventListener(\n      \"click\",\n      function (event) {\n\n        const button =\n          event.target.closest(\n            \".house-menu-button\"\n          );\n\n\n        if (\n          !button ||\n          !menu.contains(\n            button\n          )\n        ) {\n\n          return;\n\n        }\n\n\n        \/* ---------------------------------------------------\n           STORY\n           --------------------------------------------------- *\/\n\n        if (\n          button.classList.contains(\n            \"house-story\"\n          )\n        ) {\n\n          toggleAudio(\n            \"story\"\n          );\n\n          return;\n\n        }\n\n\n        \/* ---------------------------------------------------\n           ART\n           --------------------------------------------------- *\/\n\n        if (\n          button.classList.contains(\n            \"house-eye\"\n          )\n        ) {\n\n          openArtwork();\n\n          return;\n\n        }\n\n\n        \/* ---------------------------------------------------\n           HOUSE AUDIO\n           --------------------------------------------------- *\/\n\n        if (\n          button.classList.contains(\n            \"house-ear\"\n          )\n        ) {\n\n          toggleAudio(\n            \"house\"\n          );\n\n          return;\n\n        }\n\n\n        \/* ---------------------------------------------------\n           HELP\n           --------------------------------------------------- *\/\n\n        if (\n          button.classList.contains(\n            \"house-help\"\n          )\n        ) {\n\n          openHelp();\n\n          return;\n\n        }\n\n\n        \/* ---------------------------------------------------\n           LEAVE A NOTE\n           --------------------------------------------------- *\/\n\n        if (\n          button.classList.contains(\n            \"house-note\"\n          )\n        ) {\n\n          openNoteBox();\n\n          return;\n\n        }\n\n\n        \/* ---------------------------------------------------\n           SEARCH PAPER NOTES\n           --------------------------------------------------- *\/\n\n        if (\n          button.classList.contains(\n            \"house-notes\"\n          )\n        ) {\n\n          openNotesBox();\n\n          return;\n\n        }\n\n      }\n    );\n\n  }\n\n\n  \/* =========================================================\n     INITIALISE\n     ========================================================= *\/\n\n  if (\n    document.readyState ===\n    \"loading\"\n  ) {\n\n    document.addEventListener(\n      \"DOMContentLoaded\",\n      initHouseMenu\n    );\n\n  } else {\n\n    initHouseMenu();\n\n  }\n\n})();\n<\/script>\n\n\n<script>\nwindow.houseMenuFiles = {\n\n  story: \"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/the-house-speak-front-page-take-2.mp3\",\n\n  art: \"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/nathan-mcdine-Sz2UlMzTv4I-unsplash-1-scaled.jpg\",\n\n  house: \"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/09\/810428__klankbeeld__park-forest-loonse-en-drunense-duinen-netherlands-1125-am-150410_0602-1.flac\",\n\n  help: \"Read the instructions, get your sound settings just right, try using the spyglass to look closer at the house - when you see floating objects click them to learn what they do\"\n\n};\n<\/script>\n\n\n\n<div id=\"house-telegram\" class=\"ht-root\">\n  <button class=\"ht-envelope\" type=\"button\" aria-label=\"Open the telegram\" aria-haspopup=\"dialog\">\n    <img decoding=\"async\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/10\/Vintage-Telegram-Envelope-with-Wax-Seal.png\" alt=\"Sealed telegram from The House\">\n    <span class=\"ht-hint\">CLICK TO OPEN<\/span>\n  <\/button>\n  <div class=\"ht-overlay\" hidden=\"\">\n    <div class=\"ht-dialog\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Telegram from The House\" tabindex=\"-1\">\n      <button class=\"ht-close\" type=\"button\" aria-label=\"Close telegram\">\u00d7<\/button>\n      <img decoding=\"async\" class=\"ht-paper\" src=\"https:\/\/itdd.au.dk\/the-house\/wp-content\/uploads\/sites\/112\/2026\/11\/house_garden_telegram_transparent.png\" alt=\"Telegram from The House, Garden, dated 3rd of November. Finally, you are back! You have been walking in circles in the woods in what feels like weeks! The House has requested your presence in the garden. Go to the Foyer and head into the garden. Await further instructions.\">\n    <\/div>\n  <\/div>\n<\/div>\n\n<style>\n#house-telegram {\n  position:relative;\n  z-index:99990;\n  font-family:Georgia,serif;\n}\n\n#house-telegram .ht-envelope {\n  position:fixed;\n  top:50%;\n  left:50%;\n  transform:translate(-50%,-50%);\n  width:min(440px,80vw);\n  padding:0;\n  border:0;\n  background:transparent;\n  cursor:pointer;\n  z-index:99991;\n  transition:filter .3s ease, transform .3s ease;\n}\n\n#house-telegram .ht-envelope[hidden] {\n  display:none !important;\n}\n\n#house-telegram .ht-envelope.ht-docked {\n  top:auto;\n  left:auto;\n  right:18px;\n  bottom:18px;\n  width:min(190px,35vw);\n  transform:none;\n}\n\n#house-telegram .ht-envelope.ht-docked:hover,\n#house-telegram .ht-envelope.ht-docked:focus-visible {\n  transform:scale(1.045);\n}\n\n#house-telegram .ht-envelope.ht-docked .ht-hint {\n  display:none;\n}\n\n#house-telegram .ht-envelope img {\n  width:100%;\n  height:auto;\n  display:block;\n  filter:drop-shadow(0 12px 18px rgba(0,0,0,.55));\n}\n\n#house-telegram .ht-envelope:hover,\n#house-telegram .ht-envelope:focus-visible {\n  transform:translate(-50%,-50%) scale(1.035);\n  filter:drop-shadow(0 0 17px rgba(239,174,75,.62));\n}\n\n#house-telegram .ht-envelope:focus-visible,\n#house-telegram .ht-close:focus-visible {\n  outline:2px solid #f5cb85;\n  outline-offset:5px;\n}\n\n#house-telegram .ht-hint {\n  display:block;\n  margin-top:12px;\n  color:#e7c28d;\n  font-size:13px;\n  letter-spacing:.24em;\n  text-shadow:0 2px 5px #000;\n}\n\n#house-telegram .ht-overlay[hidden] {\n  display:none !important;\n}\n\n#house-telegram .ht-overlay {\n  position:fixed;\n  inset:0;\n  z-index:99992;\n  display:flex;\n  align-items:center;\n  justify-content:center;\n  padding:20px;\n  background:rgba(0,0,0,.78);\n}\n\n#house-telegram .ht-dialog {\n  position:relative;\n  width:min(660px,92vw);\n  max-height:92vh;\n  outline:none;\n  animation:ht-unfold .65s cubic-bezier(.2,.7,.2,1) both;\n  transform-origin:center top;\n}\n\n#house-telegram .ht-paper {\n  display:block;\n  width:100%;\n  max-height:92vh;\n  object-fit:contain;\n  filter:drop-shadow(0 15px 28px rgba(0,0,0,.65));\n}\n\n#house-telegram .ht-close {\n  position:absolute;\n  right:2%;\n  top:2%;\n  z-index:2;\n  width:40px;\n  height:40px;\n  border:1px solid #bd935e;\n  border-radius:50%;\n  background:#26160f;\n  color:#f4d7a1;\n  font:30px\/1 Georgia,serif;\n  cursor:pointer;\n  box-shadow:0 3px 12px #0008;\n}\n\n#house-telegram .ht-close:hover {\n  background:#58301c;\n}\n\n\/* FIX: REMOVE UNWANTED BLACK BOX AROUND ENVELOPE *\/\n\n#house-telegram .ht-envelope,\n#house-telegram .ht-envelope:hover,\n#house-telegram .ht-envelope:focus,\n#house-telegram .ht-envelope:active {\n  background:transparent !important;\n  background-color:transparent !important;\n  border:none !important;\n  box-shadow:none !important;\n  appearance:none;\n}\n\n#house-telegram .ht-envelope img {\n  background:transparent !important;\n  border:none !important;\n  box-shadow:none !important;\n}\n\n\/* TELEGRAM OPENING ANIMATION *\/\n\n@keyframes ht-unfold {\n  from {\n    opacity:0;\n    transform:perspective(900px) rotateX(-45deg) scaleY(.3);\n  }\n  to {\n    opacity:1;\n    transform:perspective(900px) rotateX(0) scaleY(1);\n  }\n}\n\n@media (prefers-reduced-motion:reduce) {\n  #house-telegram .ht-envelope,\n  #house-telegram .ht-dialog {\n    animation:none;\n    transition:none;\n  }\n}\n<\/style>\n\n<script>\n(function(){\n  const root=document.getElementById('house-telegram');\n  if(!root || root.dataset.ready) return;\n  root.dataset.ready='1';\n\n  const envelope=root.querySelector('.ht-envelope');\n  const overlay=root.querySelector('.ht-overlay');\n  const dialog=root.querySelector('.ht-dialog');\n  const close=root.querySelector('.ht-close');\n\n  let openedOnce = false;\n\n  try {\n    openedOnce = sessionStorage.getItem('houseTelegramOpened') === 'yes';\n  } catch(e) {}\n\n  if (openedOnce) envelope.classList.add('ht-docked');\n\n  function openTelegram(){\n    openedOnce = true;\n\n    try {\n      sessionStorage.setItem('houseTelegramOpened', 'yes');\n    } catch(e) {}\n\n    overlay.hidden=false;\n    envelope.hidden=true;\n    document.addEventListener('keydown',onKey);\n    close.focus();\n  }\n\n  function closeTelegram(){\n    overlay.hidden=true;\n    envelope.classList.add('ht-docked');\n    envelope.hidden=false;\n    document.removeEventListener('keydown',onKey);\n    envelope.focus();\n  }\n\n  function onKey(e){\n    if(e.key==='Escape') closeTelegram();\n\n    if(e.key==='Tab'){\n      const focusables=[close];\n      if(!focusables.includes(document.activeElement)){\n        e.preventDefault();\n        close.focus();\n      }\n    }\n  }\n\n  envelope.addEventListener('click',openTelegram);\n  close.addEventListener('click',closeTelegram);\n\n  overlay.addEventListener('click',e=>{\n    if(e.target===overlay)closeTelegram();\n  });\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>\u00d7 0:00 \/ 0:00 Welcome the House Look carefully at the windows&#8230; Someone may be watching. \u00d7 CLICK TO OPEN \u00d7<\/p>\n","protected":false},"author":224,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-47","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/itdd.au.dk\/the-house\/wp-json\/wp\/v2\/pages\/47","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itdd.au.dk\/the-house\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/itdd.au.dk\/the-house\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/itdd.au.dk\/the-house\/wp-json\/wp\/v2\/users\/224"}],"replies":[{"embeddable":true,"href":"https:\/\/itdd.au.dk\/the-house\/wp-json\/wp\/v2\/comments?post=47"}],"version-history":[{"count":79,"href":"https:\/\/itdd.au.dk\/the-house\/wp-json\/wp\/v2\/pages\/47\/revisions"}],"predecessor-version":[{"id":1534,"href":"https:\/\/itdd.au.dk\/the-house\/wp-json\/wp\/v2\/pages\/47\/revisions\/1534"}],"wp:attachment":[{"href":"https:\/\/itdd.au.dk\/the-house\/wp-json\/wp\/v2\/media?parent=47"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}