{"/components/core/navbar.vue":"<template>\n  <!-- Email Verification Banner -->\n  <div\n    v-if=\"$root.user && $root.user.role === 'unverified'\"\n    class=\"bg-amber-400/10 border-b border-amber-400/30 px-3 py-2 flex items-center justify-between gap-3\"\n  >\n    <div class=\"flex items-center gap-2\">\n      <span class=\"ph ph-warning-circle text-amber-400 text-lg\"></span>\n      <span class=\"text-amber-200 text-sm\">\n        {{ $root.translations.navbar_verify_email_text }}\n      </span>\n    </div>\n    <BaseButton\n      type=\"secondary\"\n      size=\"small\"\n      class=\"h-8 text-xs whitespace-nowrap bg-amber-400/20 hover:bg-amber-400/30 text-amber-200 border-amber-400/30\"\n      :label=\"$root.translations.navbar_resend_email\"\n      :disabled=\"resendingVerification\"\n      @click=\"resendVerification\"\n    />\n  </div>\n\n  <nav\n    :class=\"$route.path.includes('chat/') ? 'hidden md:flex' : 'flex'\"\n    class=\"items-center gap-2 border-b border-theme-900 justify-between p-2 pr-3 md:pr-4\"\n  >\n    <div class=\"flex items-center gap-2\">\n      <img\n        v-if=\"!isNonDefaultTheme\"\n        :src=\"$root.serveImg('/api/logo.php')\"\n        @click=\"!$route.path.includes('home') ? $router.push('/home') : null\"\n        class=\"w-12 h-12 object-cover\"\n        ondragstart=\"return false;\"\n        alt=\"\"\n      />\n      <ThemedLogo\n        v-else\n        class=\"w-12 h-12 cursor-pointer block\"\n        @click=\"!$route.path.includes('home') ? $router.push('/home') : null\"\n      />\n      <router-link\n        to=\"/\"\n        class=\"hidden md:flex text-theme-100 text-xl text-center font-extrabold gap-1 items-center justify-center\"\n      >\n        {{ pathName }}\n        <div\n          v-if=\"$root.get_plan() == 0 && this.$root.info.name == pathName\"\n          class=\"bg-brand-400 text-theme-900 px-2 text-xs rounded\"\n        >\n          {{ $root.info.version }}\n        </div>\n        <div\n          v-else-if=\"this.$root.info.name == pathName\"\n          class=\"bg-amber-400 text-theme-900 px-2 text-xs rounded\"\n        >\n          {{ $root.user.subscription.plan_name.split(' ')[0] }}\n        </div>\n      </router-link>\n\n      <!-- Level + credits (visible on mobile too, right after the logo) -->\n      <div v-if=\"$root.user\" class=\"flex items-center gap-1.5\">\n        <button\n          type=\"button\"\n          class=\"flex items-center gap-0.5 px-1.5 h-6 rounded bg-theme-950 border border-theme-900 text-theme-300  \"\n          :title=\"$root.translations.navbar_level_tooltip || 'Level'\"\n          @click=\"openAchievementsModal('overview', 'all')\"\n        >\n          <span class=\"text-[10px] font-bold uppercase tracking-wide text-theme-500\">\n            {{ $root.translations.navbar_level || 'Lv' }}\n          </span>\n          <span class=\"text-xs font-extrabold text-theme-100 leading-none\">\n            {{ $root.user.achievement && $root.user.achievement.level ? $root.user.achievement.level : 1 }}\n          </span>\n        </button>\n        <button\n          type=\"button\"\n          class=\"flex items-center gap-1 px-1.5 h-6 rounded border border-amber-500/20 text-amber-300 hover:bg-amber-500/10 transition-colors\"\n          :title=\"$root.translations.credit_options_title || 'Get more credits'\"\n          @click=\"$root.openCreditOptions({ reason: 'Manage your credits' })\"\n        >\n          <span class=\"ph ph-coins text-xs\"></span>\n          <span class=\"text-xs font-extrabold leading-none\">{{ creditCount }}</span>\n        </button>\n      </div>\n\n\n      <!-- Tabs for PC -->\n      <div\n        v-if=\"isPC && $root.user && $root.user.settings && $root.user.settings.enable_tabs !== false\"\n        class=\"flex-grow ml-2 flex items-center justify-center\"\n      >\n        <div class=\"flex items-center gap-1 py-1\">\n          <div\n            v-for=\"(tab, index) in $root.tabs\"\n            :key=\"tab.path\"\n            @click=\"navigateTo(tab.path)\"\n            @dragstart=\"dragStart(index)\"\n            @dragover.prevent\n            @drop=\"drop(index)\"\n            draggable=\"true\"\n            class=\"flex items-center gap-1 px-3 rounded-md cursor-pointer transition-all select-none duration-200 h-8\"\n            :class=\"tabButtonClasses(tab)\"\n          >\n            <template v-if=\"tab.icon\">\n              <img\n                v-if=\"!tab.iconError\"\n                class=\"w-5 h-5 rounded-md\"\n                :src=\"$root.baseUrl + tab.icon\"\n                @error=\"handleIconError(tab)\"\n              />\n              <span\n                v-else\n                class=\"ph ph-image w-5 h-5 flex items-center justify-center text-lg\"\n              ></span>\n            </template>\n            <span class=\"text-sm whitespace-nowrap\">\n              {{ tab.title }}\n            </span>\n            <button\n              @click.stop=\"closeTab(index)\"\n              class=\"ml-1 flex items-center justify-center text-theme-400 ph ph-x hover:text-white text-sm\"\n              style=\"line-height: 1\"\n            >\n            </button>\n          </div>\n        </div>\n      </div>\n    </div>\n\n    <div class=\"flex relative items-center gap-2\">\n      <BaseButton\n        v-if=\"isPC && $root.user && ['beta', 'admin'].includes($root.user.role)\"\n        type=\"secondary\"\n        size=\"small\"\n        class=\"h-8\"\n        icon=\"ph-broom\"\n        :disabled=\"clearingCache\"\n        :aria-label=\"$root.translations.navbar_clear_cache || 'Clear cache'\"\n        :title=\"$root.translations.navbar_clear_cache_tooltip || 'Clear frontend caches and reload'\"\n        @click=\"clearFrontendCache\"\n      />\n\n      <BaseButton\n        v-if=\"$root.user ? isPC : true\"\n        type=\"secondary\"\n        size=\"small\"\n        class=\"h-8\"\n        icon=\"ph-book-open\"\n        @click=\"$router.push('/documentation')\"\n      />\n\n      <BaseButton\n        v-if=\"isPC\"\n        type=\"secondary\"\n        size=\"small\"\n        class=\"h-8\"\n        icon=\"ph-storefront\"\n        :aria-label=\"$root.translations.store || 'Store'\"\n        :title=\"$root.translations.store || 'Store'\"\n        @click=\"goToStoreHome\"\n      />\n\n      <BaseButton\n        v-if=\"$root.user\"\n        type=\"secondary\"\n        size=\"small\"\n        class=\"hidden 2xl:flex h-8\"\n        icon=\"ph-trophy\"\n        @click=\"openAchievementsModal('achievements', 'store')\"\n      />\n\n      <!-- Alerts Button -->\n      <BaseButton\n        v-if=\"$root.user\"\n        type=\"secondary\"\n        size=\"small\"\n        class=\"h-8 relative\"\n        icon=\"ph-bell\"\n        @click=\"$root.openModal('notifications')\"\n      >\n        <template v-if=\"unreadCount > 0\" #badge>\n          <span\n            class=\"absolute -top-1 -right-1 bg-brand-400 text-theme-900 text-[10px] rounded-full h-4 min-w-4 px-1 flex items-center justify-center\"\n          >\n            {{ unreadCount > 99 ? '99+' : unreadCount }}\n          </span>\n        </template>\n      </BaseButton>\n\n      <div\n        v-if=\"!$root.user\"\n        class=\"flex gap-2 justify-end items-center\"\n      >\n      <BaseButton\n        :label=\"$root.translations.login\"\n        type=\"gradient\"\n        size=\"small\"\n          class=\"hidden sm:flex h-8\"\n          @click=\"$root.openModal('login')\"\n        />\n        <BaseButton\n          :label=\"$root.translations.register\"\n          type=\"primary\"\n          size=\"small\"\n          icon=\"ph-arrow-right\"\n          class=\"h-8\"\n          @click=\"$root.openModal('register')\"\n        />\n      </div>\n\n      <div\n        v-else\n        class=\"flex gap-2 justify-end items-center\"\n      >\n        <BaseButton\n          :label=\"isPC ? $root.translations.profile : ''\"\n          type=\"secondary\"\n          size=\"small\"\n          icon=\"ph-user\"\n          class=\"h-8\"\n          @click=\"handleProfileClick\"\n        />\n      </div>\n    </div>\n  </nav>\n</template>\n\n<script>\nimport BaseButton from \"../modules/BaseButton.vue\";\nimport ThemedLogo from \"./ThemedLogo.vue\";\n\nexport default {\n  components: {\n    BaseButton,\n    ThemedLogo,\n  },\n  name: \"Navbar\",\n  data() {\n    return {\n      isPC: false,\n      draggedIndex: null,\n      unreadCount: 0,\n      resendingVerification: false,\n      clearingCache: false,\n    };\n  },\n  watch: {\n    // Refresh the badge the moment the notifications modal closes (reads may have changed)\n    \"$root.activeModals\": {\n      handler(modals) {\n        const open = (modals || []).some(m => m.modalName === \"notifications\");\n        if (this._notificationsModalOpen && !open) {\n          this.fetchNotifications();\n        }\n        this._notificationsModalOpen = open;\n      },\n      deep: true\n    }\n  },\n  created() {\n    this.checkIfPC();\n    window.addEventListener(\"resize\", this.checkIfPC);\n  },\n  mounted() {\n    this.$nextTick(() => {\n      if (this.$root.user && this.$root.user.settings && this.$root.user.settings.enable_tabs !== false) {\n        this.loadTabs();\n        this.addTab(this.$route);\n      }\n    });\n    this.fetchNotifications();\n    // Keep the bell badge fresh without spamming the API\n    this.notificationsPoll = setInterval(() => this.fetchNotifications(), 60000);\n    window.addEventListener(\"focus\", this.fetchNotifications);\n  },\n  beforeUnmount() {\n    window.removeEventListener(\"resize\", this.checkIfPC);\n    if (this.notificationsPoll) {\n      clearInterval(this.notificationsPoll);\n      this.notificationsPoll = null;\n    }\n    window.removeEventListener(\"focus\", this.fetchNotifications);\n  },\n  watch: {\n    $route(to, from) {\n      console.log(\"Route changed from\", from.name, \"to\", to.name);\n      if (this.isPC && this.$root.user && this.$root.user.settings && this.$root.user.settings.enable_tabs !== false) this.addTab(to);\n    },\n    \"$root.tabs\": {\n      handler() {\n        if (this.$root.user && this.$root.user.settings && this.$root.user.settings.enable_tabs !== false) {\n          this.saveTabs();\n        }\n      },\n      deep: true,\n    },\n  },\n  methods: {\n    handleIconError(tab) {\n      if (tab) {\n        tab.iconError = true;\n      }\n    },\n    checkIfPC() {\n      this.isPC = window.innerWidth > 768;\n    },\n    goToStoreHome() {\n      if (!this.$root?.requireStoreAccess?.({ promptLogin: !this.$root?.user })) {\n        return;\n      }\n\n      if (this.$route.path !== \"/store\") {\n        this.$router.push(\"/store\");\n      }\n    },\n    goToStoreTab(tab) {\n      if (!this.$root?.requireStoreAccess?.({ promptLogin: !this.$root?.user })) {\n        return;\n      }\n\n      this.$router.push({\n        path: \"/store\",\n        query: {\n          tab,\n        },\n      });\n    },\n    openCreateStoreListingModal() {\n      if (!this.$root?.requireStoreAccess?.({ promptLogin: !this.$root?.user })) {\n        return;\n      }\n\n      this.$root.openModal(\"CreateStoreListingModal\", {\n        onViewListing: (listing) => {\n          this.$router.push(`/store/${listing.id}`);\n        },\n      });\n    },\n    openAchievementsModal(initialTab = \"overview\", initialCategory = \"all\") {\n      if (!this.$root.user) {\n        this.$root.openModal(\"login\");\n        return;\n      }\n\n      this.$root.openModal(\"AchievementsModal\", {\n        initialTab,\n        initialCategory,\n      });\n    },\n    handleProfileClick() {\n      this.$router.push(\"/dashboard\");\n    },\n    async clearFrontendCache() {\n      if (this.clearingCache) return;\n      this.clearingCache = true;\n      try {\n        // Compiled SFC cache (Cache API + localStorage fallback).\n        if (this.$root.MiocSFCCompiledCache?.clearAll) {\n          await this.$root.MiocSFCCompiledCache.clearAll();\n        } else if (window.MiocSFCCompiledCache?.clearAll) {\n          await window.MiocSFCCompiledCache.clearAll();\n        }\n        // Raw .vue cache stores (all versions, in case of stale names).\n        if ('caches' in window) {\n          const keys = await caches.keys();\n          await Promise.all(\n            keys\n              .filter((key) => key.indexOf('vue3-sfc-raw-') === 0 || key.indexOf('vue3-sfc-compiled-') === 0)\n              .map((key) => caches.delete(key))\n          );\n        }\n        this.$root.addAlert(\"Success\", this.$root.translations.clear_cache_done || \"Cache cleared! Reloading...\", \"Cache\");\n        setTimeout(() => window.location.reload(), 600);\n      } catch (error) {\n        console.error(\"Error clearing frontend cache:\", error);\n        this.$root.addAlert(\"Error\", this.$root.translations.clear_cache_failed || \"Failed to clear cache.\", \"Cache\");\n        this.clearingCache = false;\n      }\n    },\n    async resendVerification() {\n      this.resendingVerification = true;\n      try {\n        const response = await this.$root.handleRequest(\"resendVerificationEmail\", {});\n        if (response.status === 200) {\n          this.$root.showToast(\"Verification email sent! Check your inbox.\", \"success\");\n        } else {\n          this.$root.showToast(response.message || \"Failed to resend verification email.\", \"error\");\n        }\n      } catch (error) {\n        console.error(\"Error resending verification:\", error);\n        this.$root.showToast(\"Failed to resend verification email.\", \"error\");\n      } finally {\n        this.resendingVerification = false;\n      }\n    },\n    async fetchNotifications() {\n      if (!this.$root.user) {\n        this.unreadCount = 0;\n        return;\n      }\n      try {\n        let response = await this.$root.handleRequest(\n          \"getUserNotifications\",\n          {}\n        );\n        if (response.success) {\n          this.unreadCount = response.data.unread_count;\n        }\n      } catch (error) {\n        console.error(\"Error fetching notifications:\", error);\n      }\n    },\n    addTab(route) {\n      if (!this.$root.tabs.some(tab => tab.path === route.path)) {\n        if (this.$root.tabs.length >= 4) {\n          let oldestTabIndex = 0;\n          for (let i = 1; i < this.$root.tabs.length; i++) {\n            if (\n              this.$root.tabs[i].timestamp <\n              this.$root.tabs[oldestTabIndex].timestamp\n            ) {\n              oldestTabIndex = i;\n            }\n          }\n          this.$root.tabs.splice(oldestTabIndex, 1);\n        }\n        this.$root.tabs.push({\n          name: route.name,\n          path: route.path,\n          title: this.getRouteTitle(route),\n          icon: route.meta.icon,\n          timestamp: Date.now(),\n        });\n      }\n    },\n    getRouteTitle(route) {\n      if (route.path.includes(\"chat\")) return this.$root.translations.chats;\n      if (route.path.includes(\"characters\")) return this.$root.translations.navbar_tab_your_characters;\n      if (route.path.includes(\"studio\")) return this.$root.translations.navbar_tab_image_studio;\n      if (route.path.includes(\"dashboard\")) return this.$root.translations.dashboard;\n      if (route.path === \"/store\") return this.$root.translations.store;\n      if (route.path.includes(\"/store/\")) return this.$root.translations.navbar_tab_store_item;\n      return this.$root.info.name;\n    },\n    closeTab(index) {\n      this.$root.tabs.splice(index, 1);\n      if (this.$root.tabs.length > 0) {\n        const newIndex = Math.max(0, index - 1);\n        this.$router.push({ name: this.$root.tabs[newIndex].name });\n      } else {\n        this.$router.push(\"/home\");\n      }\n    },\n    navigateTo(routePath) {\n      this.$router.push(routePath);\n    },\n    dragStart(index) {\n      this.draggedIndex = index;\n    },\n    drop(index) {\n      const draggedTab = this.$root.tabs[this.draggedIndex];\n      this.$root.tabs.splice(this.draggedIndex, 1);\n      this.$root.tabs.splice(index, 0, draggedTab);\n      this.draggedIndex = null;\n    },\n    saveTabs() {\n      const tabsToSave = JSON.parse(JSON.stringify(this.$root.tabs));\n      tabsToSave.forEach(tab => delete tab.iconError);\n      localStorage.setItem(\"tabs\", JSON.stringify(tabsToSave));\n    },\n    loadTabs() {\n      const savedTabs = localStorage.getItem(\"tabs\");\n      if (savedTabs) {\n        this.$root.tabs = JSON.parse(savedTabs);\n      } else {\n        this.$root.tabs = [];\n      }\n    },\n    tabButtonClasses(tab) {\n      const isActive = this.$route.path === tab.path;\n\n      const gradientTypeClasses = {\n        active:\n          \"border-t-2 border-b-2 border-t-theme-900 border-b-theme-950 shadow-theme-950/50 bg-gradient-to-b from-theme-920 to-theme-940 text-theme-300 active:bg-gradient-to-t active:border-t-theme-950 active:border-b-theme-900\",\n        inactive:\n          \"border-t-2 border-b-2 border-t-theme-900 border-b-theme-950 bg-gradient-to-b from-theme-900/40 to-theme-900/20 text-theme-400 hover:text-theme-200 hover:from-theme-900/60 hover:to-theme-900/40\",\n      };\n\n      const flatTypeClasses = {\n        active:\n          \"bg-theme-900 text-theme-200 active:bg-theme-800\",\n        inactive:\n          \"bg-theme-900/50 text-theme-400 hover:bg-theme-900/70 hover:text-theme-200\",\n      };\n\n      const typeClasses = this.$root.newTheme\n        ? flatTypeClasses\n        : gradientTypeClasses;\n\n      const base =\n        \"text-sm border-none\";\n\n      const stateClass = isActive\n        ? typeClasses.active\n        : typeClasses.inactive;\n\n      return [base, stateClass].join(\" \");\n    },\n  },\n  computed: {\n    canAccessStore() {\n      return this.$root?.canAccessStore?.() === true;\n    },\n    isNonDefaultTheme() {\n      const active = this.$root?.activeThemeId;\n      const def = this.$root?.themeRegistry?.defaultTheme || window.__MIOC_CONFIG?.defaultTheme || 'midnight';\n      return !!active && active !== def;\n    },\n    pathName() {\n      if (this.$route.path.includes(\"chat\")) return this.$root.translations.chats;\n      if (this.$route.path.includes(\"characters\")) return this.$root.translations.navbar_tab_your_characters;\n      if (this.$route.path === \"/store\") return this.$root.translations.store;\n      if (this.$route.path.includes(\"/store/\")) return this.$root.translations.navbar_tab_store_item;\n      return this.$root.info.name;\n    },\n    creditCount() {\n      const credits = Number(\n        this.$root?.user?.remaining_credits ?? this.$root?.user?.credits ?? 0\n      );\n      if (!Number.isFinite(credits)) return \"0.00\";\n      // Always show exactly 2 decimal places (credits are fractional now).\n      return credits.toLocaleString(undefined, {\n        minimumFractionDigits: 2,\n        maximumFractionDigits: 2,\n      });\n    },\n    showStoreContextActions() {\n      return [\"/dashboard\", \"/store\", \"/profile/\"].some((segment) =>\n        this.$route.path.includes(segment)\n      );\n    },\n  },\n};\n</script>\n\n<style scoped>\n.tabs-container {\n}\n</style>\n","/components/modules/BaseButton.vue":"<template>\n    <button\n        :type=\"htmlType\"\n        :disabled=\"disabled\"\n        :class=\"buttonClasses\"\n\n        class=\"transition-all select-none duration-200\"\n    >\n        <div class=\"flex items-center justify-center gap-2\">\n            <i v-if=\"icon\" :class=\"iconClasses\"></i>\n            <span v-if=\"resolvedLabel\" class=\"whitespace-nowrap\">{{ resolvedLabel }}</span>\n            <slot v-if=\"$slots.default\" class=\"whitespace-nowrap\"></slot>\n        </div>\n    </button>\n</template>\n\n<script>\nexport default {\n    name: 'BaseButton',\n\n    props: {\n        label: {\n            type: String,\n            default: '',\n        },\n        icon: {\n            type: String,\n            default: '',\n        },\n        type: {\n            type: String,\n            default: 'primary',\n            validator: value => ['primary', 'secondary', 'danger', 'gradient', 'warning'].includes(value),\n        },\n        size: {\n            type: String,\n            default: 'medium',\n            validator: value => ['small', 'medium', 'large'].includes(value),\n        },\n        disabled: {\n            type: Boolean,\n            default: false,\n        },\n        color: {\n            type: String,\n            default: 'brand',\n        },\n        htmlType: {\n            type: String,\n            default: 'button',\n            validator: value => ['button', 'submit', 'reset'].includes(value),\n        },\n        background: {\n            type: Boolean,\n            default: true,\n        },\n    },\n    computed: {\n        resolvedLabel() {\n            const label = this.label;\n            if (!label) return label;\n\n            const match = /^\\s*\\{\\{(.+?)\\}\\}\\s*$/.exec(label);\n            if (!match) return label;\n\n            try {\n                const value = new Function('$root', 'return (' + match[1] + ');')(this.$root);\n                return value != null ? value : '';\n            } catch (e) {\n                console.warn('BaseButton: failed to evaluate label expression:', label, e);\n                return label;\n            }\n        },\n        buttonClasses() {\n            const baseClasses = 'rounded-md font-semibold transition-all select-none duration-200';\n\n            const gradientTypeClasses = {\n                primary: `border-t-2 shadow-xl border-b-2 border-t-${this.color}-300 border-b-${this.color}-700 shadow-${this.color}-950/50 bg-gradient-to-b from-${this.color}-400 to-${this.color}-500 text-${this.color}-950 active:bg-gradient-to-t active:border-t-${this.color}-600 active:border-b-${this.color}-300`,\n                secondary: 'border-t-2 border-b-2 border-t-theme-900 border-b-theme-940 shadow-theme-950/50 bg-gradient-to-b from-theme-920 to-theme-940 text-theme-300 active:bg-gradient-to-t active:border-t-theme-950 active:border-b-theme-900',\n                danger: 'border-t-2 border-b-2 border-t-rose-300 border-b-rose-700 shadow-rose-950/50 bg-gradient-to-b from-rose-400 to-rose-500 text-rose-950 active:bg-gradient-to-t active:border-t-rose-600 active:border-b-rose-300',\n                gradient: 'border-t-2 border-b-2 border-t-theme-900 border-b-theme-950 shadow-theme-950/50 bg-gradient-to-b from-theme-900/50 to-theme-900/25 text-theme-300',\n                warning: 'border-t-2 border-b-2 border-t-amber-300 border-b-amber-700 shadow-amber-950/50 bg-gradient-to-b from-amber-400 to-amber-500 text-amber-950 active:bg-gradient-to-t active:border-t-amber-600 active:border-b-amber-300'\n            };\n\n            const flatTypeClasses = {\n                primary: `bg-${this.color}-400 text-${this.color}-950 active:bg-${this.color}-500`,\n                secondary: ' bg-theme-900 text-theme-300 active:bg-theme-800',\n                danger: ' bg-rose-500 text-white active:bg-rose-600',\n                gradient: ' bg-theme-900/50 text-theme-300',\n                warning: ' bg-amber-500 text-white active:bg-amber-600'\n            };\n            \n            const typeClasses = this.$root.newTheme ? flatTypeClasses : gradientTypeClasses;\n\n            const sizeClasses = {\n                small: 'py-1 px-3 text-sm',\n                medium: 'py-1 px-4 text-base',\n                large: 'py-2 px-6 text-lg'\n            };\n\n            const disabledClasses = 'opacity-50 cursor-not-allowed';\n\n            const classes = [\n                baseClasses,\n                sizeClasses[this.size] || sizeClasses.medium\n            ];\n\n            if (this.background) {\n                classes.push(typeClasses[this.type] || typeClasses.gradient);\n            }\n\n            if (this.disabled) {\n                classes.push(disabledClasses);\n            }\n            \n            return classes.join(' ');\n        },\n        iconClasses() {\n            return ['ph', this.icon];\n        },\n    },\n    methods: {\n\n    },\n};\n</script>","/components/core/ThemedLogo.vue":"<template>\n  <svg\n    version=\"1.1\"\n    xmlns=\"http://www.w3.org/2000/svg\"\n    xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n    viewBox=\"0 0 500 500\"\n    xml:space=\"preserve\"\n    class=\"themed-logo\"\n    :style=\"{ color: 'rgb(var(--brand-500))' }\"\n  >\n    <path fill=\"rgb(var(--theme-950))\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM385.937073,100.970520 \n\tC385.937073,100.970520 385.924713,100.888191 385.307159,101.124962 \n\tC384.176666,102.739304 383.046143,104.353638 381.338470,106.144562 \n\tC380.861237,107.016800 380.384003,107.889038 379.307983,109.089935 \n\tC375.271729,114.080467 371.235474,119.070992 366.685669,124.383255 \n\tC366.428833,124.912025 366.171997,125.440796 365.380493,126.340828 \n\tC363.868469,128.434814 362.356445,130.528793 360.273987,132.964767 \n\tC359.906555,133.515015 359.539093,134.065262 358.666443,134.979828 \n\tC355.739258,138.564270 352.812073,142.148712 349.323395,145.998703 \n\tC348.890259,146.685043 348.457153,147.371399 347.439240,148.380814 \n\tC343.246643,153.791855 339.054047,159.202881 334.305023,164.914413 \n\tC333.834686,165.596771 333.364380,166.279144 332.315063,167.288528 \n\tC329.718506,170.987289 327.121948,174.686050 324.486389,178.466431 \n\tC324.486389,178.466431 324.403046,178.501633 323.717377,178.350067 \n\tC319.550842,183.588486 315.384308,188.826920 310.726013,194.415527 \n\tC310.411255,194.916061 310.096466,195.416580 309.193573,196.211258 \n\tC301.759033,205.459976 294.324493,214.708694 286.338104,224.246506 \n\tC285.773804,225.110596 285.209503,225.974701 284.069458,227.195053 \n\tC281.118530,231.151443 278.167572,235.107834 274.752350,239.454330 \n\tC274.387482,239.927704 274.022614,240.401077 273.059906,241.149185 \n\tC266.329834,249.489777 259.599731,257.830383 252.505630,266.622101 \n\tC247.192612,260.126953 242.200043,254.023529 236.981857,247.311493 \n\tC235.971405,246.214340 234.960953,245.117188 233.748962,243.378357 \n\tC221.375000,228.162247 208.975784,212.966553 196.633820,197.724533 \n\tC183.033676,180.928726 169.512466,164.069000 155.905121,147.279053 \n\tC148.485184,138.123688 140.958069,129.055191 133.206024,119.371994 \n\tC132.783035,118.920433 132.360046,118.468872 131.765823,117.365456 \n\tC128.881485,113.973671 125.975319,110.600159 123.118263,107.185547 \n\tC119.438438,102.787605 115.797958,98.356743 111.896347,93.302849 \n\tC110.508568,91.622360 109.120796,89.941864 107.098801,87.493378 \n\tC107.098801,90.908447 107.098801,93.257500 106.953674,96.453934 \n\tC106.761726,178.378311 106.554420,260.302673 106.434288,342.227173 \n\tC106.429504,345.486938 107.253212,348.747925 107.710426,352.705139 \n\tC107.879738,353.137054 108.049057,353.568970 108.228516,354.705231 \n\tC114.533875,370.642426 130.382050,381.922668 147.142731,381.941132 \n\tC216.914322,382.018005 286.686646,382.106232 356.456635,381.765778 \n\tC362.641418,381.735596 368.811218,378.636627 375.614990,376.933960 \n\tC376.068359,376.268433 376.521729,375.602905 377.695984,375.029144 \n\tC378.797211,373.989349 379.898468,372.949585 381.683105,372.117157 \n\tC382.432800,371.685089 383.182495,371.253021 384.548431,370.618683 \n\tC385.753906,369.102631 386.959351,367.586578 388.714722,365.900146 \n\tC389.161469,365.304962 389.608215,364.709747 390.670044,363.732910 \n\tC391.726044,361.768005 392.782043,359.803101 394.196716,357.318665 \n\tC395.132080,352.140961 396.889862,346.961609 396.879303,341.785828 \n\tC396.723785,265.441833 396.313446,189.098373 396.037201,112.754524 \n\tC396.015808,106.840263 396.544067,100.924019 396.978058,94.170441 \n\tC396.978058,92.173653 396.978058,90.176872 396.978058,86.855919 \n\tC393.587585,91.034927 391.198822,93.979225 388.278809,97.138725 \n\tC387.890503,97.770187 387.502167,98.401649 386.670532,99.400787 \n\tC386.405060,99.905846 386.139618,100.410896 385.937073,100.970520 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM112.140533,93.940063 \n\tC115.797958,98.356743 119.438438,102.787605 123.118263,107.185547 \n\tC125.975319,110.600159 128.881485,113.973671 131.589478,117.784393 \n\tC132.101852,118.784729 132.790588,119.366127 133.479309,119.947517 \n\tC140.958069,129.055191 148.485184,138.123688 155.905121,147.279053 \n\tC169.512466,164.069000 183.033676,180.928726 196.633820,197.724533 \n\tC208.975784,212.966553 221.375000,228.162247 233.662857,243.947815 \n\tC233.719971,245.961533 233.863205,247.405777 234.020309,248.990128 \n\tC235.442551,248.512634 236.325012,248.216370 237.207474,247.920105 \n\tC242.200043,254.023529 247.192612,260.126953 252.505630,266.622101 \n\tC259.599731,257.830383 266.329834,249.489777 273.628296,240.995270 \n\tC274.536682,240.248962 274.876648,239.656601 275.216644,239.064224 \n\tC278.167572,235.107834 281.118530,231.151443 284.660980,227.141159 \n\tC288.946472,227.691010 288.204865,225.974182 286.889954,223.957397 \n\tC294.324493,214.708694 301.759033,205.459976 309.748779,196.035614 \n\tC310.608582,195.261749 310.913177,194.663544 311.217773,194.065338 \n\tC315.384308,188.826920 319.550842,183.588486 324.149841,178.562195 \n\tC324.671509,178.821487 324.760651,178.868652 324.849823,178.915817 \n\tC324.741699,178.738815 324.633545,178.561813 324.525391,178.384811 \n\tC327.121948,174.686050 329.718506,170.987289 332.926239,167.026001 \n\tC333.978760,166.046951 334.420105,165.330444 334.861450,164.613922 \n\tC339.054047,159.202881 343.246643,153.791855 347.957550,148.395874 \n\tC351.551849,148.889786 350.344818,147.114914 349.884888,145.733170 \n\tC352.812073,142.148712 355.739258,138.564270 359.217834,134.833969 \n\tC360.127655,133.999664 360.486053,133.311218 360.844452,132.622772 \n\tC362.356445,130.528793 363.868469,128.434814 365.900391,126.111679 \n\tC366.679962,125.275528 366.939606,124.668533 367.199219,124.061531 \n\tC371.235474,119.070992 375.271729,114.080467 379.732056,109.267670 \n\tC383.008484,111.298607 384.548981,113.696236 385.278717,117.247131 \n\tC386.074738,121.120621 385.512268,123.575531 382.005493,125.425728 \n\tC381.643585,125.616669 382.006775,127.181969 381.943237,128.432388 \n\tC338.840179,181.886887 295.827362,235.018555 252.241226,288.858398 \n\tC246.583694,281.544647 241.334152,274.758331 236.209442,267.741943 \n\tC235.748474,267.056610 235.162659,266.601349 234.306946,265.968567 \n\tC226.237442,256.339783 218.371277,246.942444 210.660095,237.419586 \n\tC204.840439,230.232681 199.219086,222.885208 193.640381,215.512299 \n\tC193.648331,215.445282 193.525360,215.475204 193.088196,215.399170 \n\tC168.908432,186.008102 145.042892,156.722992 121.177353,127.437881 \n\tC120.826752,127.625404 120.476158,127.812927 120.125557,128.000458 \n\tC120.125557,130.117798 120.125626,132.235153 120.125542,134.352493 \n\tC120.122688,202.152267 120.188171,269.952179 120.032547,337.751617 \n\tC120.012558,346.461700 121.143143,354.616608 125.775795,362.231750 \n\tC125.600494,363.002594 125.598694,363.558838 125.596886,364.115082 \n\tC126.110977,363.981964 126.625069,363.848816 127.443710,363.864380 \n\tC133.546188,370.203827 140.452606,372.132019 149.091187,372.092590 \n\tC221.385803,371.762665 293.682678,371.926727 366.185120,372.129974 \n\tC366.950470,372.360535 367.509583,372.403046 368.068665,372.445526 \n\tC367.969940,371.927643 367.871216,371.409790 367.958435,370.609497 \n\tC370.768280,368.237091 373.392181,366.147125 376.023102,364.328674 \n\tC376.184906,365.194397 376.339691,365.788605 376.494446,366.382812 \n\tC376.958313,366.299805 377.422211,366.216827 377.886078,366.133850 \n\tC377.568604,365.082733 377.251099,364.031616 377.011932,362.640747 \n\tC378.680847,359.520233 380.271393,356.739532 382.194519,354.057068 \n\tC384.866608,355.865906 387.206085,357.576508 389.545563,359.287109 \n\tC389.179138,359.572144 388.812714,359.857208 388.446289,360.142273 \n\tC390.243530,359.374237 392.040802,358.606201 393.838043,357.838196 \n\tC392.782043,359.803101 391.726044,361.768005 390.133606,363.722778 \n\tC388.898468,363.792877 388.199829,363.873138 387.501160,363.953400 \n\tC387.722382,364.659119 387.943604,365.364807 388.164795,366.070526 \n\tC386.959351,367.586578 385.753906,369.102631 384.005432,370.558868 \n\tC382.641541,370.969299 381.820618,371.439514 380.999695,371.909790 \n\tC379.898468,372.949585 378.797211,373.989349 377.109772,374.847412 \n\tC376.011688,375.431427 375.499847,376.197174 374.987976,376.962921 \n\tC368.811218,378.636627 362.641418,381.735596 356.456635,381.765778 \n\tC286.686646,382.106232 216.914322,382.018005 147.142731,381.941132 \n\tC130.382050,381.922668 114.533875,370.642426 108.462830,354.259338 \n\tC108.361725,353.211761 108.026306,352.610046 107.690895,352.008362 \n\tC107.253212,348.747925 106.429504,345.486938 106.434288,342.227173 \n\tC106.554420,260.302673 106.761726,178.378311 107.428925,96.097504 \n\tC109.316292,95.140739 110.728409,94.540398 112.140533,93.940063 \nM154.498276,163.528320 \n\tC154.498276,163.528320 154.482101,163.486298 154.498276,163.528320 \nM348.498108,150.528275 \n\tC348.498108,150.528275 348.482086,150.486404 348.498108,150.528275 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM382.033508,128.109558 \n\tC382.006775,127.181969 381.643585,125.616669 382.005493,125.425728 \n\tC385.512268,123.575531 386.074738,121.120621 385.278717,117.247131 \n\tC384.548981,113.696236 383.008484,111.298607 380.031433,109.103348 \n\tC380.384003,107.889038 380.861237,107.016800 381.973633,106.123680 \n\tC383.788788,106.263565 384.968781,106.424332 386.413971,106.621231 \n\tC386.221527,104.366211 386.073120,102.627197 385.924713,100.888191 \n\tC385.924713,100.888191 385.937073,100.970520 386.163940,100.914627 \n\tC386.631836,100.250198 386.872833,99.641655 387.113831,99.033112 \n\tC387.502167,98.401649 387.890503,97.770187 388.915466,96.977249 \n\tC391.973694,96.213409 394.395264,95.611046 396.816833,95.008698 \n\tC396.544067,100.924019 396.015808,106.840263 396.037201,112.754524 \n\tC396.313446,189.098373 396.723785,265.441833 396.879303,341.785828 \n\tC396.889862,346.961609 395.132080,352.140961 394.017395,357.578430 \n\tC392.040802,358.606201 390.243530,359.374237 388.446289,360.142273 \n\tC388.812714,359.857208 389.179138,359.572144 389.545563,359.287109 \n\tC387.206085,357.576508 384.866608,355.865906 382.217712,353.635437 \n\tC382.489471,344.754425 383.070648,336.393250 383.976868,327.963165 \n\tC387.092987,325.302917 386.717377,323.010223 383.524841,320.544067 \n\tC383.485321,317.755280 383.570129,315.393799 383.993713,312.968384 \n\tC388.212433,309.101837 387.786438,294.194763 383.522064,288.523499 \n\tC383.377563,264.329681 383.322327,240.586823 383.356293,216.844086 \n\tC383.375244,203.573151 383.542114,190.302414 383.947815,176.976959 \n\tC387.233582,174.864899 385.951172,173.351807 383.496582,171.521027 \n\tC383.454437,158.720154 383.536896,146.370758 383.847260,133.899292 \n\tC383.909363,132.843872 383.743591,131.910507 383.455933,130.633881 \n\tC382.900543,129.563599 382.467010,128.836578 382.033508,128.109558 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM396.897461,94.589569 \n\tC394.395264,95.611046 391.973694,96.213409 389.181091,96.869644 \n\tC391.198822,93.979225 393.587585,91.034927 396.978058,86.855919 \n\tC396.978058,90.176872 396.978058,92.173653 396.897461,94.589569 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM112.018440,93.621452 \n\tC110.728409,94.540398 109.316292,95.140739 107.501488,95.673813 \n\tC107.098801,93.257500 107.098801,90.908447 107.098801,87.493378 \n\tC109.120796,89.941864 110.508568,91.622360 112.018440,93.621452 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM385.615936,101.006577 \n\tC386.073120,102.627197 386.221527,104.366211 386.413971,106.621231 \n\tC384.968781,106.424332 383.788788,106.263565 382.262207,106.035385 \n\tC383.046143,104.353638 384.176666,102.739304 385.615936,101.006577 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM237.094666,247.615784 \n\tC236.325012,248.216370 235.442551,248.512634 234.020309,248.990128 \n\tC233.863205,247.405777 233.719971,245.961533 233.763626,244.268661 \n\tC234.960953,245.117188 235.971405,246.214340 237.094666,247.615784 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM286.614014,224.101959 \n\tC288.204865,225.974182 288.946472,227.691010 284.948853,226.963028 \n\tC285.209503,225.974701 285.773804,225.110596 286.614014,224.101959 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM388.439758,365.985352 \n\tC387.943604,365.364807 387.722382,364.659119 387.501160,363.953400 \n\tC388.199829,363.873138 388.898468,363.792877 389.826050,363.913574 \n\tC389.608215,364.709747 389.161469,365.304962 388.439758,365.985352 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM349.604126,145.865936 \n\tC350.344818,147.114914 351.551849,148.889786 348.249939,148.234344 \n\tC348.457153,147.371399 348.890259,146.685043 349.604126,145.865936 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM381.341370,372.013458 \n\tC381.820618,371.439514 382.641541,370.969299 383.697327,370.659973 \n\tC383.182495,371.253021 382.432800,371.685089 381.341370,372.013458 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM375.301514,376.948425 \n\tC375.499847,376.197174 376.011688,375.431427 376.749329,374.801544 \n\tC376.521729,375.602905 376.068359,376.268433 375.301514,376.948425 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM133.342667,119.659760 \n\tC132.790588,119.366127 132.101852,118.784729 131.675079,118.110329 \n\tC132.360046,118.468872 132.783035,118.920433 133.342667,119.659760 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM274.984497,239.259277 \n\tC274.876648,239.656601 274.536682,240.248962 273.927216,240.857895 \n\tC274.022614,240.401077 274.387482,239.927704 274.984497,239.259277 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM310.971893,194.240433 \n\tC310.913177,194.663544 310.608582,195.261749 310.042847,195.888535 \n\tC310.096466,195.416580 310.411255,194.916061 310.971893,194.240433 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM334.583252,164.764160 \n\tC334.420105,165.330444 333.978760,166.046951 333.215759,166.862488 \n\tC333.364380,166.279144 333.834686,165.596771 334.583252,164.764160 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM107.700661,352.356750 \n\tC108.026306,352.610046 108.361725,353.211761 108.457756,353.907166 \n\tC108.049057,353.568970 107.879738,353.137054 107.700661,352.356750 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM386.892181,99.216949 \n\tC386.872833,99.641655 386.631836,100.250198 386.132507,100.887344 \n\tC386.139618,100.410896 386.405060,99.905846 386.892181,99.216949 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM366.942444,124.222397 \n\tC366.939606,124.668533 366.679962,125.275528 366.167725,125.926048 \n\tC366.171997,125.440796 366.428833,124.912025 366.942444,124.222397 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM360.559204,132.793762 \n\tC360.486053,133.311218 360.127655,133.999664 359.470459,134.651810 \n\tC359.539093,134.065262 359.906555,133.515015 360.559204,132.793762 \nz\"/>\n    <path fill=\"rgb(var(--theme-950))\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM381.943268,128.432388 \n\tC382.467010,128.836578 382.900543,129.563599 383.334473,131.007446 \n\tC383.429718,132.489960 383.524506,133.255661 383.619324,134.021347 \n\tC383.536896,146.370758 383.454437,158.720154 383.365662,171.929504 \n\tC383.453644,174.203476 383.547974,175.617538 383.642303,177.031586 \n\tC383.542114,190.302414 383.375244,203.573151 383.356293,216.844086 \n\tC383.322327,240.586823 383.377563,264.329681 383.384399,288.975708 \n\tC383.467224,297.596710 383.561066,305.314545 383.654938,313.032349 \n\tC383.570129,315.393799 383.485321,317.755280 383.385529,320.968933 \n\tC383.464294,323.891449 383.558075,325.961792 383.651855,328.032104 \n\tC383.070648,336.393250 382.489471,344.754425 381.885101,353.537201 \n\tC380.271393,356.739532 378.680847,359.520233 376.776062,362.735474 \n\tC376.313232,363.465729 376.164642,363.761444 376.016052,364.057159 \n\tC373.392181,366.147125 370.768280,368.237091 367.686890,370.639832 \n\tC366.812561,371.282379 366.395721,371.612152 365.978882,371.941895 \n\tC293.682678,371.926727 221.385803,371.762665 149.091187,372.092590 \n\tC140.452606,372.132019 133.546188,370.203827 127.403908,363.593597 \n\tC126.689461,362.788452 126.319374,362.402802 125.949295,362.017151 \n\tC121.143143,354.616608 120.012558,346.461700 120.032547,337.751617 \n\tC120.188171,269.952179 120.122688,202.152267 120.125542,134.352493 \n\tC120.125626,132.235153 120.125557,130.117798 120.125557,128.000458 \n\tC120.476158,127.812927 120.826752,127.625404 121.177353,127.437881 \n\tC145.042892,156.722992 168.908432,186.008102 193.128418,215.411346 \n\tC193.482849,215.529480 193.509476,215.609207 193.509476,215.609207 \n\tC199.219086,222.885208 204.840439,230.232681 210.660095,237.419586 \n\tC218.371277,246.942444 226.237442,256.339783 234.421814,266.252502 \n\tC235.232620,267.133270 235.658630,267.552643 236.084625,267.972015 \n\tC241.334152,274.758331 246.583694,281.544647 252.241226,288.858398 \n\tC295.827362,235.018555 338.840179,181.886887 381.943268,128.432388 \nM345.994263,292.717224 \n\tC355.434021,297.402740 362.841766,293.457550 363.939362,282.805054 \n\tC366.667480,256.327515 369.219299,229.831604 371.760376,203.335251 \n\tC372.171570,199.047562 371.741760,194.677124 367.182526,192.676193 \n\tC362.818817,190.761078 359.909058,193.882797 357.408508,196.789749 \n\tC342.885803,213.672699 328.457703,230.637039 313.995697,247.572250 \n\tC305.951385,256.992279 306.609833,263.346161 316.595398,270.863556 \n\tC326.150604,278.056976 335.800354,285.124817 345.994263,292.717224 \nM153.573471,205.929443 \n\tC150.675079,202.726791 148.127365,199.067993 144.758179,196.477707 \n\tC142.411514,194.673508 138.269714,192.826294 136.153854,193.763046 \n\tC134.002045,194.715729 133.182007,198.996536 132.126801,201.944550 \n\tC131.719238,203.083267 132.256134,204.565674 132.383896,205.889435 \n\tC133.262848,214.995743 134.138016,224.102463 135.032196,233.207275 \n\tC136.706055,250.250931 138.249100,267.309235 140.132263,284.329834 \n\tC141.097534,293.054230 149.798813,297.933105 156.472260,293.381226 \n\tC167.715775,285.712250 178.794922,277.766724 189.552353,269.432983 \n\tC196.869965,263.764069 197.048218,256.077148 190.947693,249.037628 \n\tC178.648239,234.845062 166.343719,220.656891 153.573471,205.929443 \nM295.542664,326.241364 \n\tC302.146515,322.675110 304.762878,316.381134 306.328827,309.659241 \n\tC309.030975,298.059967 307.658386,287.065033 299.250610,278.018250 \n\tC293.259064,271.571381 285.727478,271.841949 279.514008,278.041260 \n\tC268.902527,288.628540 266.910339,308.077911 275.166473,320.485321 \n\tC280.231079,328.096466 286.668335,330.113251 295.542664,326.241364 \nM196.074051,297.762482 \n\tC197.458405,304.513031 197.598999,311.857391 200.480789,317.892975 \n\tC206.875153,331.285126 221.765167,331.694794 229.166031,319.381927 \n\tC236.459595,307.247559 234.165161,288.188629 224.207748,278.195587 \n\tC217.678986,271.643463 210.801071,271.758667 204.101151,278.040375 \n\tC198.575119,283.221436 197.287277,289.962494 196.074051,297.762482 \nM244.460968,344.029205 \n\tC246.839630,346.746857 249.218292,349.464539 252.001419,352.644318 \n\tC257.202820,346.756989 261.596466,341.783905 266.792175,335.902985 \n\tC256.615448,335.902985 247.926010,335.902985 238.050674,335.902985 \n\tC240.435196,338.938599 242.219177,341.209686 244.460968,344.029205 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM376.023071,364.328674 \n\tC376.164642,363.761444 376.313232,363.465729 376.697693,363.075287 \n\tC377.251099,364.031616 377.568604,365.082733 377.886078,366.133850 \n\tC377.422211,366.216827 376.958313,366.299805 376.494446,366.382812 \n\tC376.339691,365.788605 376.184906,365.194397 376.023071,364.328674 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM125.775803,362.231750 \n\tC126.319374,362.402802 126.689461,362.788452 127.099350,363.444885 \n\tC126.625069,363.848816 126.110977,363.981964 125.596886,364.115082 \n\tC125.598694,363.558838 125.600494,363.002594 125.775803,362.231750 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM366.185120,372.130005 \n\tC366.395721,371.612152 366.812561,371.282379 367.500946,370.922272 \n\tC367.871216,371.409790 367.969940,371.927643 368.068665,372.445526 \n\tC367.509583,372.403046 366.950470,372.360535 366.185120,372.130005 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM236.209442,267.741943 \n\tC235.658630,267.552643 235.232620,267.133270 234.691742,266.429993 \n\tC235.162659,266.601349 235.748474,267.056610 236.209442,267.741943 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM193.442627,215.517303 \n\tC193.525360,215.475204 193.648331,215.445282 193.640381,215.512299 \n\tC193.509476,215.609207 193.482849,215.529480 193.442627,215.517303 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM324.505890,178.425629 \n\tC324.633545,178.561813 324.741699,178.738815 324.849823,178.915817 \n\tC324.760651,178.868652 324.671509,178.821487 324.492676,178.637970 \n\tC324.403046,178.501633 324.486389,178.466431 324.505890,178.425629 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM154.490189,163.507309 \n\tC154.482101,163.486298 154.498276,163.528320 154.490189,163.507309 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM348.490112,150.507339 \n\tC348.482086,150.486404 348.498108,150.528275 348.490112,150.507339 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM383.993713,312.968384 \n\tC383.561066,305.314545 383.467224,297.596710 383.510986,289.426727 \n\tC387.786438,294.194763 388.212433,309.101837 383.993713,312.968384 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM383.976898,327.963165 \n\tC383.558075,325.961792 383.464294,323.891449 383.509827,321.396301 \n\tC386.717377,323.010223 387.092987,325.302917 383.976898,327.963165 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM383.947815,176.976959 \n\tC383.547974,175.617538 383.453644,174.203476 383.490265,172.380951 \n\tC385.951172,173.351807 387.233582,174.864899 383.947815,176.976959 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM383.847229,133.899292 \n\tC383.524506,133.255661 383.429718,132.489960 383.456360,131.350708 \n\tC383.743591,131.910507 383.909363,132.843872 383.847229,133.899292 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM345.701416,292.482544 \n\tC335.800354,285.124817 326.150604,278.056976 316.595398,270.863556 \n\tC306.609833,263.346161 305.951385,256.992279 313.995697,247.572250 \n\tC328.457703,230.637039 342.885803,213.672699 357.408508,196.789749 \n\tC359.909058,193.882797 362.818817,190.761078 367.182526,192.676193 \n\tC371.741760,194.677124 372.171570,199.047562 371.760376,203.335251 \n\tC369.219299,229.831604 366.667480,256.327515 363.939362,282.805054 \n\tC362.841766,293.457550 355.434021,297.402740 345.701416,292.482544 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM153.807373,206.198166 \n\tC166.343719,220.656891 178.648239,234.845062 190.947693,249.037628 \n\tC197.048218,256.077148 196.869965,263.764069 189.552353,269.432983 \n\tC178.794922,277.766724 167.715775,285.712250 156.472260,293.381226 \n\tC149.798813,297.933105 141.097534,293.054230 140.132263,284.329834 \n\tC138.249100,267.309235 136.706055,250.250931 135.032196,233.207275 \n\tC134.138016,224.102463 133.262848,214.995743 132.383896,205.889435 \n\tC132.256134,204.565674 131.719238,203.083267 132.126801,201.944550 \n\tC133.182007,198.996536 134.002045,194.715729 136.153854,193.763046 \n\tC138.269714,192.826294 142.411514,194.673508 144.758179,196.477707 \n\tC148.127365,199.067993 150.675079,202.726791 153.807373,206.198166 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM295.239929,326.460419 \n\tC286.668335,330.113251 280.231079,328.096466 275.166473,320.485321 \n\tC266.910339,308.077911 268.902527,288.628540 279.514008,278.041260 \n\tC285.727478,271.841949 293.259064,271.571381 299.250610,278.018250 \n\tC307.658386,287.065033 309.030975,298.059967 306.328827,309.659241 \n\tC304.762878,316.381134 302.146515,322.675110 295.239929,326.460419 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM196.098267,297.314850 \n\tC197.287277,289.962494 198.575119,283.221436 204.101151,278.040375 \n\tC210.801071,271.758667 217.678986,271.643463 224.207748,278.195587 \n\tC234.165161,288.188629 236.459595,307.247559 229.166031,319.381927 \n\tC221.765167,331.694794 206.875153,331.285126 200.480789,317.892975 \n\tC197.598999,311.857391 197.458405,304.513031 196.098267,297.314850 \nz\"/>\n    <path fill=\"currentColor\" opacity=\"1.000000\" stroke=\"none\"\n\td=\"\nM244.232071,343.755005 \n\tC242.219177,341.209686 240.435196,338.938599 238.050674,335.902985 \n\tC247.926010,335.902985 256.615448,335.902985 266.792175,335.902985 \n\tC261.596466,341.783905 257.202820,346.756989 252.001419,352.644318 \n\tC249.218292,349.464539 246.839630,346.746857 244.232071,343.755005 \nz\"/>\n  </svg>\n</template>\n\n<script>\nexport default {\n  name: \"ThemedLogo\",\n  props: {\n    defaultTheme: {\n      type: Boolean,\n      default: false,\n    },\n  },\n};\n</script>\n\n<style scoped>\n.themed-logo {\n  display: block;\n}\n</style>\n","/components/core/sidebar.vue":"<template>\n  <div class=\"order-2 md:order-none mt-auto sm:mt-0\">\n    <!-- Desktop Sidebar -->\n    <div\n      :class=\"\n        $route.params.id || $route.params.articleId\n          ? 'hidden md:flex'\n          : 'hidden md:flex'\n      \"\n      class=\"flex-col max-h-screen overflow-y-auto p-2 relative border-r border-theme-900 gap-2\"\n    >\n      <!-- Chat Section (moved to top) -->\n      <div>\n        <button\n          :class=\"{ 'bg-theme-900/50': $route.path.includes('chat') }\"\n          @click=\"handleAuthClick('chat')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n        >\n          <span class=\"ph-fill text-xl ph-chat-circle\"></span>\n          <div class=\"text-theme-300 text-xs\">\n            {{ t('chat', 'Chat') }}\n          </div>\n        </button>\n      </div>\n\n      <div>\n        <button\n          :class=\"{ 'bg-theme-900/50': $route.path.includes('studio') }\"\n          @click=\"user ? (!$route.path.includes('studio') ? $router.push('/studio') : null) : safeOpenModal('login')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n        >\n          <span class=\"ph-fill text-xl ph-camera\"></span>\n          <div class=\"text-theme-300 text-xs\">{{ $root.translations.sidebar_studio }}</div>\n        </button>\n      </div>\n\n      <hr class=\"border-theme-900\" />\n      \n      <!-- Crew Section (moved up) -->\n      <div>\n        <button\n          :class=\"{ 'bg-theme-900/50': sectionOpen.crew }\"\n          @click=\"handleAuthClick('crew')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n        >\n          <div class=\"relative\">\n            <span class=\"ph-fill text-xl ph-users-three\"></span>\n            <span\n              class=\"ph-fill text-xs ph-caret-down absolute -top-1 left-1 text-theme-500 transition-transform duration-200\"\n              :class=\"{ 'rotate-180': sectionOpen.crew }\"\n            ></span>\n          </div>\n          <div class=\"text-theme-300 text-xs\">\n            {{ t('bots', 'Bots') }}\n          </div>\n        </button>\n        <transition name=\"sidebar-collapse\">\n          <div v-if=\"sectionOpen.crew && user\" class=\"flex flex-col\">\n            <button\n              :class=\"{ 'bg-theme-900/50': $route.path.includes('create') }\"\n              @click=\"safeOpenModal('create', {}, true, true)\"\n              class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n            >\n              <span class=\"ph-fill text-xl ph-magic-wand\"></span>\n              <div class=\"text-theme-300 text-xs\">\n                {{ t('create_bot_sidebar', 'Create') }}\n              </div>\n            </button>\n            <button\n              :class=\"{ 'bg-theme-900/50': $route.path.includes('characters') }\"\n              @click=\"\n                !$route.path.includes('characters')\n                  ? $router.push('/characters')\n                  : null\n              \"\n              class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n            >\n              <span class=\"ph-fill text-xl ph-users-three\"></span>\n              <div class=\"text-theme-300 text-xs\">\n                {{ t('crew', 'Crew') }}\n              </div>\n            </button>\n            <button\n              @click=\"safeOpenModal('LorebookModal', {}, true, true)\"\n              class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n            >\n              <span class=\"ph-fill text-xl ph-book-open-text\"></span>\n              <div class=\"text-theme-300 text-xs sidebar-label\">\n                <span class=\"sidebar-label-text\">{{ t('lorebooks', 'Lore') }}</span>\n              </div>\n            </button>\n            <button\n              v-if=\"isAdmin\"\n              @click=\"safeOpenModal('AdminChangelogModal')\"\n              class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n            >\n              <span class=\"ph-fill text-xl ph-users\"></span>\n              <div class=\"text-theme-300 text-xs\">{{ $root.translations.sidebar_change }}</div>\n            </button>\n            \n\n          </div>\n        </transition>\n      </div>\n\n      <hr class=\"border-theme-900\" />\n\n      <!-- Dashboard Section -->\n      <div>\n        <button\n          :class=\"{ 'bg-theme-900/50': $route.path.includes('dashboard') }\"\n          @click=\"handleAuthClick('dashboard')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n        >\n          <span class=\"ph-fill text-xl ph-user-circle-gear\"></span>\n          <div class=\"text-theme-300 text-xs\">{{ t('you', 'You') }}</div>\n        </button>\n      </div>\n\n      <div>\n        <button\n          :class=\"{ 'bg-theme-900/50': isModalOpen('AchievementsModal') }\"\n          @click=\"user ? safeOpenModal('AchievementsModal', { initialTab: 'achievements', initialCategory: 'store' }) : safeOpenModal('login')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n        >\n          <span class=\"ph-fill text-xl ph-trophy\"></span>\n          <div class=\"text-theme-300 text-xs\">{{ $root.translations.sidebar_lvls }}</div>\n        </button>\n      </div>\n\n      <!-- Plans Section (moved after dashboard) -->\n      <div\n        v-if=\"user && (planIsZero || isAdmin)\"\n      >\n        <button\n          @click=\"safeOpenModal('plans')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n        >\n          <span class=\"ph-fill text-xl ph-crown text-brand-400\"></span>\n          <div class=\"text-theme-300 text-xs\">\n            {{ t('plans', 'Plans') }}\n          </div>\n        </button>\n      </div>\n\n      <!-- Beta Section (moved after plans) -->\n      <div>\n        <button\n          v-if=\"isAdmin || isBeta\"\n          @click=\"safeOpenModal('EarlyAccessOverview')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-amber-400\"\n        >\n          <span class=\"ph-fill text-xl ph-flask\"></span>\n          <div class=\"text-theme-300 text-xs\">{{ $root.translations.sidebar_beta }}</div>\n        </button>\n      </div>\n\n      <!-- Admin Section (moved after beta) -->\n      <div v-if=\"isAdmin\">\n        <button\n          @click=\"safeOpenModal('UserSearchModal')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n        >\n          <span class=\"ph-fill text-xl ph-magnifying-glass\"></span>\n          <div class=\"text-theme-300 text-xs\">{{ $root.translations.sidebar_users }}</div>\n        </button>\n\n\n      </div>\n\n      <hr class=\"border-theme-900\" />\n\n      <!-- Help Section -->\n      <div>\n        <button\n          :class=\"{ 'bg-theme-900/50': sectionOpen.help }\"\n          @click=\"toggleSection('help')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n        >\n          <div class=\"relative\">\n            <span class=\"ph-fill text-xl ph-question\"></span>\n            <span\n              class=\"ph-fill text-xs ph-caret-down absolute -top-1 left-1 text-theme-500 transition-transform duration-200\"\n              :class=\"{ 'rotate-180': sectionOpen.help }\"\n            ></span>\n          </div>\n          <div class=\"text-theme-300 text-xs\">\n            {{ t('help', 'Help') }}\n          </div>\n        </button>\n        <transition name=\"sidebar-collapse\">\n          <div v-if=\"sectionOpen.help\" class=\"flex flex-col\">\n            <button\n              :class=\"{\n                'bg-theme-900/50': $route.path.includes('documentation'),\n              }\"\n              @click=\"\n                !$route.path.includes('documentation')\n                  ? $router.push('/documentation')\n                  : null\n              \"\n              class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n            >\n              <span class=\"ph-fill text-xl ph-book\"></span>\n              <div class=\"text-theme-300 text-xs\">\n                {{ t('docs', 'Docs') }}\n              </div>\n            </button>\n\n            <button\n              :class=\"{ 'bg-theme-900/50': $route.path.includes('blog') }\"\n              @click=\"\n                !$route.path.includes('blog')\n                  ? $router.push('/blog')\n                  : null\n              \"\n              class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n            >\n              <span class=\"ph-fill text-xl ph-pen-nib\"></span>\n              <div class=\"text-theme-300 text-xs\">\n                {{ t('blog', 'Blog') }}\n              </div>\n            </button>\n\n            <button\n              @click=\"safeOpenModal('SiteRatingModal')\"\n              class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n            >\n              <span class=\"ph-fill text-xl ph-star\"></span>\n              <div class=\"text-theme-300 text-xs\">{{ $root.translations.sidebar_rate }}</div>\n            </button>\n\n            <button\n              :class=\"{ 'bg-theme-900/50': $route.path.includes('legal') }\"\n              @click=\"\n                !$route.path.includes('legal') ? $router.push('/legal') : null\n              \"\n              class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n            >\n              <span class=\"ph-fill text-xl ph-lock\"></span>\n              <div class=\"text-theme-300 text-xs\">\n                {{ t('legal', 'Legal') }}\n              </div>\n            </button>\n            \n            <button\n              :class=\"{ 'bg-theme-900/50': $route.path.includes('privacy') }\"\n              @click=\"\n                !$route.path.includes('privacy') ? $router.push('/privacy') : null\n              \"\n              class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n            >\n              <span class=\"ph-fill text-xl ph-shield-checkered\"></span>\n              <div class=\"text-theme-300 text-xs\">\n                {{ t('privacy', 'Privacy') }}\n              </div>\n            </button>\n\n            <button\n              :class=\"{ 'bg-theme-900/50': $route.path.includes('contact') }\"\n              @click=\"\n                !$route.path.includes('contact') ? $router.push('/contact') : null\n              \"\n              class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n            >\n              <span class=\"ph-fill text-xl ph-envelope\"></span>\n              <div class=\"text-theme-300 text-xs\">\n                {{ t('contact', 'Contact') }}\n              </div>\n            </button>\n          </div>\n        </transition>\n      </div>\n\n      <hr class=\"border-theme-900\" />\n\n      <!-- Settings and External Links -->\n      <div class=\"flex flex-col gap-2\">\n        <button\n          v-if=\"installAvailable\"\n          @click=\"installApp\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-brand-500/20 rounded-md border border-brand-500/30 text-brand-400\"\n        >\n          <span class=\"ph-fill text-xl ph-download-simple\"></span>\n          <div class=\"text-theme-300 text-xs\">\n            {{ t('install', 'Install') }}\n          </div>\n        </button>\n        <button\n          @click=\"user ? safeOpenModal('settings') : safeOpenModal('login')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n        >\n          <span class=\"ph-fill text-xl ph-gear\"></span>\n          <div class=\"text-theme-300 text-xs\">\n            {{ t('config', 'Settings') }}\n          </div>\n        </button>\n        <button\n          onclick=\"window.open('https://discord.gg/W4mSNKSSdR', '_blank')\"\n          class=\"min-w-12 h-12 transition-all duration-200 select-none active:scale-95 hover:bg-theme-900/50 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n        >\n          <span class=\"ph-fill text-xl ph-discord-logo\"></span>\n          <div class=\"text-theme-300 text-xs\">\n            {{ t('discord', 'Discord') }}\n          </div>\n        </button>\n      </div>\n    </div>\n\n    <!-- Mobile Navigation Bar -->\n    <div\n      :class=\"$route.path.includes('chat/') ? 'hidden' : 'flex'\"\n      class=\"md:hidden items-center justify-between p-2 border-t border-theme-900 bg-theme-950 z-[60]\"\n    >\n      <!-- Home/Logo Button (moved to first position) -->\n      <button\n        @click=\"!$route.path.includes('home') ? $router.push('/home') : null\"\n        :class=\"{ 'bg-theme-900/50': $route.path.includes('home') }\"\n        class=\"flex-1 flex flex-col items-center justify-center p-2 min-h-[44px] transition-all duration-200 select-none active:scale-95 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n      >\n        <span class=\"ph-fill text-xl ph-house\"></span>\n        <div class=\"text-theme-300 text-xs\">{{ $root.translations.home }}</div>\n      </button>\n\n      <!-- Chat Button (moved to second position) -->\n      <button\n        :class=\"{ 'bg-theme-900/50': $route.path.includes('chat') }\"\n        @click=\"handleAuthClick('chat')\"\n        class=\"flex-1 flex flex-col items-center justify-center p-2 min-h-[44px] transition-all duration-200 select-none active:scale-95 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n      >\n        <span class=\"ph-fill text-xl ph-chat-circle\"></span>\n        <div class=\"text-theme-300 text-xs\">{{ t('chat', 'Chat') }}</div>\n      </button>\n\n      <!-- Crew Button (moved to third position) -->\n      <button\n        @click=\"user ? showMobilePopup('crew') : safeOpenModal('login')\"\n        :class=\"{ 'bg-theme-900/50': activeMobileSection === 'crew' }\"\n        class=\"flex-1 flex flex-col items-center justify-center p-2 min-h-[44px] transition-all duration-200 select-none active:scale-95 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n      >\n        <span class=\"ph-fill text-xl ph-users-three\"></span>\n        <div class=\"text-theme-300 text-xs\">{{ t('bots', 'Bots') }}</div>\n      </button>\n\n      <!-- Studio Button (moved to fourth position) -->\n      <button\n        @click=\"user ? (!$route.path.includes('studio') ? $router.push('/studio') : null) : safeOpenModal('login')\"\n        :class=\"{ 'bg-theme-900/50': $route.path.includes('studio') }\"\n        class=\"flex-1 flex flex-col items-center justify-center p-2 min-h-[44px] transition-all duration-200 select-none active:scale-95 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n      >\n        <span class=\"ph-fill text-xl ph-camera\"></span>\n        <div class=\"text-theme-300 text-xs\">{{ $root.translations.sidebar_studio }}</div>\n      </button>\n\n      <!-- More Button (moved to last position) -->\n      <button\n        @click=\"showMobilePopup('more')\"\n        :class=\"{ 'bg-theme-900/50': activeMobileSection === 'more' }\"\n        class=\"flex-1 flex flex-col items-center justify-center p-2 min-h-[44px] transition-all duration-200 select-none active:scale-95 rounded-md border border-transparent hover:border-theme-800 text-theme-300\"\n      >\n        <span class=\"ph-fill text-xl ph-dots-three-outline\"></span>\n        <div class=\"text-theme-300 text-xs\">{{ $root.translations.sidebar_more }}</div>\n      </button>\n    </div>\n\n    <!-- Mobile Popup Overlay -->\n    <transition name=\"sidebar-fade\">\n      <div\n        v-if=\"showMobileMenu && activeMobileSection\"\n        @click=\"closeMobilePopup\"\n        class=\"fixed inset-0 bg-black/50 z-50 md:hidden\"\n      >\n        <!-- Popup Content -->\n        <transition name=\"sidebar-slide-up\">\n          <div\n            v-if=\"showMobileMenu && activeMobileSection\"\n            @click.stop\n            class=\"absolute bottom-16 left-0 right-0 bg-theme-950 border-t border-theme-900 p-4 rounded-t-lg max-h-[70vh] overflow-y-auto\"\n          >\n        <div class=\"flex justify-between items-center mb-3\">\n          <h3 class=\"text-sm font-semibold text-theme-200\">\n            {{\n              activeMobileSection === \"crew\"\n                ? t('bots', 'Bots')\n                : $root.translations.sidebar_more_options\n            }}\n          </h3>\n          <button\n            @click=\"closeMobilePopup\"\n            class=\"p-1.5 rounded-md text-theme-400 hover:text-theme-200 transition-colors hover:bg-theme-800/50\"\n          >\n            <span class=\"ph text-xl ph-x\"></span>\n          </button>\n        </div>\n\n        <!-- Crew Section Content -->\n        <div\n          v-if=\"activeMobileSection === 'crew'\"\n          class=\"grid grid-cols-3 gap-y-2 gap-x-0.5\"\n        >\n          <button\n            @click=\"user ? safeOpenModal('create', {}, true, true) : safeOpenModal('login')\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <span class=\"ph-fill text-xl ph-magic-wand mb-1\"></span>\n            <div class=\"text-theme-300 text-xs text-center\">\n              {{ t('create_bot_sidebar', 'Create') }}\n            </div>\n          </button>\n          <button\n            @click=\"user ? navigateAndClose('/characters') : safeOpenModal('login')\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <span class=\"ph-fill text-xl ph-users-three mb-1\"></span>\n            <div class=\"text-theme-300 text-xs text-center\">\n              {{ t('crew', 'Crew') }}\n            </div>\n          </button>\n          <!-- Mobile Lorebook Button -->\n          <button\n            @click=\"openModalAndClose('LorebookModal')\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <span class=\"ph-fill text-xl ph-book-open-text mb-1\"></span>\n            <div class=\"text-theme-300 text-xs text-center sidebar-label\">\n              <span class=\"sidebar-label-text\">{{ t('lorebooks', 'Lore') }}</span>\n            </div>\n          </button>\n\n        </div>\n\n        <!-- More Options Content -->\n        <div\n          v-if=\"activeMobileSection === 'more'\"\n          class=\"grid grid-cols-3 gap-y-2 gap-x-0.5\"\n        >\n          <button\n            @click=\"user ? safeOpenModal('settings') : safeOpenModal('login')\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <span class=\"ph-fill text-xl ph-gear mb-1\"></span>\n            <div class=\"text-theme-300 text-xs text-center\">\n              {{ t('config', 'Settings') }}\n            </div>\n          </button>\n          <button\n            @click=\"navigateAndClose('/store')\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <span class=\"ph-fill text-xl ph-storefront mb-1\"></span>\n            <div class=\"text-theme-300 text-xs text-center\">{{ $root.translations.store }}</div>\n          </button>\n          <button\n            @click=\"user ? openModalAndClose('AchievementsModal', { initialTab: 'achievements', initialCategory: 'store' }) : openModalAndClose('login')\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <span class=\"ph-fill text-xl ph-trophy mb-1\"></span>\n            <div class=\"text-theme-300 text-xs text-center\">{{ $root.translations.sidebar_achievements }}</div>\n          </button>\n          <!-- Admin Section -->\n\n            <button\n             v-if=\"isAdmin\"\n              @click=\"safeOpenModal('UserSearchModal')\"\n              class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n            >\n              <span class=\"ph-fill text-xl ph-magnifying-glass mb-1\"></span>\n              <div class=\"text-theme-300 text-xs text-center\">{{ $root.translations.sidebar_users }}</div>\n            </button>\n\n          <button\n            @click=\"safeOpenModal('SiteRatingModal')\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <span class=\"ph-fill text-xl ph-star mb-1\"></span>\n            <div class=\"text-theme-300 text-xs text-center\">{{ $root.translations.sidebar_rate }}</div>\n          </button>\n\n          <button\n            v-if=\"user && (planIsZero || isAdmin)\"\n            @click=\"safeOpenModal('plans')\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <span\n              class=\"ph-fill text-xl ph-crown mb-1 bg-gradient-to-r from-brand-400 via-brand-500 to-brand-600 inline-block text-transparent bg-clip-text\"\n            ></span>\n            <div class=\"text-theme-300 text-xs text-center\">\n              {{ t('plans', 'Plans') }}\n            </div>\n          </button>\n\n          <button\n            v-if=\"isBeta || isAdmin\"\n            @click=\"safeOpenModal('EarlyAccessOverview')\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <span class=\"ph-fill text-xl ph-flask mb-1 text-amber-400\"></span>\n            <div class=\"text-theme-300 text-xs text-center\">{{ $root.translations.sidebar_beta }}</div>\n          </button>\n\n          <button\n            @click=\"toggleMobileSection('help')\"\n            :class=\"{ 'bg-theme-900/50': mobileSectionOpen.help }\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <div class=\"relative mb-1\">\n              <span class=\"ph-fill text-xl ph-question\"></span>\n              <span\n                class=\"ph-fill text-xs ph-caret-down absolute -top-1 left-1 text-theme-500 transition-transform duration-200\"\n                :class=\"{ 'rotate-180': mobileSectionOpen.help }\"\n              ></span>\n            </div>\n            <div class=\"text-theme-300 text-xs text-center\">\n              {{ t('help', 'Help') }}\n            </div>\n          </button>\n<button\n            v-if=\"isAdmin\"\n            @click=\"safeOpenModal('AdminChangelogModal')\"\n            class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n          >\n            <span class=\"ph-fill text-xl ph-users mb-1\"></span>\n            <div class=\"text-theme-300 text-xs text-center\">{{ $root.translations.sidebar_change }}</div>\n          </button>\n          <button\n             onclick=\"window.open('https://discord.gg/W4mSNKSSdR', '_blank')\"\n             class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n           >\n             <span class=\"ph-fill text-xl ph-discord-logo mb-1\"></span>\n             <div class=\"text-theme-300 text-xs text-center\">\n               {{ t('discord', 'Discord') }}\n             </div>\n           </button>\n\n           <!-- Install App (PWA) button - only shown when install is available -->\n           <button\n             v-if=\"installAvailable\"\n             @click=\"installApp\"\n             class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-brand-400\"\n           >\n             <span class=\"ph-fill text-xl ph-download-simple mb-1\"></span>\n<div class=\"text-brand-400 text-xs text-center font-semibold\">{{ $root.translations.sidebar_install_app }}</div>\n           </button>\n\n         </div>\n\n         <!-- Help Expandable Section -->\n        <transition name=\"sidebar-collapse\">\n          <div\n            v-if=\"activeMobileSection === 'more' && mobileSectionOpen.help\"\n            class=\"mt-3 grid grid-cols-3 gap-3 border-t border-theme-900 pt-3\"\n          >\n            <button\n              @click=\"navigateAndClose('/documentation')\"\n              class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n            >\n              <span class=\"ph-fill text-xl ph-book mb-1\"></span>\n              <div class=\"text-theme-300 text-xs text-center\">\n                {{ t('docs', 'Docs') }}\n              </div>\n            </button>\n            <button\n              @click=\"navigateAndClose('/legal')\"\n              class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n            >\n              <span class=\"ph-fill text-xl ph-lock mb-1\"></span>\n              <div class=\"text-theme-300 text-xs text-center\">\n                {{ t('legal', 'Legal') }}\n              </div>\n            </button>\n            <button\n              @click=\"navigateAndClose('/privacy')\"\n              class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n            >\n              <span class=\"ph-fill text-xl ph-shield-checkered mb-1\"></span>\n              <div class=\"text-theme-300 text-xs text-center\">\n                {{ t('privacy', 'Privacy') }}\n              </div>\n            </button>\n            <button\n              @click=\"navigateAndClose('/blog')\"\n              class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n            >\n              <span class=\"ph-fill text-xl ph-pen-nib mb-1\"></span>\n              <div class=\"text-theme-300 text-xs text-center\">\n                {{ t('blog', 'Blog') }}\n              </div>\n            </button>\n            <button\n              @click=\"navigateAndClose('/contact')\"\n              class=\"flex flex-col items-center p-1.5 min-h-[40px] gap-0.5 transition-all duration-200 select-none active:scale-95 text-theme-300 hover:text-theme-100\"\n            >\n              <span class=\"ph-fill text-xl ph-envelope mb-1\"></span>\n              <div class=\"text-theme-300 text-xs text-center\">\n                {{ t('contact', 'Contact') }}\n              </div>\n            </button>\n          </div>\n        </transition>\n      </div>\n      </transition>\n    </div>\n    </transition>\n  </div>\n</template>\n\n<script>\nexport default {\n  data() {\n    return {\n      sectionOpen: {\n        plans: false,\n        chat: false,\n        create: false,\n        help: false,\n        crew: false,\n        dashboard: false,\n        legal: false,\n        settings: false,\n      },\n      showMobileMenu: false,\n      activeMobileSection: null,\n      mobileSectionOpen: {\n        help: false,\n      },\n    };\n  },\n  computed: {\n    // Safe computed property for user - handles cache/initialization issues\n    user() {\n      try {\n        return this.$root?.user || null;\n      } catch (e) {\n        return null;\n      }\n    },\n    // Safe computed property for checking if user is admin\n    isAdmin() {\n      try {\n        return this.user?.role === 'admin';\n      } catch (e) {\n        return false;\n      }\n    },\n    // Safe computed property for checking if user is beta\n    isBeta() {\n      try {\n        return this.user?.role === 'beta';\n      } catch (e) {\n        return false;\n      }\n    },\n    // Safe computed property for checking if plan is 0 (free)\n    planIsZero() {\n      try {\n        if (this.$root && typeof this.$root.get_plan === 'function') {\n          return this.$root.get_plan() === 0;\n        }\n        return false;\n      } catch (e) {\n        return false;\n      }\n    },\n    // PWA install availability - checks global window.isPwaInstallable\n    installAvailable() {\n      try {\n        return typeof window.isPwaInstallable === 'function' && window.isPwaInstallable();\n      } catch (e) {\n        return false;\n      }\n    },\n  },\n  mounted() {\n    // Listen for install availability changes\n    window.addEventListener('pwa-install-ready', this._onInstallReady);\n    window.addEventListener('appinstalled', this._onInstalled);\n    window.addEventListener('pwa-installed', this._onInstalled);\n  },\n  beforeUnmount() {\n    window.removeEventListener('pwa-install-ready', this._onInstallReady);\n    window.removeEventListener('appinstalled', this._onInstalled);\n    window.removeEventListener('pwa-installed', this._onInstalled);\n  },\n  methods: {\n    // Safe translation accessor with fallback\n    t(key, fallback = '') {\n      try {\n        if (this.$root?.translations && this.$root.translations[key]) {\n          return this.$root.translations[key];\n        }\n        return fallback || key;\n      } catch (e) {\n        return fallback || key;\n      }\n    },\n    // Safe openModal wrapper\n    safeOpenModal(modalName, data = null, arg1 = null, arg2 = null) {\n      try {\n        if (this.$root && typeof this.$root.openModal === 'function') {\n          if (arg1 !== null || arg2 !== null) {\n            this.$root.openModal(modalName, data, arg1, arg2);\n          } else {\n            this.$root.openModal(modalName, data);\n          }\n        }\n      } catch (e) {\n        console.warn('openModal failed:', e);\n      }\n    },\n    // Handle auth-required click actions\n    handleAuthClick(action) {\n      try {\n        if (this.user) {\n          switch (action) {\n            case 'chat':\n              if (!this.$route.path.includes('chat')) {\n                this.$router.push('/chat');\n              }\n              break;\n            case 'crew':\n              this.toggleSection('crew');\n              break;\n            case 'dashboard':\n              if (!this.$route.path.includes('dashboard')) {\n                this.$router.push('/dashboard');\n              }\n              break;\n          }\n        } else {\n          this.safeOpenModal('login');\n        }\n      } catch (e) {\n        console.warn('handleAuthClick failed:', e);\n      }\n    },\n    toggleSection(section) {\n      this.sectionOpen[section] = !this.sectionOpen[section];\n    },\n    showMobilePopup(section) {\n      this.activeMobileSection = section;\n      this.showMobileMenu = true;\n    },\n    closeMobilePopup() {\n      this.showMobileMenu = false;\n      setTimeout(() => {\n        this.activeMobileSection = null;\n      }, 300);\n    },\n    toggleMobileSection(section) {\n      this.mobileSectionOpen[section] = !this.mobileSectionOpen[section];\n    },\n    navigateAndClose(path) {\n      if (!this.$route.path.includes(path.substring(1))) {\n        this.$router.push(path);\n      }\n      this.closeMobilePopup();\n    },\n    openModalAndClose(modalName, data = null) {\n      this.safeOpenModal(modalName, data);\n      this.closeMobilePopup();\n    },\n    isModalOpen(modalName) {\n      try {\n        return Array.isArray(this.$root?.activeModals)\n          ? this.$root.activeModals.some((modal) => modal.modalName === modalName)\n          : false;\n      } catch (e) {\n        return false;\n      }\n    },\n    // PWA Install helper\n    installApp() {\n      if (typeof window.triggerPwaInstall === 'function') {\n        window.triggerPwaInstall().then(function(accepted) {\n          if (accepted && typeof window.lightHaptic === 'function') {\n            window.successHaptic();\n          }\n        });\n      }\n    },\n    // Called when install becomes available\n    _onInstallReady() {\n      this.$forceUpdate();\n    },\n    // Called when app is installed\n    _onInstalled() {\n      this.$forceUpdate();\n    },\n  },\n};\n</script>\n\n<style scoped>\n/* Simple expand/collapse animation for sidebar sections */\n.sidebar-collapse-enter-active,\n.sidebar-collapse-leave-active {\n  overflow: hidden;\n  transition: max-height 0.2s ease, opacity 0.2s ease;\n}\n\n/* Mobile popup overlay fade */\n.sidebar-fade-enter-active,\n.sidebar-fade-leave-active {\n  transition: opacity 0.2s ease;\n}\n.sidebar-fade-enter-from,\n.sidebar-fade-leave-to {\n  opacity: 0;\n}\n\n/* Mobile popup content slide-up */\n.sidebar-slide-up-enter-active,\n.sidebar-slide-up-leave-active {\n  transition: transform 0.25s ease, opacity 0.25s ease;\n}\n.sidebar-slide-up-enter-from,\n.sidebar-slide-up-leave-to {\n  transform: translateY(20px);\n  opacity: 0;\n}\n\n.sidebar-collapse-enter-from,\n.sidebar-collapse-leave-to {\n  max-height: 0;\n  opacity: 0;\n}\n\n.sidebar-collapse-enter-to,\n.sidebar-collapse-leave-from {\n  max-height: 1000px;\n  opacity: 1;\n}\n\n/* Train-display marquee for overflowing sidebar labels */\n.sidebar-label {\n  overflow: hidden;\n  max-width: 100%;\n  white-space: nowrap;\n}\n\n.sidebar-label-text {\n  display: inline-block;\n  animation: train-scroll 4s ease-in-out infinite;\n}\n\n.sidebar-label:not(:hover) .sidebar-label-text {\n  animation-play-state: running;\n}\n\n@keyframes train-scroll {\n  0%, 25% {\n    transform: translateX(0);\n  }\n  50%, 75% {\n    transform: translateX(min(0px, calc(-100% + 48px)));\n  }\n  100% {\n    transform: translateX(0);\n  }\n}\n\n/* Only animate when text actually overflows */\n.sidebar-label-text:not(.overflows) {\n  animation: none;\n}\n</style>","/components/modules/Alert.vue":"<template>\n    <div class=\"pointer-events-none fixed top-4 left-1/2 z-[9999] w-full max-w-md -translate-x-1/2 px-4\">\n        <transition-group name=\"alert-fade\" tag=\"div\"\n            class=\"pointer-events-none flex w-full flex-col items-stretch gap-2\"\n            :class=\"alerts.length > 3 ? 'max-h-[80vh] overflow-y-auto' : ''\"\n            aria-live=\"polite\" role=\"status\">\n            <div v-for=\"(alert, index) in alerts\" :key=\"alert.id\"\n                class=\"pointer-events-auto relative flex items-start gap-3 rounded-lg bg-theme-950/95 p-3.5 pr-2 shadow-lg backdrop-blur-sm\"\n                :class=\"meta(alert.type).border\">\n                <i v-if=\"meta(alert.type).icon\" class=\"ph mt-0.5 flex-shrink-0\" :class=\"[meta(alert.type).icon, meta(alert.type).iconColor]\"></i>\n\n                <div class=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n                    <strong v-if=\"alert.title\" class=\"text-sm font-semibold\" :class=\"meta(alert.type).title\">{{ alert.title }}</strong>\n                    <p v-if=\"alert.message\" class=\"break-words text-sm leading-5\" :class=\"meta(alert.type).body\">{{ alert.message }}</p>\n                </div>\n\n                <button @click=\"dismiss(alert)\" aria-label=\"Dismiss\"\n                    class=\"flex-shrink-0 rounded-md p-1 text-theme-400 transition-colors hover:bg-theme-800/50 hover:text-theme-200\">\n                    <span class=\"ph ph-x text-lg\"></span>\n                </button>\n\n                <div class=\"progress-bar absolute bottom-0 left-0 h-0.5 origin-left rounded-full\"\n                    :class=\"meta(alert.type).bar\"\n                    :style=\"{ animationDuration: (alert.ttl || 5000) + 'ms' }\"></div>\n            </div>\n        </transition-group>\n    </div>\n</template>\n\n<script>\nexport default {\n    name: 'alert',\n    computed: {\n        alerts() {\n            return this.$root.alerts || [];\n        },\n    },\n    methods: {\n        meta(type) {\n            const map = {\n                error: {\n                    border: 'border border-rose-500/40',\n                    icon: 'ph-warning-circle',\n                    iconColor: 'text-rose-400',\n                    title: 'text-rose-300',\n                    body: 'text-rose-200/80',\n                    bar: 'bg-rose-500',\n                },\n                success: {\n                    border: 'border border-green-500/40',\n                    icon: 'ph-check-circle',\n                    iconColor: 'text-green-400',\n                    title: 'text-green-300',\n                    body: 'text-green-200/80',\n                    bar: 'bg-green-500',\n                },\n                warning: {\n                    border: 'border border-amber-500/40',\n                    icon: 'ph-warning',\n                    iconColor: 'text-amber-400',\n                    title: 'text-amber-300',\n                    body: 'text-amber-200/80',\n                    bar: 'bg-amber-500',\n                },\n                info: {\n                    border: 'border border-brand-500/40',\n                    icon: 'ph-info',\n                    iconColor: 'text-brand-400',\n                    title: 'text-brand-300',\n                    body: 'text-theme-300',\n                    bar: 'bg-brand-400',\n                },\n            };\n            return map[type] || {\n                border: 'border border-theme-800',\n                icon: 'ph-info',\n                iconColor: 'text-theme-400',\n                title: 'text-theme-200',\n                body: 'text-theme-300',\n                bar: 'bg-theme-600',\n            };\n        },\n        dismiss(alert) {\n            const index = this.alerts.indexOf(alert);\n            if (index !== -1) {\n                if (alert.timeoutId) clearTimeout(alert.timeoutId);\n                this.alerts.splice(index, 1);\n            }\n        },\n    },\n};\n</script>\n\n<style>\n/* Stacking + enter/leave/move transitions */\n.alert-fade-enter-active,\n.alert-fade-leave-active {\n    transition: opacity 0.25s ease, transform 0.25s ease, margin 0.25s ease;\n}\n\n.alert-fade-enter-from,\n.alert-fade-leave-to {\n    opacity: 0;\n    transform: translateY(-12px) scale(0.98);\n}\n\n.alert-fade-leave-active {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n}\n\n.alert-fade-move {\n    transition: transform 0.25s ease;\n}\n\n/* Auto-dismiss progress */\n.progress-bar {\n    animation-name: progress;\n    animation-timing-function: linear;\n    animation-fill-mode: forwards;\n}\n\n@keyframes progress {\n    0% {\n        transform: scaleX(1);\n        opacity: 1;\n    }\n\n    85% {\n        opacity: 1;\n    }\n\n    100% {\n        transform: scaleX(0);\n        opacity: 0;\n    }\n}\n</style>\n","/components/modals/AgeGate/main.vue":"<template>\n  <div\n    class=\"flex flex-col relative w-full text-theme-200 sm:h-auto max-h-full sm:max-w-lg bg-theme-950 border border-theme-900 rounded-xl overflow-hidden shadow-xl\"\n  >\n\n    <!-- Content -->\n    <div class=\"relative z-10 flex flex-col\">\n      <!-- Header -->\n      <div class=\"p-6 sm:p-8 pb-3 text-center\">\n        <img\n          :src=\"$root.serveImg('/media/logo/transparent.png')\"\n          class=\"mx-auto w-12 h-12 mb-3 object-contain\"\n          alt=\"MiocAI\"\n        />\n        <h1 class=\"text-2xl sm:text-3xl font-bold text-theme-100 mb-1\">\n          Welcome to MiocAI\n        </h1>\n        <p class=\"text-theme-400 text-sm max-w-xs mx-auto leading-relaxed\">\n          Chat with AI characters, build your own, generate images. An open sandbox powered by AI models.\n        </p>\n      </div>\n\n      <!-- Body — single compact block -->\n      <div class=\"px-6 sm:px-8 pb-4\">\n        <div class=\"bg-theme-940 border border-theme-900 rounded-lg p-4 space-y-3\">\n          <div class=\"flex items-start gap-3\">\n            <span class=\"ph ph-shield-check text-brand-300 text-base mt-0.5 flex-shrink-0\"></span>\n            <p class=\"text-sm text-theme-400 leading-relaxed\">\n              You need to be <strong class=\"text-theme-200\">18 or older</strong> to use MiocAI. By continuing, you're confirming you meet that requirement.\n            </p>\n          </div>\n          <div class=\"flex items-start gap-3\">\n            <span class=\"ph ph-lock text-brand-300 text-base mt-0.5 flex-shrink-0\"></span>\n            <p class=\"text-sm text-theme-400 leading-relaxed\">\n              Everything here is private and encrypted. Your conversations stay yours, your data stays safe.\n            </p>\n          </div>\n          <div class=\"flex items-start gap-3\">\n            <span class=\"ph ph-file-text text-brand-300 text-base mt-0.5 flex-shrink-0\"></span>\n            <p class=\"text-sm text-theme-400 leading-relaxed\">\n              By using MiocAI, you agree to our\n              <a\n                @click.stop=\"openTerms\"\n                class=\"text-brand-300 hover:text-brand-200 transition-colors cursor-pointer underline underline-offset-2\"\n              >Terms of Service</a>\n              and\n              <a\n                @click.stop=\"openPrivacy\"\n                class=\"text-brand-300 hover:text-brand-200 transition-colors cursor-pointer underline underline-offset-2\"\n              >Privacy Policy</a>.\n            </p>\n          </div>\n        </div>\n      </div>\n\n      <!-- Footer -->\n      <div class=\"px-6 sm:px-8 pb-6 sm:pb-8 pt-3\">\n        <div class=\"flex flex-col sm:flex-row gap-3\">\n          <button\n            @click=\"decline\"\n            class=\"flex-1 px-4 py-2.5 rounded-md font-semibold transition-all duration-200 select-none border-t-2 border-b-2 border-t-theme-900 border-b-theme-940 bg-gradient-to-b from-theme-920 to-theme-940 text-theme-300 hover:text-theme-100 active:scale-95 text-sm\"\n          >\n            Leave Site\n          </button>\n          <button\n            @click=\"confirm\"\n            class=\"flex-1 px-4 py-2.5 rounded-md font-semibold transition-all duration-200 select-none border-t-2 border-b-2 border-t-brand-300 border-b-brand-700 bg-gradient-to-b from-brand-400 to-brand-500 text-brand-950 active:scale-95 text-sm\"\n          >\n            I'm 18+\n          </button>\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script>\nexport default {\n  name: \"AgeGate\",\n  methods: {\n    confirm() {\n      try {\n        localStorage.setItem(\"miocai_age_gate_confirmed\", \"true\");\n      } catch (e) {\n        // localStorage unavailable — proceed anyway\n      }\n      this.$root.closeModal(\"AgeGate\");\n    },\n    decline() {\n      window.location.href = \"https://www.google.com\";\n    },\n    openTerms() {\n      this.$root.closeModal(\"AgeGate\");\n      this.$router.push(\"/legal\");\n    },\n    openPrivacy() {\n      this.$root.closeModal(\"AgeGate\");\n      this.$router.push(\"/privacy\");\n    },\n  },\n};\n</script>"}