diff --git a/config/staging/versions.php b/config/staging/versions.php
index 56e410d..b362a82 100644
--- a/config/staging/versions.php
+++ b/config/staging/versions.php
@@ -1,4 +1,4 @@
-
-
v = htmlspecialchars($version) ?>
-
diff --git a/partials/structure/layout_start.php b/partials/structure/layout_start.php
index b6fed2e..0ec0e74 100644
--- a/partials/structure/layout_start.php
+++ b/partials/structure/layout_start.php
@@ -46,8 +46,6 @@ $sharedCss = [
.user-menu-item{display:block;width:100%;text-align:left;padding:.45rem .75rem;border-radius:.65rem;font-size:.9rem;color:#0f172a}
.user-menu-item:hover{background:#f1f5f9}
.page-shell{min-height:100vh;display:flex;flex-direction:column;}
- .app-version-fixed{position:fixed;right:12px;bottom:12px;z-index:2147483000;font-size:12px;font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#0f172a;background:rgba(248,250,252,.85);border:1px solid rgba(148,163,184,.6);border-radius:999px;padding:4px 10px;box-shadow:0 8px 20px rgba(15,23,42,.15);backdrop-filter:blur(6px);}
- @media print {.app-version-fixed{display:none}}
= $snippet . PHP_EOL ?>
diff --git a/partials/structure/matomo.php b/partials/structure/matomo.php
deleted file mode 100644
index b8fdb20..0000000
--- a/partials/structure/matomo.php
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/public/index.php b/public/index.php
index 2ad6e9d..3358906 100644
--- a/public/index.php
+++ b/public/index.php
@@ -1,84 +1,10 @@
-
-
-
-
-
- Email Template System – Admin
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Email Template System
-
-
-
-
-
-
-
-
-
+
@@ -185,8 +111,9 @@ $appApiBase = rtrim($GLOBALS['app_api_base'] ?? '', '/');
-
-
-
-
-
+ app_asset_url('/assets/js/toast.js')],
+ ['src' => app_asset_url('/assets/js/app.js'), 'module' => true],
+];
+require __DIR__ . '/../partials/structure/layout_end.php';
diff --git a/src/functions.php b/src/functions.php
deleted file mode 100644
index 99faf2c..0000000
--- a/src/functions.php
+++ /dev/null
@@ -1,320 +0,0 @@
- $src,
- 'defer' => $defer,
- 'async' => $async,
- 'type' => $type,
- 'version' => $version,
- ];
-
- if ($pos === 'header') {
- $GLOBALS['page_header_scripts'][] = $data;
- } else {
- $GLOBALS['page_footer_scripts'][] = $data;
- }
-}
-
-/**
- * CSS registrieren – MIT Cache-Buster und Priorität
- *
- * @param string $href Pfad zur CSS-Datei oder externe URL
- * @param string $pos aktuell nur 'header' relevant (aber für Symmetrie drin)
- * @param string $priority 'early' | 'normal' | 'late'
- * @param string|null $version null = nutze ASSET_VERSION (falls definiert),
- * '' = kein ?v=,
- * 'xyz'= erzwinge diese Version
- */
-function tpl_add_style(
- string $href,
- string $pos = 'header',
- string $priority = 'normal',
- ?string $version = null
-): void {
- if ($version === null && defined('ASSET_VERSION')) {
- $version = ASSET_VERSION;
- }
-
- $GLOBALS['page_styles'][] = [
- 'href' => $href,
- 'pos' => $pos,
- 'priority' => $priority,
- 'version' => $version,
- ];
-}
-
-/* -------------------------------------------------
- Template Loader
- ------------------------------------------------- */
-
-function tpl(string $file, string $type = 'structure', string $site = 'main'): void
-{
- $base = __DIR__ . '/../partials/';
-
- if (preg_match('/[^a-zA-Z0-9_\-]/', $file)) {
- echo "";
- return;
- }
- if (preg_match('/[^a-zA-Z0-9_\-]/', $type)) {
- echo "";
- return;
- }
- if (preg_match('/[^a-zA-Z0-9_\-]/', $site)) {
- echo "";
- return;
- }
-
- if ($type === 'landing') {
- $path = $base . "landing/$site/$file.php";
- } else {
- $path = $base . "structure/$file.php";
- }
-
- extract($GLOBALS, EXTR_SKIP);
-
- if (file_exists($path)) {
- include $path;
- } else {
- echo "";
- }
-}
-
-/* -------------------------------------------------
- Flash-Messages
- ------------------------------------------------- */
-
-function flash_set(string $type, string $message, ?string $context = null): void
-{
- if (session_status() !== PHP_SESSION_ACTIVE) {
- @session_start();
- }
-
- $_SESSION['flash'] = [
- 'type' => $type,
- 'message' => $message,
- 'context' => $context,
- ];
-}
-
-function flash_get(): ?array
-{
- if (session_status() !== PHP_SESSION_ACTIVE) {
- @session_start();
- }
-
- if (empty($_SESSION['flash']) || !is_array($_SESSION['flash'])) {
- return null;
- }
-
- $flash = $_SESSION['flash'];
- unset($_SESSION['flash']);
-
- $flash['type'] = $flash['type'] ?? 'info';
- $flash['message'] = $flash['message'] ?? '';
- $flash['context'] = $flash['context'] ?? null;
-
- return $flash;
-}
-
-/* -------------------------------------------------
- i18n Helper
- ------------------------------------------------- */
-
-/**
- * interner Helper für dot-notation keys
- */
-function _i18n_traverse_array(array $data, string $key)
-{
- $segments = explode('.', $key);
- $node = $data;
-
- foreach ($segments as $seg) {
- if (!is_array($node) || !array_key_exists($seg, $node)) {
- return null;
- }
- $node = $node[$seg];
- }
-
- return $node;
-}
-
-/**
- * Hauptfunktion i18n_get
- */
-function i18n_get(string $path, $default = null, array $replacements = []): string
-{
- if (!isset($GLOBALS['i18n']) || !is_array($GLOBALS['i18n'])) {
- return $default !== null ? (string)$default : '';
- }
-
- $current = $GLOBALS['i18n']['current'] ?? [];
- $fallback = $GLOBALS['i18n']['fallback'] ?? [];
-
- $value = _i18n_traverse_array($current, $path);
-
- if ($value === null && !empty($fallback)) {
- $value = _i18n_traverse_array($fallback, $path);
- }
-
- if (!is_string($value)) {
- return $default !== null ? (string)$default : '';
- }
-
- $text = $value;
-
- // built-in placeholder
- $builtIn = [
- '{year}' => date('Y'),
- '{{primary_domain}}' => function_exists('app_primary_domain') ? app_primary_domain() : '',
- '{{primary_url}}' => function_exists('app_primary_url') ? app_primary_url() : '',
- ];
-
- foreach ($builtIn as $ph => $val) {
- $text = str_replace($ph, $val, $text);
- }
-
- foreach ($replacements as $key => $val) {
- $val = (string)$val;
- $text = str_replace('{' . $key . '}', $val, $text);
- $text = str_replace('{{' . $key . '}}', $val, $text);
- }
-
- return $text;
-}
-
-/**
- * Kurzform für i18n_get
- */
-function i18n_get_fmt(string $path, $default = '', array $vars = []): string
-{
- $def = $default ?? '';
- return i18n_get($path, $def, $vars);
-}