diff --git a/frontend/src/pages/api-docs/ApiDocsPage.vue b/frontend/src/pages/api-docs/ApiDocsPage.vue index 9a5f958e..c53ae553 100644 --- a/frontend/src/pages/api-docs/ApiDocsPage.vue +++ b/frontend/src/pages/api-docs/ApiDocsPage.vue @@ -1,5 +1,5 @@ @@ -150,7 +199,7 @@ onMounted(() => { API Token - +
Regenerate - +
 {
                 
               
               
-                {{ visibleSections }} / {{ endpointCount }} endpoints
+                {{ visibleEndpoints }} / {{ endpointCount }} endpoints
               
               
                 
@@ -213,16 +262,27 @@ onMounted(() => {
 
             
 
             
@@ -273,20 +333,25 @@ onMounted(() => {
 }
 
 .docs-header {
-  margin-bottom: 18px;
+  margin-bottom: 20px;
+  padding: 24px;
+  background: var(--bg-card);
+  border: 1px solid rgba(128, 128, 128, 0.12);
+  border-radius: 10px;
 }
 
 .docs-title {
-  font-size: 26px;
-  font-weight: 700;
+  font-size: 28px;
+  font-weight: 800;
   margin: 0 0 8px;
   color: rgba(0, 0, 0, 0.88);
+  letter-spacing: -0.3px;
 }
 
 .docs-lead {
   margin: 0;
   color: rgba(0, 0, 0, 0.65);
-  line-height: 1.6;
+  line-height: 1.65;
   font-size: 14px;
 }
 
@@ -310,7 +375,8 @@ onMounted(() => {
   justify-content: space-between;
   gap: 12px;
   flex-wrap: wrap;
-  margin-bottom: 8px;
+  margin-bottom: 10px;
+  min-height: 32px;
 }
 
 .token-card-title {
@@ -321,6 +387,13 @@ onMounted(() => {
   font-size: 14px;
 }
 
+.token-actions {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  flex-wrap: wrap;
+}
+
 .token-value {
   background: rgba(128, 128, 128, 0.08);
   border: 1px solid rgba(128, 128, 128, 0.15);
@@ -377,32 +450,87 @@ onMounted(() => {
 .toc-nav {
   display: flex;
   flex-wrap: wrap;
-  align-items: center;
-  gap: 8px 14px;
+  align-items: flex-start;
+  gap: 8px 12px;
   padding: 12px 16px;
-  background: rgba(128, 128, 128, 0.08);
-  border-radius: 6px;
+  background: var(--bg-card);
+  border: 1px solid rgba(128, 128, 128, 0.12);
+  border-radius: 8px;
   margin-bottom: 16px;
 }
 
 .toc-label {
-  font-size: 12px;
+  font-size: 11px;
   font-weight: 600;
   text-transform: uppercase;
-  letter-spacing: 0.5px;
+  letter-spacing: 0.6px;
   color: rgba(0, 0, 0, 0.5);
+  padding-top: 3px;
+  flex-shrink: 0;
+}
+
+.toc-links {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 6px;
 }
 
 .toc-link {
-  color: #1677ff;
+  display: inline-flex;
+  align-items: center;
+  gap: 5px;
+  padding: 4px 10px;
+  border-radius: 20px;
+  font-size: 12.5px;
+  color: rgba(0, 0, 0, 0.65);
+  background: rgba(128, 128, 128, 0.06);
+  border: 1px solid transparent;
   text-decoration: none;
   cursor: pointer;
-  font-size: 13px;
+  transition: all 0.2s;
+  white-space: nowrap;
 }
 
 .toc-link:hover {
-  color: #4096ff;
-  text-decoration: underline;
+  background: rgba(22, 119, 255, 0.08);
+  color: #1677ff;
+  border-color: rgba(22, 119, 255, 0.2);
+}
+
+.toc-link.active {
+  background: rgba(22, 119, 255, 0.12);
+  color: #1677ff;
+  border-color: rgba(22, 119, 255, 0.3);
+  font-weight: 600;
+}
+
+.toc-icon {
+  font-size: 13px;
+  opacity: 0.8;
+}
+
+.toc-text {
+  font-size: 12.5px;
+}
+
+.toc-badge {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  min-width: 18px;
+  height: 18px;
+  padding: 0 5px;
+  border-radius: 9px;
+  font-size: 10.5px;
+  font-weight: 700;
+  background: rgba(22, 119, 255, 0.12);
+  color: #1677ff;
+  line-height: 1;
+}
+
+.toc-link.active .toc-badge {
+  background: #1677ff;
+  color: #fff;
 }
 
 
@@ -411,16 +539,40 @@ body.dark .docs-title {
   color: rgba(255, 255, 255, 0.92);
 }
 
+html[data-theme='ultra-dark'] .docs-title {
+  color: rgba(255, 255, 255, 0.95);
+}
+
+body.dark .docs-header {
+  background: #252526;
+  border-color: rgba(255, 255, 255, 0.08);
+}
+
+html[data-theme='ultra-dark'] .docs-header {
+  background: #0a0a0a;
+  border-color: rgba(255, 255, 255, 0.06);
+}
+
 body.dark .docs-lead,
 body.dark .token-hint {
   color: rgba(255, 255, 255, 0.7);
 }
 
+html[data-theme='ultra-dark'] .docs-lead,
+html[data-theme='ultra-dark'] .token-hint {
+  color: rgba(255, 255, 255, 0.75);
+}
+
 body.dark .docs-lead code,
 body.dark .token-hint code {
   background: rgba(255, 255, 255, 0.1);
 }
 
+html[data-theme='ultra-dark'] .docs-lead code,
+html[data-theme='ultra-dark'] .token-hint code {
+  background: rgba(255, 255, 255, 0.12);
+}
+
 body.dark .token-value,
 body.dark .code-block {
   background: rgba(255, 255, 255, 0.04);
@@ -428,11 +580,58 @@ body.dark .code-block {
   color: rgba(255, 255, 255, 0.88);
 }
 
+html[data-theme='ultra-dark'] .token-value,
+html[data-theme='ultra-dark'] .code-block {
+  background: rgba(255, 255, 255, 0.02);
+  border-color: rgba(255, 255, 255, 0.08);
+}
+
 body.dark .toc-nav {
-  background: rgba(255, 255, 255, 0.04);
+  background: #252526;
+  border-color: rgba(255, 255, 255, 0.08);
+}
+
+html[data-theme='ultra-dark'] .toc-nav {
+  background: #0a0a0a;
+  border-color: rgba(255, 255, 255, 0.06);
 }
 
 body.dark .toc-label {
   color: rgba(255, 255, 255, 0.55);
 }
+
+html[data-theme='ultra-dark'] .toc-label {
+  color: rgba(255, 255, 255, 0.6);
+}
+
+body.dark .toc-link {
+  color: rgba(255, 255, 255, 0.65);
+  background: rgba(255, 255, 255, 0.06);
+}
+
+html[data-theme='ultra-dark'] .toc-link {
+  background: rgba(255, 255, 255, 0.04);
+}
+
+body.dark .toc-link:hover {
+  background: rgba(88, 166, 255, 0.12);
+  color: #58a6ff;
+  border-color: rgba(88, 166, 255, 0.25);
+}
+
+body.dark .toc-link.active {
+  background: rgba(88, 166, 255, 0.15);
+  color: #58a6ff;
+  border-color: rgba(88, 166, 255, 0.35);
+}
+
+body.dark .toc-badge {
+  background: rgba(88, 166, 255, 0.15);
+  color: #58a6ff;
+}
+
+body.dark .toc-link.active .toc-badge {
+  background: #58a6ff;
+  color: #0d1117;
+}
 
diff --git a/frontend/src/pages/api-docs/CodeBlock.vue b/frontend/src/pages/api-docs/CodeBlock.vue
index b728e854..446016c7 100644
--- a/frontend/src/pages/api-docs/CodeBlock.vue
+++ b/frontend/src/pages/api-docs/CodeBlock.vue
@@ -50,10 +50,13 @@ async function copyCode() {
 
 
@@ -63,30 +66,40 @@ async function copyCode() {
   position: relative;
   border-radius: 6px;
   overflow: hidden;
+  border: 1px solid rgba(128, 128, 128, 0.15);
+}
+
+.code-toolbar {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 4px 8px;
+  background: rgba(128, 128, 128, 0.06);
+  border-bottom: 1px solid rgba(128, 128, 128, 0.1);
+}
+
+.lang-badge {
+  font-size: 10px;
+  font-weight: 700;
+  letter-spacing: 0.5px;
+  color: rgba(0, 0, 0, 0.4);
+  text-transform: uppercase;
+  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
 }
 
 .copy-btn {
-  position: absolute;
-  top: 6px;
-  right: 6px;
-  z-index: 1;
   display: inline-flex;
   align-items: center;
   justify-content: center;
-  width: 28px;
-  height: 28px;
-  border: 1px solid rgba(128, 128, 128, 0.2);
+  width: 26px;
+  height: 26px;
+  border: 1px solid rgba(128, 128, 128, 0.15);
   border-radius: 4px;
-  background: rgba(255, 255, 255, 0.85);
-  color: rgba(0, 0, 0, 0.5);
+  background: rgba(255, 255, 255, 0.7);
+  color: rgba(0, 0, 0, 0.45);
   cursor: pointer;
-  font-size: 13px;
-  opacity: 0;
-  transition: opacity 0.15s, background 0.15s, color 0.15s;
-}
-
-.code-block-wrapper:hover .copy-btn {
-  opacity: 1;
+  font-size: 12px;
+  transition: all 0.15s;
 }
 
 .copy-btn:hover {
@@ -96,27 +109,24 @@ async function copyCode() {
 }
 
 .copy-btn.copied {
-  opacity: 1;
   background: #52c41a;
   color: #fff;
   border-color: #52c41a;
 }
 
 .code-block {
-  background: rgba(128, 128, 128, 0.08);
-  border: 1px solid rgba(128, 128, 128, 0.15);
-  border-radius: 6px;
-  padding: 12px;
+  background: rgba(128, 128, 128, 0.04);
+  padding: 10px 12px;
   margin: 0;
   font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
   font-size: 12.5px;
-  line-height: 1.55;
+  line-height: 1.6;
   white-space: pre-wrap;
   word-break: break-word;
   overflow-x: auto;
+  border: none;
+  border-radius: 0;
 }
-
-
 
 
 
 
 
diff --git a/frontend/src/pages/api-docs/endpoints.js b/frontend/src/pages/api-docs/endpoints.js
index c92ee389..24259bbb 100644
--- a/frontend/src/pages/api-docs/endpoints.js
+++ b/frontend/src/pages/api-docs/endpoints.js
@@ -69,7 +69,7 @@ export const sections = [
 
   {
     id: 'inbounds',
-    title: 'Inbounds API',
+    title: 'Inbounds',
     description:
       'Manage inbound configurations and their clients. All endpoints live under /panel/api/inbounds and require a logged-in session or Bearer token. Link-generating endpoints honour forwarded headers only when the request comes from a configured trusted proxy.',
     endpoints: [
@@ -193,6 +193,14 @@ export const sections = [
         body:
           '{\n  "id": 1,\n  "settings": "{\\"clients\\":[{\\"id\\":\\"uuid-here\\",\\"email\\":\\"user1\\",\\"limitIp\\":2,\\"totalGB\\":10737418240,\\"expiryTime\\":1735689600000,\\"enable\\":true}]}"\n}',
       },
+      {
+        method: 'POST',
+        path: '/panel/api/inbounds/:id/resetTraffic',
+        summary: 'Zero out upload + download counters for a single inbound. Does not touch per-client counters.',
+        params: [
+          { name: 'id', in: 'path', type: 'number', desc: 'Inbound ID.' },
+        ],
+      },
       {
         method: 'POST',
         path: '/panel/api/inbounds/:id/resetClientTraffic/:email',
@@ -289,7 +297,7 @@ export const sections = [
 
   {
     id: 'server',
-    title: 'Server API',
+    title: 'Server',
     description:
       'System status, log retrieval, certificate generators, Xray binary management, and backup/restore. All under /panel/api/server.',
     endpoints: [
@@ -488,7 +496,7 @@ export const sections = [
 
   {
     id: 'nodes',
-    title: 'Nodes API',
+    title: 'Nodes',
     description:
       'Manage remote 3x-ui panels acting as nodes for a central panel. All endpoints under /panel/api/nodes.',
     endpoints: [
@@ -569,7 +577,7 @@ export const sections = [
 
   {
     id: 'customGeo',
-    title: 'Custom Geo API',
+    title: 'Custom Geo',
     description:
       'Manage user-supplied GeoIP / GeoSite source files. All endpoints under /panel/api/custom-geo.',
     endpoints: [
@@ -637,7 +645,7 @@ export const sections = [
 
   {
     id: 'settings',
-    title: 'Settings API',
+    title: 'Settings',
     description:
       'Panel configuration, user credentials, and API token management. All endpoints live under /panel/setting and require a logged-in session or Bearer token.',
     endpoints: [
@@ -697,7 +705,7 @@ export const sections = [
 
   {
     id: 'xraySettings',
-    title: 'Xray Settings API',
+    title: 'Xray Settings',
     description:
       'Xray configuration template, outbound management, Warp/Nord integration, and config testing. All endpoints under /panel/xray.',
     endpoints: [