diff --git a/extension/content.js b/extension/content.js
new file mode 100644
index 0000000..df00446
--- /dev/null
+++ b/extension/content.js
@@ -0,0 +1,42 @@
+const CHAT_ORIGIN = 'https://inquid.github.io/github-chat'
+const CHAT_URL = CHAT_ORIGIN + '/index.html'
+
+let chatFrame = null
+let toggleBtn = null
+let isOpen = false
+
+function createToggle() {
+ toggleBtn = document.createElement('button')
+ toggleBtn.id = 'ghchat-toggle'
+ toggleBtn.innerHTML = `
+
+ `
+ toggleBtn.setAttribute('aria-label', 'Toggle chat')
+ toggleBtn.addEventListener('click', toggleChat)
+ document.body.appendChild(toggleBtn)
+}
+
+function createChatFrame() {
+ chatFrame = document.createElement('div')
+ chatFrame.id = 'ghchat-frame'
+ chatFrame.innerHTML = `
+
+
+ `
+ chatFrame.querySelector('#ghchat-close').addEventListener('click', toggleChat)
+ document.body.appendChild(chatFrame)
+}
+
+function toggleChat() {
+ isOpen = !isOpen
+ chatFrame.classList.toggle('ghchat-open', isOpen)
+ toggleBtn.classList.toggle('ghchat-hidden', isOpen)
+}
+
+createToggle()
+createChatFrame()
diff --git a/extension/icons/icon128.png b/extension/icons/icon128.png
new file mode 100644
index 0000000..09f83c3
Binary files /dev/null and b/extension/icons/icon128.png differ
diff --git a/extension/icons/icon16.png b/extension/icons/icon16.png
new file mode 100644
index 0000000..9048827
Binary files /dev/null and b/extension/icons/icon16.png differ
diff --git a/extension/icons/icon48.png b/extension/icons/icon48.png
new file mode 100644
index 0000000..b5e4ff7
Binary files /dev/null and b/extension/icons/icon48.png differ
diff --git a/extension/manifest.json b/extension/manifest.json
new file mode 100644
index 0000000..dfcafbc
--- /dev/null
+++ b/extension/manifest.json
@@ -0,0 +1,21 @@
+{
+ "manifest_version": 3,
+ "name": "GitHub Chat",
+ "version": "1.0.0",
+ "description": "Floating chat panel for GitHub pages. Toggle in the bottom-right corner.",
+ "permissions": [],
+ "host_permissions": ["https://github.com/*"],
+ "content_scripts": [
+ {
+ "matches": ["https://github.com/*"],
+ "js": ["content.js"],
+ "css": ["styles.css"],
+ "run_at": "document_end"
+ }
+ ],
+ "icons": {
+ "16": "icons/icon16.png",
+ "48": "icons/icon48.png",
+ "128": "icons/icon128.png"
+ }
+}
diff --git a/extension/styles.css b/extension/styles.css
new file mode 100644
index 0000000..25988d4
--- /dev/null
+++ b/extension/styles.css
@@ -0,0 +1,83 @@
+#ghchat-toggle {
+ position: fixed;
+ bottom: 20px;
+ right: 20px;
+ z-index: 999999;
+ width: 48px;
+ height: 48px;
+ border-radius: 50%;
+ background: #2da44e;
+ color: #fff;
+ border: none;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 4px 12px rgba(0,0,0,0.25);
+ transition: transform 0.2s, opacity 0.2s, visibility 0.2s;
+}
+#ghchat-toggle:hover {
+ transform: scale(1.1);
+ background: #2c974b;
+}
+#ghchat-toggle.ghchat-hidden {
+ opacity: 0;
+ visibility: hidden;
+ transform: scale(0.8);
+}
+
+#ghchat-frame {
+ position: fixed;
+ bottom: 20px;
+ right: 20px;
+ z-index: 999999;
+ width: 360px;
+ height: 500px;
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.3);
+ display: flex;
+ flex-direction: column;
+ transform: translateY(20px);
+ opacity: 0;
+ visibility: hidden;
+ transition: transform 0.25s ease, opacity 0.25s ease, visibility 0.25s;
+}
+#ghchat-frame.ghchat-open {
+ transform: translateY(0);
+ opacity: 1;
+ visibility: visible;
+}
+
+#ghchat-header {
+ background: #2da44e;
+ color: #fff;
+ padding: 10px 16px;
+ font: 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
+ font-weight: 600;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-shrink: 0;
+}
+#ghchat-header button {
+ background: none;
+ border: none;
+ color: #fff;
+ font-size: 20px;
+ cursor: pointer;
+ padding: 0 4px;
+ line-height: 1;
+ opacity: 0.8;
+}
+#ghchat-header button:hover {
+ opacity: 1;
+}
+
+#ghchat-iframe {
+ flex: 1;
+ width: 100%;
+ height: 100%;
+ background: #fff;
+ border: none;
+}