diff --git a/websites/_site/sites/admin.headysystems.com/index.html b/websites/_site/sites/admin.headysystems.com/index.html index a0cacf4..726933e 100644 --- a/websites/_site/sites/admin.headysystems.com/index.html +++ b/websites/_site/sites/admin.headysystems.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ Overview Architecture API Reference + User Experience Ecosystem - Heady Platform → +
+
G
+
+ Guest Access + Local Storage Only +
+ +
+ Sign In → @@ -541,6 +643,7 @@

Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    +
    User Experience
    +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +
    Integration

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.admin.headysystems.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/_site/sites/heady-ai.com/index.html b/websites/_site/sites/heady-ai.com/index.html index de53703..e24bb8b 100644 --- a/websites/_site/sites/heady-ai.com/index.html +++ b/websites/_site/sites/heady-ai.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady-ai.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/_site/sites/headyconnection.com/index.html b/websites/_site/sites/headyconnection.com/index.html index 3eba4ec..9811c55 100644 --- a/websites/_site/sites/headyconnection.com/index.html +++ b/websites/_site/sites/headyconnection.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyconnection.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/_site/sites/headyconnection.org/index.html b/websites/_site/sites/headyconnection.org/index.html index 041b7af..6511c82 100644 --- a/websites/_site/sites/headyconnection.org/index.html +++ b/websites/_site/sites/headyconnection.org/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyconnection.org/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/_site/sites/headyex.com/index.html b/websites/_site/sites/headyex.com/index.html index aeb44fb..465d2bf 100644 --- a/websites/_site/sites/headyex.com/index.html +++ b/websites/_site/sites/headyex.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyex.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/_site/sites/headyfinance.com/index.html b/websites/_site/sites/headyfinance.com/index.html index 1a97afe..2e3cafd 100644 --- a/websites/_site/sites/headyfinance.com/index.html +++ b/websites/_site/sites/headyfinance.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyfinance.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/_site/sites/headyio.com/index.html b/websites/_site/sites/headyio.com/index.html index 28fc8ee..11cbaab 100644 --- a/websites/_site/sites/headyio.com/index.html +++ b/websites/_site/sites/headyio.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyio.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/_site/sites/headyme.com/index.html b/websites/_site/sites/headyme.com/index.html index 6be6f39..24100d7 100644 --- a/websites/_site/sites/headyme.com/index.html +++ b/websites/_site/sites/headyme.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyme.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/_site/sites/headyos.com/index.html b/websites/_site/sites/headyos.com/index.html index 25916e7..f59a00a 100644 --- a/websites/_site/sites/headyos.com/index.html +++ b/websites/_site/sites/headyos.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyos.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/_site/sites/headysystems.com/index.html b/websites/_site/sites/headysystems.com/index.html index c39ad4e..e154b4e 100644 --- a/websites/_site/sites/headysystems.com/index.html +++ b/websites/_site/sites/headysystems.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headysystems.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/_site/sites/headyweb.com/index.html b/websites/_site/sites/headyweb.com/index.html index c7d1cb4..76ec70e 100644 --- a/websites/_site/sites/headyweb.com/index.html +++ b/websites/_site/sites/headyweb.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyweb.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/build.js b/websites/build.js index 6321ddb..b5ab566 100644 --- a/websites/build.js +++ b/websites/build.js @@ -17,4 +17,4 @@ const { execSync } = require('child_process'); // Build each site -execSync('npx eleventy --config=eleventy-config.js', { stdio: 'inherit' }); +execSync('npx @11ty/eleventy --config=eleventy-config.js', { stdio: 'inherit' }); diff --git a/websites/generate-sites.js b/websites/generate-sites.js index de292b7..c88fcdf 100644 --- a/websites/generate-sites.js +++ b/websites/generate-sites.js @@ -148,6 +148,99 @@ const generateHtml = (site) => ` transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -526,8 +619,17 @@ const generateHtml = (site) => `OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -558,6 +660,7 @@ const generateHtml = (site) => `
  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -621,6 +724,27 @@ const topology = { }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -628,7 +752,7 @@ const topology = {

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.${site.domain}/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -735,7 +859,7 @@ const topology = { @@ -782,7 +906,61 @@ const topology = { }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + `; diff --git a/websites/package-lock.json b/websites/package-lock.json new file mode 100644 index 0000000..ef50694 --- /dev/null +++ b/websites/package-lock.json @@ -0,0 +1,1532 @@ +{ + "name": "heady-websites", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "heady-websites", + "version": "1.0.0", + "dependencies": { + "@11ty/eleventy": "^3.1.5", + "eleventy": "^2.0.0" + } + }, + "node_modules/@11ty/dependency-tree": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@11ty/dependency-tree/-/dependency-tree-4.0.2.tgz", + "integrity": "sha512-RTF6VTZHatYf7fSZBUN3RKwiUeJh5dhWV61gDPrHhQF2/gzruAkYz8yXuvGLx3w3ZBKreGrR+MfYpSVkdbdbLA==", + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.1" + } + }, + "node_modules/@11ty/dependency-tree-esm": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@11ty/dependency-tree-esm/-/dependency-tree-esm-2.0.4.tgz", + "integrity": "sha512-MYKC0Ac77ILr1HnRJalzKDlb9Z8To3kXQCltx299pUXXUFtJ1RIONtULlknknqW8cLe19DLVgmxVCtjEFm7h0A==", + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.7", + "acorn": "^8.15.0", + "dependency-graph": "^1.0.0", + "normalize-path": "^3.0.0" + } + }, + "node_modules/@11ty/eleventy": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@11ty/eleventy/-/eleventy-3.1.5.tgz", + "integrity": "sha512-hZ0g6MwZyRxCqXsPm82gIM304LraKbUz3ZmezOSjsqxttZG6cHTib3Qq8QkESJoKwnr+yX1eyfOkPC5/mEgZnQ==", + "license": "MIT", + "dependencies": { + "@11ty/dependency-tree": "^4.0.2", + "@11ty/dependency-tree-esm": "^2.0.4", + "@11ty/eleventy-dev-server": "^2.0.8", + "@11ty/eleventy-plugin-bundle": "^3.0.7", + "@11ty/eleventy-utils": "^2.0.7", + "@11ty/lodash-custom": "^4.17.21", + "@11ty/posthtml-urls": "^1.0.2", + "@11ty/recursive-copy": "^4.0.4", + "@sindresorhus/slugify": "^2.2.1", + "bcp-47-normalize": "^2.3.0", + "chokidar": "^3.6.0", + "debug": "^4.4.3", + "dependency-graph": "^1.0.0", + "entities": "^6.0.1", + "filesize": "^10.1.6", + "gray-matter": "^4.0.3", + "iso-639-1": "^3.1.5", + "js-yaml": "^4.1.1", + "kleur": "^4.1.5", + "liquidjs": "^10.25.0", + "luxon": "^3.7.2", + "markdown-it": "^14.1.1", + "minimist": "^1.2.8", + "moo": "0.5.2", + "node-retrieve-globals": "^6.0.1", + "nunjucks": "^3.2.4", + "picomatch": "^4.0.3", + "please-upgrade-node": "^3.2.0", + "posthtml": "^0.16.7", + "posthtml-match-helper": "^2.0.3", + "semver": "^7.7.4", + "slugify": "^1.6.8", + "tinyglobby": "^0.2.15" + }, + "bin": { + "eleventy": "cmd.cjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-dev-server": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-dev-server/-/eleventy-dev-server-2.0.8.tgz", + "integrity": "sha512-15oC5M1DQlCaOMUq4limKRYmWiGecDaGwryr7fTE/oM9Ix8siqMvWi+I8VjsfrGr+iViDvWcH/TVI6D12d93mA==", + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.1", + "chokidar": "^3.6.0", + "debug": "^4.4.0", + "finalhandler": "^1.3.1", + "mime": "^3.0.0", + "minimist": "^1.2.8", + "morphdom": "^2.7.4", + "please-upgrade-node": "^3.2.0", + "send": "^1.1.0", + "ssri": "^11.0.0", + "urlpattern-polyfill": "^10.0.0", + "ws": "^8.18.1" + }, + "bin": { + "eleventy-dev-server": "cmd.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-plugin-bundle": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-bundle/-/eleventy-plugin-bundle-3.0.7.tgz", + "integrity": "sha512-QK1tRFBhQdZASnYU8GMzpTdsMMFLVAkuU0gVVILqNyp09xJJZb81kAS3AFrNrwBCsgLxTdWHJ8N64+OTTsoKkA==", + "license": "MIT", + "dependencies": { + "@11ty/eleventy-utils": "^2.0.2", + "debug": "^4.4.0", + "posthtml-match-helper": "^2.0.3" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/eleventy-utils": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@11ty/eleventy-utils/-/eleventy-utils-2.0.7.tgz", + "integrity": "sha512-6QE+duqSQ0GY9rENXYb4iPR4AYGdrFpqnmi59tFp9VrleOl0QSh8VlBr2yd6dlhkdtj7904poZW5PvGr9cMiJQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/lodash-custom": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@11ty/lodash-custom/-/lodash-custom-4.17.21.tgz", + "integrity": "sha512-Mqt6im1xpb1Ykn3nbcCovWXK3ggywRJa+IXIdoz4wIIK+cvozADH63lexcuPpGS/gJ6/m2JxyyXDyupkMr5DHw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/11ty" + } + }, + "node_modules/@11ty/posthtml-urls": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@11ty/posthtml-urls/-/posthtml-urls-1.0.2.tgz", + "integrity": "sha512-0vaV3Wt0surZ+oS1VdKKe0axeeupuM+l7W/Z866WFQwF+dGg2Tc/nmhk/5l74/Y55P8KyImnLN9CdygNw2huHg==", + "license": "MIT", + "dependencies": { + "evaluate-value": "^2.0.0", + "http-equiv-refresh": "^2.0.1", + "list-to-array": "^1.1.0", + "parse-srcset": "^1.0.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@11ty/recursive-copy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@11ty/recursive-copy/-/recursive-copy-4.0.4.tgz", + "integrity": "sha512-oI7m8pa7/IAU/3lqRU9vjBbs20iKFo7x+1K9kT3aVira6scc1X9MjBdgLCHzLJeJ7iB6wydioA+kr9/qPnvmlQ==", + "license": "ISC", + "dependencies": { + "errno": "^1.0.0", + "junk": "^3.1.0", + "minimatch": "^3.1.5", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sindresorhus/slugify": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/slugify/-/slugify-2.2.1.tgz", + "integrity": "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==", + "license": "MIT", + "dependencies": { + "@sindresorhus/transliterate": "^1.0.0", + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@sindresorhus/transliterate": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/transliterate/-/transliterate-1.6.0.tgz", + "integrity": "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/bcp-47": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", + "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-normalize": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-2.3.0.tgz", + "integrity": "sha512-8I/wfzqQvttUFz7HVJgIZ7+dj3vUaIyIxYXaTRP1YWoSDfzt6TUmxaKZeuXR62qBmYr+nvuWINFRl6pZ5DlN4Q==", + "license": "MIT", + "dependencies": { + "bcp-47": "^2.0.0", + "bcp-47-match": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dependency-graph": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-1.0.0.tgz", + "integrity": "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/eleventy": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/eleventy/-/eleventy-2.0.1.tgz", + "integrity": "sha512-Zsh2rCvXxxjIDj9s93YhhfqmIzhUpv4VQgS7QxFB51btWO/09xdm7/Da/KmDpunTQ8wWsvW2Jo8a6gDcCc+6VA==", + "license": "MIT", + "bin": { + "eleventy": "cmd.js" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/errno": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/errno/-/errno-1.0.0.tgz", + "integrity": "sha512-3zV5mFS1E8/1bPxt/B0xxzI1snsg3uSCIh6Zo1qKg6iMw93hzPANk9oBFzSFBFrwuVoQuE3rLoouAUfwOAj1wQ==", + "license": "MIT", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esm-import-transformer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/esm-import-transformer/-/esm-import-transformer-3.0.5.tgz", + "integrity": "sha512-1GKLvfuMnnpI75l8c6sHoz0L3Z872xL5akGuBudgqTDPv4Vy6f2Ec7jEMKTxlqWl/3kSvNbHELeimJtnqgYniw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.15.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/evaluate-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/evaluate-value/-/evaluate-value-2.0.0.tgz", + "integrity": "sha512-VonfiuDJc0z4sOO7W0Pd130VLsXN6vmBWZlrog1mCb/o7o/Nl5Lr25+Kj/nkCCAhG+zqeeGjxhkK9oHpkgTHhQ==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filesize": { + "version": "10.1.6", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.6.tgz", + "integrity": "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 10.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-equiv-refresh": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-equiv-refresh/-/http-equiv-refresh-2.0.1.tgz", + "integrity": "sha512-XJpDL/MLkV3dKwLzHwr2dY05dYNfBNlyPu4STQ8WvKCFdc6vC5tPXuq28of663+gHVg03C+16pHHs/+FmmDjcw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-json": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", + "integrity": "sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==", + "license": "ISC" + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/iso-639-1": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/iso-639-1/-/iso-639-1-3.1.5.tgz", + "integrity": "sha512-gXkz5+KN7HrG0Q5UGqSMO2qB9AsbEeyLP54kF1YrMsIxmu+g4BdB7rflReZTSTZGpfj8wywu6pfPBCylPIzGQA==", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/liquidjs": { + "version": "10.25.0", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.0.tgz", + "integrity": "sha512-XpO7AiGULTG4xcTlwkcTI5JreFG7b6esLCLp+aUSh7YuQErJZEoUXre9u9rbdb0057pfWG4l0VursvLd5Q/eAw==", + "license": "MIT", + "dependencies": { + "commander": "^10.0.0" + }, + "bin": { + "liquid": "bin/liquid.js", + "liquidjs": "bin/liquid.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/liquidjs" + } + }, + "node_modules/list-to-array": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/list-to-array/-/list-to-array-1.1.0.tgz", + "integrity": "sha512-+dAZZ2mM+/m+vY9ezfoueVvrgnHIGi5FvgSymbIgJOFwiznWyA59mav95L+Mc6xPtL3s9gm5eNTlNtxJLbNM1g==", + "license": "MIT" + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT" + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "license": "BSD-3-Clause" + }, + "node_modules/morphdom": { + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.7.8.tgz", + "integrity": "sha512-D/fR4xgGUyVRbdMGU6Nejea1RFzYxYtyurG4Fbv2Fi/daKlWKuXGLOdXtl+3eIwL110cI2hz1ZojGICjjFLgTg==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/node-retrieve-globals": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/node-retrieve-globals/-/node-retrieve-globals-6.0.1.tgz", + "integrity": "sha512-j0DeFuZ/Wg3VlklfbxUgZF/mdHMTEiEipBb3q0SpMMbHaV3AVfoUQF8UGxh1s/yjqO0TgRZd4Pi/x2yRqoQ4Eg==", + "license": "MIT", + "dependencies": { + "acorn": "^8.14.1", + "acorn-walk": "^8.3.4", + "esm-import-transformer": "^3.0.3" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "license": "BSD-2-Clause", + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parse-srcset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", + "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==", + "license": "MIT" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "license": "MIT", + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/posthtml": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.16.7.tgz", + "integrity": "sha512-7Hc+IvlQ7hlaIfQFZnxlRl0jnpWq2qwibORBhQYIb0QbNtuicc5ZxvKkVT71HJ4Py1wSZ/3VR1r8LfkCtoCzhw==", + "license": "MIT", + "dependencies": { + "posthtml-parser": "^0.11.0", + "posthtml-render": "^3.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/posthtml-match-helper": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/posthtml-match-helper/-/posthtml-match-helper-2.0.3.tgz", + "integrity": "sha512-p9oJgTdMF2dyd7WE54QI1LvpBIkNkbSiiECKezNnDVYhGhD1AaOnAkw0Uh0y5TW+OHO8iBdSqnd8Wkpb6iUqmw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "posthtml": "^0.16.6" + } + }, + "node_modules/posthtml-parser": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.11.0.tgz", + "integrity": "sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==", + "license": "MIT", + "dependencies": { + "htmlparser2": "^7.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/posthtml-render": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-3.0.0.tgz", + "integrity": "sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==", + "license": "MIT", + "dependencies": { + "is-json": "^2.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "license": "MIT" + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "license": "MIT" + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slugify": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.8.tgz", + "integrity": "sha512-HVk9X1E0gz3mSpoi60h/saazLKXKaZThMLU3u/aNwoYn8/xQyX2MGxL0ui2eaokkD7tF+Zo+cKTHUbe1mmmGzA==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-11.0.0.tgz", + "integrity": "sha512-aZpUoMN/Jj2MqA4vMCeiKGnc/8SuSyHbGSBdgFbZxP8OJGF/lFkIuElzPxsN0q8TQQ+prw3P4EDfB3TBHHgfXw==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.1.0.tgz", + "integrity": "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==", + "license": "MIT" + }, + "node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/websites/package.json b/websites/package.json index a379e24..a2e404d 100644 --- a/websites/package.json +++ b/websites/package.json @@ -5,6 +5,7 @@ "build": "node build.js" }, "dependencies": { + "@11ty/eleventy": "^3.1.5", "eleventy": "^2.0.0" } } diff --git a/websites/sites/admin.headysystems.com/index.html b/websites/sites/admin.headysystems.com/index.html index a0cacf4..726933e 100644 --- a/websites/sites/admin.headysystems.com/index.html +++ b/websites/sites/admin.headysystems.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.admin.headysystems.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/sites/heady-ai.com/index.html b/websites/sites/heady-ai.com/index.html index de53703..e24bb8b 100644 --- a/websites/sites/heady-ai.com/index.html +++ b/websites/sites/heady-ai.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady-ai.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/sites/headyconnection.com/index.html b/websites/sites/headyconnection.com/index.html index 3eba4ec..9811c55 100644 --- a/websites/sites/headyconnection.com/index.html +++ b/websites/sites/headyconnection.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyconnection.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/sites/headyconnection.org/index.html b/websites/sites/headyconnection.org/index.html index 041b7af..6511c82 100644 --- a/websites/sites/headyconnection.org/index.html +++ b/websites/sites/headyconnection.org/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyconnection.org/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/sites/headyex.com/index.html b/websites/sites/headyex.com/index.html index aeb44fb..465d2bf 100644 --- a/websites/sites/headyex.com/index.html +++ b/websites/sites/headyex.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyex.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/sites/headyfinance.com/index.html b/websites/sites/headyfinance.com/index.html index 1a97afe..2e3cafd 100644 --- a/websites/sites/headyfinance.com/index.html +++ b/websites/sites/headyfinance.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyfinance.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/sites/headyio.com/index.html b/websites/sites/headyio.com/index.html index 28fc8ee..11cbaab 100644 --- a/websites/sites/headyio.com/index.html +++ b/websites/sites/headyio.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyio.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/sites/headyme.com/index.html b/websites/sites/headyme.com/index.html index 6be6f39..24100d7 100644 --- a/websites/sites/headyme.com/index.html +++ b/websites/sites/headyme.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyme.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/sites/headyos.com/index.html b/websites/sites/headyos.com/index.html index 25916e7..f59a00a 100644 --- a/websites/sites/headyos.com/index.html +++ b/websites/sites/headyos.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyos.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/sites/headysystems.com/index.html b/websites/sites/headysystems.com/index.html index c39ad4e..e154b4e 100644 --- a/websites/sites/headysystems.com/index.html +++ b/websites/sites/headysystems.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headysystems.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file diff --git a/websites/sites/headyweb.com/index.html b/websites/sites/headyweb.com/index.html index c7d1cb4..76ec70e 100644 --- a/websites/sites/headyweb.com/index.html +++ b/websites/sites/headyweb.com/index.html @@ -131,6 +131,99 @@ transform: translateY(-1px); } + /* ─── Auth Widget ───────────────────────────────────────── */ + .auth-widget { + display: flex; + align-items: center; + gap: 12px; + padding: 6px 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + border-radius: 20px; + font-size: 0.85rem; + color: var(--text-secondary); + transition: all 0.2s; + } + + .auth-widget:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--accent); + } + + .auth-widget.authenticated { + border-color: rgba(34, 197, 94, 0.4); + background: rgba(34, 197, 94, 0.05); + color: var(--text-primary); + } + + .auth-widget .avatar { + width: 24px; + height: 24px; + border-radius: 50%; + background: var(--accent-glow); + display: flex; + align-items: center; + justify-content: center; + font-size: 0.7rem; + color: var(--accent-bright); + border: 1px solid var(--border-accent); + } + + .auth-widget.authenticated .avatar { + background: rgba(34, 197, 94, 0.2); + color: #4ade80; + border-color: rgba(34, 197, 94, 0.4); + } + + .auth-status-text { + display: flex; + flex-direction: column; + line-height: 1.2; + } + + .auth-status-text strong { + font-weight: 600; + } + + .auth-status-text small { + font-size: 0.65rem; + color: var(--text-muted); + } + + .btn-logout { + background: transparent; + border: none; + color: var(--text-muted); + cursor: pointer; + padding: 2px; + display: none; + } + + .auth-widget.authenticated .btn-logout { + display: block; + } + + .btn-logout:hover { + color: var(--accent-6); + } + + .storage-indicator { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 0.7rem; + padding: 2px 6px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid var(--border); + } + + .storage-indicator.synced { + color: #4ade80; + border-color: rgba(34, 197, 94, 0.3); + background: rgba(34, 197, 94, 0.05); + } + .page-wrapper { position: relative; z-index: 1; @@ -509,8 +602,17 @@ OverviewArchitectureAPI Reference + User ExperienceEcosystem - Heady Platform → +
    +
    G
    +
    + Guest Access + Local Storage Only +
    + +
    + Sign In → @@ -541,6 +643,7 @@

    Core Concepts

  • Architecture
  • Data Model
  • Security
  • +
  • User Experience
  • Integration

    @@ -604,6 +707,27 @@

    System Architecture

    }; +
    + +

    Flawless User Experience & Personal Storage

    +

    We ensure that the websites have professionally scaffolded info and allow for the user UI and UX to be comprehensive and easily understood. We provide the sites with everything necessary to ensure the user experience is flawless from guest access to personal persistent storage happening optimally after auth.

    + +
    +
    +

    Guest Access

    +

    Immediate, low-friction access to explore the platform. Local data is securely kept in memory and transient browser storage until you choose to persist it.

    +
    +
    +

    Optimal Authentication

    +

    Seamlessly transition from guest to an authenticated user using our Zero Trust Firebase gateway, protecting your sessions using httpOnly cookies.

    +
    +
    +

    Personal Persistent Storage

    +

    Once authenticated, your local data seamlessly and optimally synchronizes to your personal persistent storage across the Heady ecosystem, governed by our Vector memory and Postgres replication layers.

    +
    +
    +
    +

    API Reference

    @@ -611,7 +735,7 @@

    API Reference

    Authentication

    Include your API key in the Authorization header of your requests:

    -
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.headyweb.com/v1/status
    +
    curl -H "Authorization: Bearer hdy_your_api_key" https://api.heady.io/v1/status

    Common Endpoints

    @@ -778,7 +902,7 @@

    Admin

    @@ -825,6 +949,60 @@

    Admin

    }, observerOptions); sections.forEach(section => observer.observe(section)); + + // ─── Auth & Storage Sync Logic ────────────────────────────────────── + document.addEventListener('DOMContentLoaded', () => { + const authWidget = document.getElementById('auth-widget-container'); + const authAvatar = document.getElementById('auth-avatar'); + const authUserName = document.getElementById('auth-user-name'); + const authStorageStatus = document.getElementById('auth-storage-status'); + const btnLogin = document.getElementById('btn-login-nav'); + const btnLogout = document.getElementById('btn-logout'); + + function updateUI(user) { + if (user) { + authWidget.classList.add('authenticated'); + authAvatar.textContent = user.displayName ? user.displayName.charAt(0).toUpperCase() : 'U'; + authUserName.textContent = user.displayName || user.email || 'Authenticated User'; + + // Simulate optimal transition to personal persistent storage after auth + authStorageStatus.innerHTML = '● Synced to Personal Storage'; + btnLogin.style.display = 'none'; + } else { + authWidget.classList.remove('authenticated'); + authAvatar.textContent = 'G'; + authUserName.textContent = 'Guest Access'; + authStorageStatus.textContent = 'Local Storage Only'; + btnLogin.style.display = 'block'; + } + } + + // Initialize UI from HeadyAuth if present + if (window.headyAuth) { + updateUI(window.headyAuth.user); + + window.headyAuth.listenForAuthChanges((user) => { + updateUI(user); + }); + + // Handle cross-window token relay from auth.heady.io + window.addEventListener('message', (event) => { + if (event.data && event.data.type === 'heady:auth:token') { + window.headyAuth.login(event.data.token, event.data.user); + updateUI(event.data.user); + } + }); + + btnLogout.addEventListener('click', () => { + window.headyAuth.logout(); + updateUI(null); + }); + } else { + console.warn('HeadyAuth not found - fallback to guest mode'); + updateUI(null); + } + }); + \ No newline at end of file