(function(){const posthogKey = "phc\_oMfVwfGjzwkE5n7cCaDf25rTm7WaYn8rH4FnvsVq57Zb"; const posthogHost = "https://i.buildy.so"; const forceAnalytics = false; const analyticsHosts = \["buildy.so","www.buildy.so","usecharming.com","www.usecharming.com"\]; const analyticsIdCookie = "charming\_marketing\_identity\_seen"; const legacyAnalyticsIdCookie = "buildy\_marketing\_identity\_seen"; const analyticsIdCookieMaxAgeSeconds = 31536000; !function(t,e){var o,n,p,r;e.\_\_SV||(window.posthog && window.posthog.\_\_loaded)||(window.posthog=e,e.\_i=\[\],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t\[o\[0\]\],e=o\[1\]),t\[e\]=function(){t.push(\[e\].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api\_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")\[0\]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e\[a\]=\[\]:a="posthog",u.people=u.people||\[\],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init os ds Ie us vs ss ls capture calculateEventProperties register register\_once register\_for\_session unregister unregister\_for\_session ws getFeatureFlag getFeatureFlagPayload getFeatureFlagResult isFeatureEnabled reloadFeatureFlags updateFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSurveysLoaded onSessionId getSurveys getActiveMatchingSurveys renderSurvey displaySurvey cancelPendingSurvey canRenderSurvey canRenderSurveyAsync identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get\_distinct\_id getGroups get\_session\_id get\_session\_replay\_url alias set\_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException startExceptionAutocapture stopExceptionAutocapture loadToolbar get\_property getSessionProperty bs ps createPersonProfile setInternalOrTestUser ys es $s opt\_in\_capturing opt\_out\_capturing has\_opted\_in\_capturing has\_opted\_out\_capturing get\_explicit\_consent\_status is\_capturing clear\_opt\_in\_out\_capturing cs debug M gs getPageViewId captureTraceFeedback captureTraceMetric Qr".split(" "),n=0;n<o.length;n++)g(u,o\[n\]);e.\_i.push(\[i,s,a\])},e.\_\_SV=1)}(document,window.posthog||\[\]); var h = window.location.hostname; if (forceAnalytics || analyticsHosts.indexOf(h) !== -1) { const hashParams = new URLSearchParams(window.location.hash.substring(1)); const productDistinctId = hashParams.get('distinct\_id'); const productSessionId = hashParams.get('session\_id'); const productBootstrap = productDistinctId && productSessionId ? { distinctID: productDistinctId, sessionID: productSessionId } : null; let markerDistinctId = null; if (!productBootstrap) { const markerIdPattern = /^\[0-9a-f\]{8}-\[0-9a-f\]{4}-\[0-9a-f\]{4}-\[0-9a-f\]{4}-\[0-9a-f\]{12}$/i; var markerUsedLegacy = false; for (const markerName of \[analyticsIdCookie, legacyAnalyticsIdCookie\]) { const markerPrefix = markerName + '='; const markerCookie = document.cookie .split(';') .map(function (part) { return part.trim(); }) .find(function (part) { return part.startsWith(markerPrefix); }); if (!markerCookie) continue; try { const value = decodeURIComponent(markerCookie.slice(markerPrefix.length)); if (markerIdPattern.test(value)) { markerDistinctId = value; markerUsedLegacy = markerName === legacyAnalyticsIdCookie; break; } } catch {} } } const bootstrap = productBootstrap ?? (markerDistinctId ? { distinctID: markerDistinctId } : null); posthog.init(posthogKey, { api\_host: posthogHost, defaults: '2026-01-30', ...(bootstrap ? { bootstrap } : {}), loaded: function (ph) { const distinctId = ph.get\_distinct\_id(); if (typeof distinctId !== 'string') return; if (markerUsedLegacy) { ph.capture('legacy\_state\_key\_observed', { key: legacyAnalyticsIdCookie }); } try { localStorage.setItem(analyticsIdCookie, distinctId); localStorage.removeItem(legacyAnalyticsIdCookie); } catch {} document.cookie = analyticsIdCookie + '=' + encodeURIComponent(distinctId) + '; Path=/; Max-Age=' + analyticsIdCookieMaxAgeSeconds + '; SameSite=Lax' + (window.location.protocol === 'https:' ? '; Secure' : ''); document.cookie = legacyAnalyticsIdCookie + '=; Path=/; Max-Age=0; SameSite=Lax' + (window.location.protocol === 'https:' ? '; Secure' : ''); }, }); } })();(function(){const ga4Id = "G-XG5Q0M59CD"; const forceAnalytics = false; const analyticsHosts = \["buildy.so","www.buildy.so","usecharming.com","www.usecharming.com"\]; var h = window.location.hostname; if (forceAnalytics || analyticsHosts.indexOf(h) !== -1) { window.dataLayer = window.dataLayer || \[\]; function gtag() { window.dataLayer.push(arguments); } window.gtag = gtag; gtag('consent', 'default', { ad\_storage: 'denied', ad\_user\_data: 'denied', ad\_personalization: 'denied', analytics\_storage: 'granted', }); gtag('js', new Date()); gtag('config', ga4Id); var s = document.createElement('script'); s.async = true; s.src = 'https://www.googletagmanager.com/gtag/js?id=' + ga4Id; document.head.appendChild(s); } })(); (function () { function setThemeColorMetas(theme) { var light = document.querySelector('meta\[data-theme-color="light"\]'); var dark = document.querySelector('meta\[data-theme-color="dark"\]'); if (light) light.setAttribute('media', theme === 'light' ? 'all' : 'not all'); if (dark) dark.setAttribute('media', theme === 'dark' ? 'all' : 'not all'); } try { var stored = localStorage.getItem('charming-theme'); if (stored === 'dark' || stored === 'light') { document.documentElement.setAttribute('data-theme', stored); setThemeColorMetas(stored); } } catch (\_err) { // Storage can be unavailable (private mode, disabled) — fall back to // the media query, same as a first-time visitor. } })(); Charming works with almost any AI(() => { // Keep this fallback aligned with copyValueToClipboard in ./clipboard.ts. // This script runs before modules load, so it cannot import the shared helper. async function copy(value) { try { if (navigator.clipboard) { await navigator.clipboard.writeText(value); return true; } } catch { // Fall through to the textarea path for browsers that block the async API. } let fallback; try { fallback = document.createElement('textarea'); fallback.value = value; fallback.setAttribute('readonly', ''); fallback.style.position = 'fixed'; fallback.style.top = '-9999px'; document.body.appendChild(fallback); fallback.select(); return document.execCommand('copy'); } catch { return false; } finally { fallback?.remove(); } } const resetTimers = new WeakMap(); function setVisible(element, visible) { element?.classList.replace( visible ? 'opacity-0' : 'opacity-100', visible ? 'opacity-100' : 'opacity-0', ); } function resetFeedback(button, island) { const action = button.querySelector('\[data-copy-action-label\]'); const confirmed = button.querySelector('\[data-copy-confirmed-label\]'); const confirmation = island.querySelector('\[data-copy-confirmation\]'); const liveRegion = island.querySelector('\[data-copy-live-region\]'); setVisible(action, true); setVisible(confirmed, false); setVisible(confirmation, false); confirmation?.classList.replace('translate-y-0', 'translate-y-1'); if (confirmation) { confirmation.textContent = button.dataset.copySuccessMessage ?? ''; if (confirmation.dataset.copyConfirmation === 'false') { confirmation.parentElement?.classList.replace('mt-2.5', 'mt-0'); confirmation.parentElement?.classList.replace('grid-rows-\[1fr\]', 'grid-rows-\[0fr\]'); } } if (liveRegion) liveRegion.textContent = ''; resetTimers.delete(button); } function showFeedback(button, island, copied) { const action = button.querySelector('\[data-copy-action-label\]'); const confirmed = button.querySelector('\[data-copy-confirmed-label\]'); const confirmation = island.querySelector('\[data-copy-confirmation\]'); const liveRegion = island.querySelector('\[data-copy-live-region\]'); const message = copied ? (button.dataset.copySuccessMessage ?? '') : (button.dataset.copyBlockedMessage ?? ''); setVisible(action, !copied); setVisible(confirmed, copied); if (confirmation) { confirmation.textContent = message; const buttonOnlySuccess = copied && confirmation.dataset.copyConfirmation === 'false'; setVisible(confirmation, !buttonOnlySuccess); confirmation.classList.replace( buttonOnlySuccess ? 'translate-y-0' : 'translate-y-1', buttonOnlySuccess ? 'translate-y-1' : 'translate-y-0', ); if (!copied && confirmation.dataset.copyConfirmation === 'false') { confirmation.parentElement?.classList.replace('mt-0', 'mt-2.5'); confirmation.parentElement?.classList.replace('grid-rows-\[0fr\]', 'grid-rows-\[1fr\]'); } } if (liveRegion) liveRegion.textContent = message; const priorTimer = resetTimers.get(button); if (priorTimer) clearTimeout(priorTimer); resetTimers.set( button, setTimeout(() => resetFeedback(button, island), 10000), ); } document.addEventListener( 'click', async (event) => { const target = event.target instanceof Element ? event.target : null; const button = target?.closest('button\[data-copy-value\]'); const island = button?.closest('astro-island\[ssr\]'); if (!button || !island) return; showFeedback(button, island, await copy(button.dataset.copyValue ?? '')); }, true, ); })(); {"@context":"https://schema.org","@graph":\[{"@type":"WebPage","@id":"https://usecharming.com/works-with#webpage","url":"https://usecharming.com/works-with","name":"Charming works with almost any AI","description":"Connect Charming to almost any AI through MCP or HTTP. See tested setup guides for ChatGPT, Claude, Microsoft Copilot, Codex, Cursor, and more.","isPartOf":{"@id":"https://usecharming.com/#website"},"about":{"@id":"https://usecharming.com/#software"},"primaryImageOfPage":"https://usecharming.com/og-image-works-with.png","speakable":{"@type":"SpeakableSpecification","cssSelector":\["h1","\[data-speakable\]"\]}},{"@type":"BreadcrumbList","@id":"https://usecharming.com/works-with#breadcrumb","itemListElement":\[{"@type":"ListItem","position":1,"name":"Charming","item":"https://usecharming.com/"},{"@type":"ListItem","position":2,"name":"Works with","item":"https://usecharming.com/works-with"}\]}\]}.marketing-cta-pair\[data-astro-cid-tks6ajz2\]>a{width:100%}@media (width>=640px){.marketing-cta-pair\[data-astro-cid-tks6ajz2\]>a{width:auto}} 

[![Charming](/charming-lockup.svg)![Charming](/charming-lockup-dark.svg)](/)

[Ideas](/#apps)[Pricing](/#pricing)[For Work](/work)[Blog](/blog)[Docs](/docs)

[Sign up](https://charm.ing/auth/signup)

[Ideas](/#apps)[Pricing](/#pricing)[For Work](/work)[Blog](/blog)[Docs](/docs)

var e=document.querySelector(\`\[data-nav-menu\]\`);e&&(e.querySelectorAll(\`a\`).forEach(t=>{t.addEventListener(\`click\`,()=>{e.open=!1})}),document.addEventListener(\`pointerdown\`,t=>{e.open&&!e.contains(t.target)&&(e.open=!1)}),document.addEventListener(\`keydown\`,t=>{t.key===\`Escape\`&&e.open&&(e.open=!1,e.querySelector(\`summary\`)?.focus())}));

# Charming works with _almost any AI._

If your AI supports MCP or can make HTTP requests, it can build and update Charming apps. That covers most AI chats, coding agents, and assistants.

[Sign up](https://charm.ing/auth/signup)[See how Charming works](/how-it-works)

Works with

![](/logos/chatgpt.svg)ChatGPT![](/logos/claude.svg)Claude![](/logos/claude-code.png)Claude Code![](/logos/cursor.svg)Cursor![](/logos/codex.svg)Codex![](/logos/gemini.svg)Gemini![](/logos/grok.svg)Grok![](/logos/perplexity.svg)Perplexity![](/logos/openclaw.svg)OpenClaw![](/logos/goose.png)Goose

## Tested with _these AIs._

We have tested Charming with every client below. Choose yours for the setup guide.

### Opens in the conversation

Build and use your app in the same chat.

[

![](/logos/chatgpt.svg)

### ChatGPT

Apps open in the chat

↗](https://charm.ing/docs/clients/chatgpt)[

![](/logos/claude.svg)

### Claude

Web, desktop, and Claude Code desktop

↗](https://charm.ing/docs/clients/claude)[

365

### Microsoft 365 Copilot

Apps open in Copilot chat

↗](https://charm.ing/docs/clients/microsoft-365-copilot)[

![](/logos/codex.svg)

### Codex

Codex app opens inline; CLI uses the browser

↗](https://charm.ing/docs/clients/codex)[

![](/logos/goose.png)

### Goose

Apps open in the conversation

↗](https://charm.ing/docs/clients/goose)

### Opens the app in your browser

Your AI can still build and update it.

[![](/logos/cursor.svg)

### Cursor

Remote MCP server

↗](https://charm.ing/docs/clients/cursor)[![](/logos/claude-code.png)

### Claude Code CLI

One terminal command

↗](https://charm.ing/docs/clients/claude-code)[![](/logos/perplexity.svg)

### Perplexity

Custom remote connector

↗](https://charm.ing/docs/clients/perplexity)[![](/logos/clients/cline.svg)

### Cline

VS Code extension

↗](https://charm.ing/docs/clients/cline)[![](/logos/clients/windsurf.svg)

### Windsurf

Cascade

↗](https://charm.ing/docs/clients/windsurf)[![](/logos/clients/continue.svg)

### Continue

Coding assistant

↗](https://charm.ing/docs/clients/continue)[![](/logos/clients/zed.svg)

### Zed

AI editor

↗](https://charm.ing/docs/clients/zed)[![](/logos/clients/notion.svg)

### Notion

Custom Agents

↗](https://charm.ing/docs/clients/notion)[![](/logos/clients/n8n.svg)

### n8n

MCP Client Tool

↗](https://charm.ing/docs/clients/n8n)[![](/logos/clients/aws.svg)

### Amazon Bedrock AgentCore

MCP server target

↗](https://charm.ing/docs/clients/agentcore)[![](/logos/gemini.svg)

### Gemini

Gemini CLI

↗](https://charm.ing/docs/clients/gemini)[![](/logos/grok.svg)

### Grok

Custom connector

↗](https://charm.ing/docs/clients/grok)

## Your AI is _probably supported._

Most AI agents can use one of these two paths. Add the MCP URL, or copy the setup prompt and let your agent handle it.

### Add the MCP URL

`https://charm.ing/mcp`astro-island,astro-slot,astro-static-slot{display:contents}(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event("astro:load"));})();(()=>{var g=Object.defineProperty;var w=(a,s,c)=>s in a?g(a,s,{enumerable:!0,configurable:!0,writable:!0,value:c}):a\[s\]=c;var l=(a,s,c)=>w(a,typeof s!="symbol"?s+"":s,c);var E=new Set(\["\_\_proto\_\_","constructor","prototype"\]);{let a={0:t=>y(t),1:t=>c(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(c(t)),5:t=>new Set(c(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>Number.POSITIVE\_INFINITY\*t},s=t=>{let\[p,e\]=t;return p in a?a\[p\](e):void 0},c=t=>t.map(s),y=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map((\[p,e\])=>\[p,s(e)\]));class f extends HTMLElement{constructor(){super(...arguments);l(this,"Component");l(this,"hydrator");l(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island\[ssr\]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let r=this.querySelectorAll("astro-slot"),n={},d=this.querySelectorAll("template\[data-astro-template\]");for(let o of d){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(n\[o.getAttribute("data-astro-template")||"default"\]=o.innerHTML,o.remove())}for(let o of r){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(n\[o.getAttribute("name")||"default"\]=o.innerHTML)}let u;try{u=this.hasAttribute("props")?y(JSON.parse(this.getAttribute("props"))):{}}catch(o){let i=this.getAttribute("component-url")||"<unknown>",v=this.getAttribute("component-export");throw v&&(i+=\` (export ${v})\`),console.error(\`\[hydrate\] Error parsing props for component ${i}\`,this.getAttribute("props"),o),o}let h;await this.hydrator(this)(this.Component,u,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});l(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),r.disconnect(),this.childrenConnectedCallback()},r=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT\_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});r.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}getRetryImportUrl(e){let r=new URL(e,document.baseURI);return r.searchParams.set("astro-retry",Date.now().toString()),r.toString()}async importWithRetry(e){try{return await import(e)}catch(r){return await new Promise(n=>setTimeout(n,1e3)),import(this.getRetryImportUrl(e))}}handleHydrationError(e){let r=this.getAttribute("component-url"),n=new CustomEvent("astro:hydration-error",{cancelable:!0,bubbles:!0,composed:!0,detail:{error:e,componentUrl:r}});this.dispatchEvent(n)&&console.error(\`\[astro-island\] Error hydrating ${r}\`,e)}async start(){let e=JSON.parse(this.getAttribute("opts")),r=this.getAttribute("client");if(Astro\[r\]===void 0){window.addEventListener(\`astro:${r}\`,()=>this.start(),{once:!0});return}try{await Astro\[r\](async()=>{let n=this.getAttribute("renderer-url");try{let\[d,{default:u}\]=await Promise.all(\[this.importWithRetry(this.getAttribute("component-url")),n?this.importWithRetry(n):Promise.resolve({default:()=>()=>{}})\]),h=this.getAttribute("component-export")||"default";if(h.includes(".")){this.Component=d;for(let m of h.split(".")){if(E.has(m)||!this.Component||typeof this.Component!="object"&&typeof this.Component!="function"||!Object.hasOwn(this.Component,m))throw new Error(\`Invalid component export path: ${h}\`);this.Component=this.Component\[m\]}}else{if(E.has(h))throw new Error(\`Invalid component export path: ${h}\`);this.Component=d\[h\]}return this.hydrator=u,this.hydrate}catch(d){return this.handleHydrationError(d),()=>{}}},e,this)}catch(n){this.handleHydrationError(n)}}attributeChangedCallback(){this.hydrate()}}l(f,"observedAttributes",\["props"\]),customElements.get("astro-island")||customElements.define("astro-island",f)}})();Copy MCP URL

### Let your AI set it up

Connect Charming to this agent. First check whether this client supports a remote MCP server. If it does, add https://charm.ing/mcp and complete the sign-in flow. Check https://charm.ing/docs/clients.md for a client-specific guide. If remote MCP is not available but you can make HTTP requests, read https://usecharming.com/build-http.md and use that path. Complete every step you can. Ask me only when you need approval. Then verify the connection, read https://charm.ing/docs/clients.md, and ask what app I want to build. If neither path works, tell me what this client is missing.

Copy setup prompt

## Bring the AI _you already pay for._

Connect once. Build and update apps from any chat.

[Sign up](https://charm.ing/auth/signup)[See the setup guides](https://charm.ing/docs/clients)

[](/)

Software that’s finally yours.

[Up and running](https://status.usecharming.com "System status. Opens status.usecharming.com")

## Explore

*   [Ideas](/#apps)
*   [How it works](/how-it-works)
*   [Pricing](/#pricing)
*   [For Work](/work)
*   [Blog](/blog)

## For work

*   [Finance](/work/finance)
*   [Internal tools](/work/internal-tools)
*   [Recruiting](/work/recruiting)
*   [Consultants](/work/consultants)
*   [Marketing](/work/marketing)

## Works with

*   [ChatGPT](https://chatgpt.com/plugins/plugin_asdk_app_6a56c533cd7c8191b9a16cb7973a65e6)
*   [Claude](https://charm.ing/docs/clients/claude)
*   [Microsoft 365 Copilot](https://charm.ing/docs/clients/microsoft-365-copilot)
*   [Cursor](https://charm.ing/docs/clients/cursor)
*   [All setup guides](/works-with)

## Learn

*   [Docs](/docs)
*   [Guides](/guides)
*   [Contact](/contact-us)
*   [llms.txt](/llms.txt)
*   [Email us](mailto:support@usecharming.com)

Explore+

*   [Ideas](/#apps)
*   [How it works](/how-it-works)
*   [Pricing](/#pricing)
*   [For Work](/work)
*   [Blog](/blog)

For work+

*   [Finance](/work/finance)
*   [Internal tools](/work/internal-tools)
*   [Recruiting](/work/recruiting)
*   [Consultants](/work/consultants)
*   [Marketing](/work/marketing)

App ideas+

*   [Job application tracker](/apps/job-application-tracker)
*   [Project status](/apps/project-status-tracker)
*   [Meeting actions](/apps/meeting-action-tracker)
*   [Vendor review](/apps/vendor-review)
*   [Product launch](/apps/product-launch-tracker)
*   [Review and approval](/apps/review-approval)
*   [Quote calculator](/apps/pricing-calculator)

Works with+

*   [ChatGPT](https://chatgpt.com/plugins/plugin_asdk_app_6a56c533cd7c8191b9a16cb7973a65e6)
*   [Claude](https://charm.ing/docs/clients/claude)
*   [Microsoft 365 Copilot](https://charm.ing/docs/clients/microsoft-365-copilot)
*   [Cursor](https://charm.ing/docs/clients/cursor)
*   [All setup guides](/works-with)

Learn+

*   [Docs](/docs)
*   [Guides](/guides)
*   [Contact](/contact-us)
*   [llms.txt](/llms.txt)
*   [Email us](mailto:support@usecharming.com)

## App ideas

[Job application tracker](/apps/job-application-tracker)[Project status](/apps/project-status-tracker)[Meeting actions](/apps/meeting-action-tracker)[Vendor review](/apps/vendor-review)[Product launch](/apps/product-launch-tracker)[Review and approval](/apps/review-approval)[Quote calculator](/apps/pricing-calculator)

© 2026 Charming

[Privacy](/privacy)[Terms](/terms)[Fair use](/fair-use)[Subprocessors](/subprocessors)

charm.ing

var e=document.documentElement,t=window.matchMedia(\`(prefers-color-scheme: dark)\`),n=()=>{let n=e.getAttribute(\`data-theme\`);return n===\`light\`||n===\`dark\`?n:t.matches?\`dark\`:\`light\`},r=document.querySelector(\`\[data-theme-toggle\]\`),i=()=>{if(!r)return;let e=n()===\`dark\`?\`light\`:\`dark\`;r.setAttribute(\`aria-label\`,\`Switch to ${e} theme\`)};i();var a=e=>{let t=document.querySelector(\`meta\[data-theme-color="light"\]\`),n=document.querySelector(\`meta\[data-theme-color="dark"\]\`);t?.setAttribute(\`media\`,e===\`light\`?\`all\`:\`not all\`),n?.setAttribute(\`media\`,e===\`dark\`?\`all\`:\`not all\`)};r?.addEventListener(\`click\`,()=>{let t=n()===\`dark\`?\`light\`:\`dark\`;e.setAttribute(\`data-theme\`,t),a(t);try{localStorage.setItem(\`charming-theme\`,t)}catch{}i()}),t.addEventListener(\`change\`,()=>{e.hasAttribute(\`data-theme\`)||i()});