@agent-link/server 0.1.158 → 0.1.160
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/web/images/chat-iPad.webp +0 -0
- package/web/images/chat-iPhone.webp +0 -0
- package/web/images/loop-iPad.webp +0 -0
- package/web/images/team-iPad.webp +0 -0
- package/web/landing.html +329 -122
- package/web/landing.zh.html +326 -120
- package/web/iPad.png +0 -0
- package/web/iPad.webp +0 -0
- package/web/iPhone.png +0 -0
- package/web/iPhone.webp +0 -0
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/web/landing.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>AgentLink — Remote Control for Claude Code</title>
|
|
7
|
-
<meta name="description" content="Remote control for Claude Code.
|
|
8
|
-
<meta name="keywords" content="Claude Code, remote control, browser IDE, AI coding assistant, AgentLink, end-to-end encrypted, self-hosted, mobile coding">
|
|
7
|
+
<meta name="description" content="Remote control for Claude Code. Chat, spawn agent teams, or schedule recurring tasks — from your phone or any browser. Multi-session, end-to-end encrypted.">
|
|
8
|
+
<meta name="keywords" content="Claude Code, remote control, browser IDE, AI coding assistant, AgentLink, end-to-end encrypted, self-hosted, mobile coding, multi-agent, scheduled tasks, cron">
|
|
9
9
|
<link rel="canonical" href="https://msclaude.ai/">
|
|
10
10
|
<link rel="alternate" hreflang="en" href="https://msclaude.ai/">
|
|
11
11
|
<link rel="alternate" hreflang="zh" href="https://msclaude.ai/zh">
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
<!-- Open Graph -->
|
|
14
14
|
<meta property="og:type" content="website">
|
|
15
15
|
<meta property="og:title" content="AgentLink — Remote Control for Claude Code">
|
|
16
|
-
<meta property="og:description" content="Remote control for Claude Code.
|
|
16
|
+
<meta property="og:description" content="Remote control for Claude Code. Chat, spawn agent teams, or schedule recurring tasks — from your phone or any browser. Multi-session, end-to-end encrypted.">
|
|
17
17
|
<meta property="og:url" content="https://msclaude.ai/">
|
|
18
18
|
<meta property="og:image" content="https://msclaude.ai/iPad.png">
|
|
19
19
|
<meta property="og:site_name" content="AgentLink">
|
|
20
20
|
<!-- Twitter Card -->
|
|
21
21
|
<meta name="twitter:card" content="summary_large_image">
|
|
22
22
|
<meta name="twitter:title" content="AgentLink — Remote Control for Claude Code">
|
|
23
|
-
<meta name="twitter:description" content="Remote control for Claude Code.
|
|
23
|
+
<meta name="twitter:description" content="Remote control for Claude Code. Chat, spawn agent teams, or schedule recurring tasks — from your phone or any browser. Multi-session, end-to-end encrypted.">
|
|
24
24
|
<meta name="twitter:image" content="https://msclaude.ai/iPad.png">
|
|
25
25
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
26
26
|
<script type="application/ld+json">
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@context": "https://schema.org",
|
|
29
29
|
"@type": "SoftwareApplication",
|
|
30
30
|
"name": "AgentLink",
|
|
31
|
-
"description": "Remote control for Claude Code.
|
|
31
|
+
"description": "Remote control for Claude Code. Chat, spawn agent teams, or schedule recurring tasks — from your phone or any browser. Multi-session, end-to-end encrypted.",
|
|
32
32
|
"url": "https://msclaude.ai/",
|
|
33
33
|
"applicationCategory": "DeveloperApplication",
|
|
34
34
|
"operatingSystem": "Windows, macOS, Linux",
|
|
@@ -536,11 +536,8 @@
|
|
|
536
536
|
}
|
|
537
537
|
|
|
538
538
|
.device-ipad img {
|
|
539
|
-
border-radius:
|
|
540
|
-
box-shadow:
|
|
541
|
-
0 40px 100px rgba(0,0,0,0.5),
|
|
542
|
-
0 15px 50px rgba(0,0,0,0.3),
|
|
543
|
-
0 0 80px rgba(59,130,246,0.08);
|
|
539
|
+
border-radius: 0;
|
|
540
|
+
box-shadow: none;
|
|
544
541
|
}
|
|
545
542
|
|
|
546
543
|
.device-iphone {
|
|
@@ -563,6 +560,106 @@
|
|
|
563
560
|
0 0 80px rgba(245,158,11,0.08);
|
|
564
561
|
}
|
|
565
562
|
|
|
563
|
+
/* ── iPad Carousel ── */
|
|
564
|
+
.ipad-carousel {
|
|
565
|
+
position: relative;
|
|
566
|
+
width: 100%;
|
|
567
|
+
overflow: hidden;
|
|
568
|
+
border-radius: 4.2%;
|
|
569
|
+
box-shadow:
|
|
570
|
+
0 40px 100px rgba(0,0,0,0.5),
|
|
571
|
+
0 15px 50px rgba(0,0,0,0.3),
|
|
572
|
+
0 0 80px rgba(59,130,246,0.08);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.carousel-track {
|
|
576
|
+
position: relative;
|
|
577
|
+
width: 100%;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
.carousel-slide {
|
|
581
|
+
position: absolute;
|
|
582
|
+
top: 0;
|
|
583
|
+
left: 0;
|
|
584
|
+
width: 100%;
|
|
585
|
+
opacity: 0;
|
|
586
|
+
transition: opacity 0.6s ease;
|
|
587
|
+
pointer-events: none;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.carousel-slide.active {
|
|
591
|
+
position: relative;
|
|
592
|
+
opacity: 1;
|
|
593
|
+
pointer-events: auto;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
.carousel-slide img {
|
|
597
|
+
display: block;
|
|
598
|
+
width: 100%;
|
|
599
|
+
height: auto;
|
|
600
|
+
border-radius: 0;
|
|
601
|
+
box-shadow: none;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.carousel-dots {
|
|
605
|
+
position: absolute;
|
|
606
|
+
bottom: 12px;
|
|
607
|
+
left: 50%;
|
|
608
|
+
transform: translateX(-50%);
|
|
609
|
+
display: flex;
|
|
610
|
+
gap: 8px;
|
|
611
|
+
z-index: 5;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
.carousel-dot {
|
|
615
|
+
width: 8px;
|
|
616
|
+
height: 8px;
|
|
617
|
+
border-radius: 50%;
|
|
618
|
+
border: none;
|
|
619
|
+
background: rgba(255,255,255,0.4);
|
|
620
|
+
cursor: pointer;
|
|
621
|
+
padding: 0;
|
|
622
|
+
transition: background 0.3s ease, transform 0.3s ease;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
.carousel-dot.active {
|
|
626
|
+
background: rgba(255,255,255,0.9);
|
|
627
|
+
transform: scale(1.2);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
.carousel-dot:hover {
|
|
631
|
+
background: rgba(255,255,255,0.7);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
.carousel-label {
|
|
635
|
+
position: absolute;
|
|
636
|
+
top: 16px;
|
|
637
|
+
left: 16px;
|
|
638
|
+
display: flex;
|
|
639
|
+
flex-direction: column;
|
|
640
|
+
gap: 2px;
|
|
641
|
+
background: rgba(0,0,0,0.55);
|
|
642
|
+
backdrop-filter: blur(12px);
|
|
643
|
+
-webkit-backdrop-filter: blur(12px);
|
|
644
|
+
padding: 8px 14px;
|
|
645
|
+
border-radius: 10px;
|
|
646
|
+
z-index: 4;
|
|
647
|
+
pointer-events: none;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
.carousel-label-title {
|
|
651
|
+
font-size: 0.95rem;
|
|
652
|
+
font-weight: 700;
|
|
653
|
+
color: #fff;
|
|
654
|
+
letter-spacing: 0.02em;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.carousel-label-desc {
|
|
658
|
+
font-size: 0.72rem;
|
|
659
|
+
color: rgba(255,255,255,0.75);
|
|
660
|
+
font-weight: 400;
|
|
661
|
+
}
|
|
662
|
+
|
|
566
663
|
/* ── Divider ── */
|
|
567
664
|
.section-divider {
|
|
568
665
|
max-width: 200px;
|
|
@@ -668,6 +765,60 @@
|
|
|
668
765
|
.bento-icon.amber { background: linear-gradient(135deg, rgba(245,158,11,0.2), rgba(245,158,11,0.05)); color: var(--amber); }
|
|
669
766
|
.bento-icon.blue { background: linear-gradient(135deg, rgba(96,165,250,0.2), rgba(96,165,250,0.05)); color: var(--blue); }
|
|
670
767
|
|
|
768
|
+
/* Mode toggle visual */
|
|
769
|
+
.mode-toggle {
|
|
770
|
+
display: flex;
|
|
771
|
+
gap: 0;
|
|
772
|
+
background: rgba(255,255,255,0.04);
|
|
773
|
+
border: 1px solid var(--border);
|
|
774
|
+
border-radius: 12px;
|
|
775
|
+
overflow: hidden;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
.mode-toggle-item {
|
|
779
|
+
flex: 1;
|
|
780
|
+
text-align: center;
|
|
781
|
+
padding: 0.7rem 1rem;
|
|
782
|
+
position: relative;
|
|
783
|
+
transition: all 0.3s;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
.mode-toggle-item:not(:last-child) {
|
|
787
|
+
border-right: 1px solid var(--border);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
.mode-toggle-item.active {
|
|
791
|
+
background: rgba(59,130,246,0.12);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
.mode-toggle-item .mode-icon {
|
|
795
|
+
width: 32px; height: 32px;
|
|
796
|
+
margin: 0 auto 0.4rem;
|
|
797
|
+
border-radius: 8px;
|
|
798
|
+
display: flex;
|
|
799
|
+
align-items: center;
|
|
800
|
+
justify-content: center;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
.mode-toggle-item .mode-icon svg { width: 18px; height: 18px; }
|
|
804
|
+
|
|
805
|
+
.mode-toggle-item .mode-icon.chat-icon { background: rgba(59,130,246,0.15); color: var(--accent); }
|
|
806
|
+
.mode-toggle-item .mode-icon.team-icon { background: rgba(96,165,250,0.15); color: var(--blue); }
|
|
807
|
+
.mode-toggle-item .mode-icon.loop-icon { background: rgba(52,211,153,0.15); color: var(--green); }
|
|
808
|
+
|
|
809
|
+
.mode-toggle-item .mode-name {
|
|
810
|
+
font-size: 0.8rem;
|
|
811
|
+
font-weight: 600;
|
|
812
|
+
margin-bottom: 0.2rem;
|
|
813
|
+
color: var(--text);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
.mode-toggle-item .mode-desc {
|
|
817
|
+
font-size: 0.68rem;
|
|
818
|
+
color: var(--text-dim);
|
|
819
|
+
line-height: 1.4;
|
|
820
|
+
}
|
|
821
|
+
|
|
671
822
|
/* Encryption visual */
|
|
672
823
|
.encrypt-visual {
|
|
673
824
|
display: flex;
|
|
@@ -926,6 +1077,11 @@
|
|
|
926
1077
|
align-self: auto;
|
|
927
1078
|
}
|
|
928
1079
|
.device-iphone:hover { transform: translateY(-3%); }
|
|
1080
|
+
.carousel-dots { bottom: 8px; gap: 6px; }
|
|
1081
|
+
.carousel-dot { width: 6px; height: 6px; }
|
|
1082
|
+
.carousel-label { top: 8px; left: 8px; padding: 5px 10px; border-radius: 8px; }
|
|
1083
|
+
.carousel-label-title { font-size: 0.8rem; }
|
|
1084
|
+
.carousel-label-desc { font-size: 0.62rem; }
|
|
929
1085
|
.terminal { margin: 0 1rem; max-width: calc(100vw - 2rem); }
|
|
930
1086
|
.terminal-body { padding: 1rem; font-size: 0.75rem; overflow-x: auto; }
|
|
931
1087
|
.terminal-line { gap: 0.4rem; white-space: nowrap; }
|
|
@@ -942,18 +1098,6 @@
|
|
|
942
1098
|
.workflow-steps::before { left: 19px; }
|
|
943
1099
|
}
|
|
944
1100
|
|
|
945
|
-
/* ── Scroll animations ── */
|
|
946
|
-
.reveal {
|
|
947
|
-
opacity: 0;
|
|
948
|
-
transform: translateY(30px);
|
|
949
|
-
transition: opacity 0.8s ease, transform 0.8s ease;
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
.reveal.visible {
|
|
953
|
-
opacity: 1;
|
|
954
|
-
transform: translateY(0);
|
|
955
|
-
}
|
|
956
|
-
|
|
957
1101
|
.sr-only {
|
|
958
1102
|
position: absolute;
|
|
959
1103
|
width: 1px; height: 1px;
|
|
@@ -1010,8 +1154,8 @@
|
|
|
1010
1154
|
</h1>
|
|
1011
1155
|
<p class="hero-sub">
|
|
1012
1156
|
Start Claude Code on your machine. Walk away.
|
|
1013
|
-
<strong>
|
|
1014
|
-
|
|
1157
|
+
<strong>Chat, launch agent teams, or schedule tasks</strong> —
|
|
1158
|
+
from your phone, tablet, or any browser. End-to-end encrypted, zero config.
|
|
1015
1159
|
</p>
|
|
1016
1160
|
<div class="cta-group">
|
|
1017
1161
|
<button class="cta-primary" onclick="copyInstall()">
|
|
@@ -1049,41 +1193,106 @@
|
|
|
1049
1193
|
</section>
|
|
1050
1194
|
|
|
1051
1195
|
<!-- Device Showcase -->
|
|
1052
|
-
<section class="showcase
|
|
1196
|
+
<section class="showcase">
|
|
1053
1197
|
<div class="device device-ipad">
|
|
1054
|
-
<
|
|
1055
|
-
<
|
|
1056
|
-
|
|
1057
|
-
|
|
1198
|
+
<div class="ipad-carousel">
|
|
1199
|
+
<div class="carousel-track">
|
|
1200
|
+
<div class="carousel-slide active">
|
|
1201
|
+
<img src="/images/chat-iPad.webp" alt="AgentLink Chat mode on iPad" loading="eager">
|
|
1202
|
+
<div class="carousel-label">
|
|
1203
|
+
<span class="carousel-label-title">Chat</span>
|
|
1204
|
+
<span class="carousel-label-desc">Remote pair-programming with Claude Code</span>
|
|
1205
|
+
</div>
|
|
1206
|
+
</div>
|
|
1207
|
+
<div class="carousel-slide">
|
|
1208
|
+
<img src="/images/team-iPad.webp" alt="AgentLink Team mode on iPad" loading="eager">
|
|
1209
|
+
<div class="carousel-label">
|
|
1210
|
+
<span class="carousel-label-title">Teams</span>
|
|
1211
|
+
<span class="carousel-label-desc">Orchestrate multiple agents in parallel</span>
|
|
1212
|
+
</div>
|
|
1213
|
+
</div>
|
|
1214
|
+
<div class="carousel-slide">
|
|
1215
|
+
<img src="/images/loop-iPad.webp" alt="AgentLink Loop mode on iPad" loading="eager">
|
|
1216
|
+
<div class="carousel-label">
|
|
1217
|
+
<span class="carousel-label-title">Loop</span>
|
|
1218
|
+
<span class="carousel-label-desc">Scheduled tasks with cron automation</span>
|
|
1219
|
+
</div>
|
|
1220
|
+
</div>
|
|
1221
|
+
</div>
|
|
1222
|
+
<div class="carousel-dots">
|
|
1223
|
+
<button class="carousel-dot active" data-index="0" aria-label="Chat mode"></button>
|
|
1224
|
+
<button class="carousel-dot" data-index="1" aria-label="Team mode"></button>
|
|
1225
|
+
<button class="carousel-dot" data-index="2" aria-label="Loop mode"></button>
|
|
1226
|
+
</div>
|
|
1227
|
+
</div>
|
|
1058
1228
|
</div>
|
|
1059
1229
|
<div class="device device-iphone">
|
|
1060
|
-
<
|
|
1061
|
-
<source srcset="/iPhone.webp" type="image/webp">
|
|
1062
|
-
<img src="/iPhone.png" alt="AgentLink mobile interface on iPhone" loading="eager">
|
|
1063
|
-
</picture>
|
|
1230
|
+
<img src="/images/chat-iPhone.webp" alt="AgentLink mobile interface on iPhone" loading="eager">
|
|
1064
1231
|
</div>
|
|
1065
1232
|
</section>
|
|
1066
1233
|
|
|
1067
1234
|
<div class="section-divider"></div>
|
|
1068
1235
|
|
|
1069
1236
|
<!-- Philosophy -->
|
|
1070
|
-
<section class="philosophy
|
|
1237
|
+
<section class="philosophy">
|
|
1071
1238
|
<div class="philosophy-label">Philosophy</div>
|
|
1072
1239
|
<h2>Code shouldn't be <em>chained to a desk.</em></h2>
|
|
1073
1240
|
<p>
|
|
1074
1241
|
AgentLink turns Claude Code into a truly portable experience.
|
|
1075
|
-
One command, one URL —
|
|
1076
|
-
|
|
1242
|
+
One command, one URL — chat interactively, spin up agent teams,
|
|
1243
|
+
or schedule recurring tasks, all from any device.
|
|
1244
|
+
Real encryption, zero accounts required.
|
|
1077
1245
|
</p>
|
|
1078
1246
|
</section>
|
|
1079
1247
|
|
|
1080
1248
|
<div class="section-divider"></div>
|
|
1081
1249
|
|
|
1082
1250
|
<!-- Bento Features -->
|
|
1083
|
-
<section class="bento
|
|
1251
|
+
<section class="bento" id="features">
|
|
1084
1252
|
<h2 class="sr-only">Features</h2>
|
|
1085
1253
|
|
|
1086
|
-
<!--
|
|
1254
|
+
<!-- Row 1: Chat | Team | Loop (wide) + Any Device -->
|
|
1255
|
+
<div class="bento-card wide">
|
|
1256
|
+
<div class="bento-visual">
|
|
1257
|
+
<div class="mode-toggle">
|
|
1258
|
+
<div class="mode-toggle-item active">
|
|
1259
|
+
<div class="mode-icon chat-icon">
|
|
1260
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
|
|
1261
|
+
</div>
|
|
1262
|
+
<div class="mode-name">Chat</div>
|
|
1263
|
+
<div class="mode-desc">Interactive coding sessions</div>
|
|
1264
|
+
</div>
|
|
1265
|
+
<div class="mode-toggle-item">
|
|
1266
|
+
<div class="mode-icon team-icon">
|
|
1267
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
|
|
1268
|
+
</div>
|
|
1269
|
+
<div class="mode-name">Team</div>
|
|
1270
|
+
<div class="mode-desc">Parallel sub-agents</div>
|
|
1271
|
+
</div>
|
|
1272
|
+
<div class="mode-toggle-item">
|
|
1273
|
+
<div class="mode-icon loop-icon">
|
|
1274
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path></svg>
|
|
1275
|
+
</div>
|
|
1276
|
+
<div class="mode-name">Loop</div>
|
|
1277
|
+
<div class="mode-desc">Scheduled cron tasks</div>
|
|
1278
|
+
</div>
|
|
1279
|
+
</div>
|
|
1280
|
+
</div>
|
|
1281
|
+
<h3>Three Modes, One Interface</h3>
|
|
1282
|
+
<p>Chat with Claude interactively, spawn agent teams for complex tasks, or schedule recurring Loop jobs with cron — all from the same browser tab.</p>
|
|
1283
|
+
</div>
|
|
1284
|
+
|
|
1285
|
+
<div class="bento-card">
|
|
1286
|
+
<div class="bento-visual">
|
|
1287
|
+
<div class="bento-icon cyan">
|
|
1288
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect><line x1="12" y1="18" x2="12.01" y2="18"></line></svg>
|
|
1289
|
+
</div>
|
|
1290
|
+
</div>
|
|
1291
|
+
<h3>Any Device</h3>
|
|
1292
|
+
<p>Phone, tablet, laptop — any browser becomes your Claude Code terminal.</p>
|
|
1293
|
+
</div>
|
|
1294
|
+
|
|
1295
|
+
<!-- Row 2: E2E Encryption (wide) + Self-Hostable -->
|
|
1087
1296
|
<div class="bento-card wide">
|
|
1088
1297
|
<div class="bento-visual">
|
|
1089
1298
|
<div class="encrypt-visual">
|
|
@@ -1098,18 +1307,17 @@
|
|
|
1098
1307
|
<p>XSalsa20-Poly1305 encryption. The relay server is a blind forwarder — it never sees your code, your prompts, or your data.</p>
|
|
1099
1308
|
</div>
|
|
1100
1309
|
|
|
1101
|
-
<!-- Zero Config -->
|
|
1102
1310
|
<div class="bento-card">
|
|
1103
1311
|
<div class="bento-visual">
|
|
1104
|
-
<div class="bento-icon
|
|
1105
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><
|
|
1312
|
+
<div class="bento-icon green">
|
|
1313
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6.01" y2="6"></line><line x1="6" y1="18" x2="6.01" y2="18"></line></svg>
|
|
1106
1314
|
</div>
|
|
1107
1315
|
</div>
|
|
1108
|
-
<h3>
|
|
1109
|
-
<p>
|
|
1316
|
+
<h3>Self-Hostable</h3>
|
|
1317
|
+
<p>Run your own relay server. Your infrastructure, your rules, your data.</p>
|
|
1110
1318
|
</div>
|
|
1111
1319
|
|
|
1112
|
-
<!-- Multi-Agent Teams -->
|
|
1320
|
+
<!-- Row 3: Multi-Agent Teams + Multi Session + Zero Config -->
|
|
1113
1321
|
<div class="bento-card">
|
|
1114
1322
|
<div class="bento-visual">
|
|
1115
1323
|
<div class="bento-icon blue">
|
|
@@ -1120,7 +1328,6 @@
|
|
|
1120
1328
|
<p>Spawn parallel Claude subagents to tackle complex tasks. Live kanban board, activity feed, and team history.</p>
|
|
1121
1329
|
</div>
|
|
1122
1330
|
|
|
1123
|
-
<!-- Multi Session -->
|
|
1124
1331
|
<div class="bento-card">
|
|
1125
1332
|
<div class="bento-visual">
|
|
1126
1333
|
<div class="bento-icon blue">
|
|
@@ -1131,84 +1338,21 @@
|
|
|
1131
1338
|
<p>Run multiple conversations in parallel. Switch between tasks without losing context.</p>
|
|
1132
1339
|
</div>
|
|
1133
1340
|
|
|
1134
|
-
<!-- Any Device -->
|
|
1135
|
-
<div class="bento-card">
|
|
1136
|
-
<div class="bento-visual">
|
|
1137
|
-
<div class="bento-icon cyan">
|
|
1138
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect><line x1="12" y1="18" x2="12.01" y2="18"></line></svg>
|
|
1139
|
-
</div>
|
|
1140
|
-
</div>
|
|
1141
|
-
<h3>Any Device</h3>
|
|
1142
|
-
<p>Phone, tablet, laptop — any browser becomes your Claude Code terminal.</p>
|
|
1143
|
-
</div>
|
|
1144
|
-
|
|
1145
|
-
<!-- Full Claude Code — wide -->
|
|
1146
|
-
<div class="bento-card wide">
|
|
1147
|
-
<div class="bento-visual">
|
|
1148
|
-
<div class="device-flow">
|
|
1149
|
-
<div class="device-pill">
|
|
1150
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line></svg>
|
|
1151
|
-
Terminal
|
|
1152
|
-
</div>
|
|
1153
|
-
<div class="flow-line"></div>
|
|
1154
|
-
<div class="device-pill">
|
|
1155
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path><polyline points="14 2 14 8 20 8"></polyline></svg>
|
|
1156
|
-
Files
|
|
1157
|
-
</div>
|
|
1158
|
-
<div class="flow-line"></div>
|
|
1159
|
-
<div class="device-pill">
|
|
1160
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
|
|
1161
|
-
Search
|
|
1162
|
-
</div>
|
|
1163
|
-
<div class="flow-line"></div>
|
|
1164
|
-
<div class="device-pill">
|
|
1165
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
|
|
1166
|
-
Chat
|
|
1167
|
-
</div>
|
|
1168
|
-
</div>
|
|
1169
|
-
</div>
|
|
1170
|
-
<h3>Full Claude Code Experience</h3>
|
|
1171
|
-
<p>File editing, shell commands, search, multi-turn conversations — every capability, now in your browser.</p>
|
|
1172
|
-
</div>
|
|
1173
|
-
|
|
1174
|
-
<!-- Self-hostable -->
|
|
1175
|
-
<div class="bento-card">
|
|
1176
|
-
<div class="bento-visual">
|
|
1177
|
-
<div class="bento-icon green">
|
|
1178
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6.01" y2="6"></line><line x1="6" y1="18" x2="6.01" y2="18"></line></svg>
|
|
1179
|
-
</div>
|
|
1180
|
-
</div>
|
|
1181
|
-
<h3>Self-Hostable</h3>
|
|
1182
|
-
<p>Run your own relay server. Your infrastructure, your rules, your data.</p>
|
|
1183
|
-
</div>
|
|
1184
|
-
|
|
1185
|
-
<!-- Password Protection -->
|
|
1186
1341
|
<div class="bento-card">
|
|
1187
1342
|
<div class="bento-visual">
|
|
1188
|
-
<div class="bento-icon
|
|
1189
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><
|
|
1190
|
-
</div>
|
|
1191
|
-
</div>
|
|
1192
|
-
<h3>Optional Password</h3>
|
|
1193
|
-
<p>Add <code style="color:var(--green);font-family:'JetBrains Mono',monospace;font-size:0.8rem">--password</code> to lock your session. Brute-force protection built in.</p>
|
|
1194
|
-
</div>
|
|
1195
|
-
|
|
1196
|
-
<!-- File Preview -->
|
|
1197
|
-
<div class="bento-card wide">
|
|
1198
|
-
<div class="bento-visual">
|
|
1199
|
-
<div class="bento-icon rose">
|
|
1200
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path><line x1="12" y1="11" x2="12" y2="17"></line><line x1="9" y1="14" x2="15" y2="14"></line></svg>
|
|
1343
|
+
<div class="bento-icon purple">
|
|
1344
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg>
|
|
1201
1345
|
</div>
|
|
1202
1346
|
</div>
|
|
1203
|
-
<h3>
|
|
1204
|
-
<p>
|
|
1347
|
+
<h3>Zero Config</h3>
|
|
1348
|
+
<p>No accounts. No registration. Install, start, open — done.</p>
|
|
1205
1349
|
</div>
|
|
1206
1350
|
</section>
|
|
1207
1351
|
|
|
1208
1352
|
<div class="section-divider"></div>
|
|
1209
1353
|
|
|
1210
1354
|
<!-- How It Works -->
|
|
1211
|
-
<section class="workflow
|
|
1355
|
+
<section class="workflow" id="how-it-works">
|
|
1212
1356
|
<div class="workflow-label">How It Works</div>
|
|
1213
1357
|
<h2>Three steps. That's it.</h2>
|
|
1214
1358
|
<div class="workflow-steps">
|
|
@@ -1229,8 +1373,8 @@
|
|
|
1229
1373
|
<div class="workflow-step">
|
|
1230
1374
|
<div class="step-marker">03</div>
|
|
1231
1375
|
<div class="step-content">
|
|
1232
|
-
<h3>
|
|
1233
|
-
<p>
|
|
1376
|
+
<h3>Chat, collaborate, automate</h3>
|
|
1377
|
+
<p>Run interactive sessions, spawn agent teams for complex tasks, or set up scheduled Loop jobs — all from the same URL, with full history preserved.</p>
|
|
1234
1378
|
</div>
|
|
1235
1379
|
</div>
|
|
1236
1380
|
</div>
|
|
@@ -1268,16 +1412,79 @@ function showToast() {
|
|
|
1268
1412
|
setTimeout(() => toast.classList.remove('show'), 1800);
|
|
1269
1413
|
}
|
|
1270
1414
|
|
|
1271
|
-
//
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1415
|
+
// iPad carousel
|
|
1416
|
+
(function() {
|
|
1417
|
+
const slides = document.querySelectorAll('.carousel-slide');
|
|
1418
|
+
const dots = document.querySelectorAll('.carousel-dot');
|
|
1419
|
+
if (!slides.length) return;
|
|
1420
|
+
let current = 0;
|
|
1421
|
+
let interval;
|
|
1422
|
+
|
|
1423
|
+
function goTo(i) {
|
|
1424
|
+
slides[current].classList.remove('active');
|
|
1425
|
+
dots[current].classList.remove('active');
|
|
1426
|
+
current = (i + slides.length) % slides.length;
|
|
1427
|
+
slides[current].classList.add('active');
|
|
1428
|
+
dots[current].classList.add('active');
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
function startAuto() {
|
|
1432
|
+
interval = setInterval(() => goTo(current + 1), 4000);
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
function resetAuto() {
|
|
1436
|
+
clearInterval(interval);
|
|
1437
|
+
startAuto();
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
dots.forEach(dot => {
|
|
1441
|
+
dot.addEventListener('click', () => {
|
|
1442
|
+
goTo(Number(dot.dataset.index));
|
|
1443
|
+
resetAuto();
|
|
1444
|
+
});
|
|
1445
|
+
});
|
|
1446
|
+
|
|
1447
|
+
// Touch/swipe support
|
|
1448
|
+
const track = document.querySelector('.ipad-carousel');
|
|
1449
|
+
let startX = 0, startY = 0, dragging = false;
|
|
1450
|
+
|
|
1451
|
+
track.addEventListener('touchstart', e => {
|
|
1452
|
+
startX = e.touches[0].clientX;
|
|
1453
|
+
startY = e.touches[0].clientY;
|
|
1454
|
+
dragging = true;
|
|
1455
|
+
}, { passive: true });
|
|
1456
|
+
|
|
1457
|
+
track.addEventListener('touchend', e => {
|
|
1458
|
+
if (!dragging) return;
|
|
1459
|
+
dragging = false;
|
|
1460
|
+
const dx = e.changedTouches[0].clientX - startX;
|
|
1461
|
+
const dy = e.changedTouches[0].clientY - startY;
|
|
1462
|
+
if (Math.abs(dx) > 50 && Math.abs(dx) > Math.abs(dy)) {
|
|
1463
|
+
goTo(dx < 0 ? current + 1 : current - 1);
|
|
1464
|
+
resetAuto();
|
|
1465
|
+
}
|
|
1466
|
+
}, { passive: true });
|
|
1467
|
+
|
|
1468
|
+
// Mouse drag support for desktop
|
|
1469
|
+
track.addEventListener('mousedown', e => {
|
|
1470
|
+
startX = e.clientX;
|
|
1471
|
+
dragging = true;
|
|
1472
|
+
track.style.cursor = 'grabbing';
|
|
1473
|
+
});
|
|
1474
|
+
|
|
1475
|
+
document.addEventListener('mouseup', e => {
|
|
1476
|
+
if (!dragging) return;
|
|
1477
|
+
dragging = false;
|
|
1478
|
+
track.style.cursor = '';
|
|
1479
|
+
const dx = e.clientX - startX;
|
|
1480
|
+
if (Math.abs(dx) > 50) {
|
|
1481
|
+
goTo(dx < 0 ? current + 1 : current - 1);
|
|
1482
|
+
resetAuto();
|
|
1276
1483
|
}
|
|
1277
1484
|
});
|
|
1278
|
-
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
|
|
1279
1485
|
|
|
1280
|
-
|
|
1486
|
+
startAuto();
|
|
1487
|
+
})();
|
|
1281
1488
|
</script>
|
|
1282
1489
|
|
|
1283
1490
|
</body>
|
package/web/landing.zh.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>AgentLink — Claude Code 开源版远程控制</title>
|
|
7
|
-
<meta name="description" content="Claude Code
|
|
8
|
-
<meta name="keywords" content="Claude Code, Claude Code开源版远程控制, 远程控制, 浏览器 IDE, AI 编程助手, AgentLink, 端到端加密, 自建部署,
|
|
7
|
+
<meta name="description" content="Claude Code 开源版远程控制。对话、多 Agent 协作、定时任务三大模式,手机或任何浏览器即可操控,端到端加密,无需注册。">
|
|
8
|
+
<meta name="keywords" content="Claude Code, Claude Code开源版远程控制, 远程控制, 浏览器 IDE, AI 编程助手, AgentLink, 端到端加密, 自建部署, 移动编程, 多Agent协作, 定时任务">
|
|
9
9
|
<link rel="canonical" href="https://msclaude.ai/zh">
|
|
10
10
|
<link rel="alternate" hreflang="en" href="https://msclaude.ai/">
|
|
11
11
|
<link rel="alternate" hreflang="zh" href="https://msclaude.ai/zh">
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<!-- Open Graph -->
|
|
14
14
|
<meta property="og:type" content="website">
|
|
15
15
|
<meta property="og:title" content="AgentLink — Claude Code 开源版远程控制">
|
|
16
|
-
<meta property="og:description" content="Claude Code
|
|
16
|
+
<meta property="og:description" content="Claude Code 开源版远程控制。对话、多 Agent 协作、定时任务三大模式,手机或任何浏览器即可操控,端到端加密,无需注册。">
|
|
17
17
|
<meta property="og:url" content="https://msclaude.ai/zh">
|
|
18
18
|
<meta property="og:image" content="https://msclaude.ai/iPad.png">
|
|
19
19
|
<meta property="og:site_name" content="AgentLink">
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<!-- Twitter Card -->
|
|
23
23
|
<meta name="twitter:card" content="summary_large_image">
|
|
24
24
|
<meta name="twitter:title" content="AgentLink — Claude Code 开源版远程控制">
|
|
25
|
-
<meta name="twitter:description" content="Claude Code
|
|
25
|
+
<meta name="twitter:description" content="Claude Code 开源版远程控制。对话、多 Agent 协作、定时任务三大模式,手机或任何浏览器即可操控,端到端加密,无需注册。">
|
|
26
26
|
<meta name="twitter:image" content="https://msclaude.ai/iPad.png">
|
|
27
27
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
28
28
|
<script type="application/ld+json">
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@context": "https://schema.org",
|
|
31
31
|
"@type": "SoftwareApplication",
|
|
32
32
|
"name": "AgentLink",
|
|
33
|
-
"description": "Claude Code
|
|
33
|
+
"description": "Claude Code 开源版远程控制。对话、多 Agent 协作、定时任务三大模式,手机或任何浏览器即可操控,端到端加密,无需注册。",
|
|
34
34
|
"url": "https://msclaude.ai/zh",
|
|
35
35
|
"applicationCategory": "DeveloperApplication",
|
|
36
36
|
"operatingSystem": "Windows, macOS, Linux",
|
|
@@ -537,11 +537,8 @@
|
|
|
537
537
|
}
|
|
538
538
|
|
|
539
539
|
.device-ipad img {
|
|
540
|
-
border-radius:
|
|
541
|
-
box-shadow:
|
|
542
|
-
0 40px 100px rgba(0,0,0,0.5),
|
|
543
|
-
0 15px 50px rgba(0,0,0,0.3),
|
|
544
|
-
0 0 80px rgba(59,130,246,0.08);
|
|
540
|
+
border-radius: 0;
|
|
541
|
+
box-shadow: none;
|
|
545
542
|
}
|
|
546
543
|
|
|
547
544
|
.device-iphone {
|
|
@@ -564,6 +561,106 @@
|
|
|
564
561
|
0 0 80px rgba(245,158,11,0.08);
|
|
565
562
|
}
|
|
566
563
|
|
|
564
|
+
/* ── iPad Carousel ── */
|
|
565
|
+
.ipad-carousel {
|
|
566
|
+
position: relative;
|
|
567
|
+
width: 100%;
|
|
568
|
+
overflow: hidden;
|
|
569
|
+
border-radius: 4.2%;
|
|
570
|
+
box-shadow:
|
|
571
|
+
0 40px 100px rgba(0,0,0,0.5),
|
|
572
|
+
0 15px 50px rgba(0,0,0,0.3),
|
|
573
|
+
0 0 80px rgba(59,130,246,0.08);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
.carousel-track {
|
|
577
|
+
position: relative;
|
|
578
|
+
width: 100%;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
.carousel-slide {
|
|
582
|
+
position: absolute;
|
|
583
|
+
top: 0;
|
|
584
|
+
left: 0;
|
|
585
|
+
width: 100%;
|
|
586
|
+
opacity: 0;
|
|
587
|
+
transition: opacity 0.6s ease;
|
|
588
|
+
pointer-events: none;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
.carousel-slide.active {
|
|
592
|
+
position: relative;
|
|
593
|
+
opacity: 1;
|
|
594
|
+
pointer-events: auto;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.carousel-slide img {
|
|
598
|
+
display: block;
|
|
599
|
+
width: 100%;
|
|
600
|
+
height: auto;
|
|
601
|
+
border-radius: 0;
|
|
602
|
+
box-shadow: none;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
.carousel-dots {
|
|
606
|
+
position: absolute;
|
|
607
|
+
bottom: 12px;
|
|
608
|
+
left: 50%;
|
|
609
|
+
transform: translateX(-50%);
|
|
610
|
+
display: flex;
|
|
611
|
+
gap: 8px;
|
|
612
|
+
z-index: 5;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
.carousel-dot {
|
|
616
|
+
width: 8px;
|
|
617
|
+
height: 8px;
|
|
618
|
+
border-radius: 50%;
|
|
619
|
+
border: none;
|
|
620
|
+
background: rgba(255,255,255,0.4);
|
|
621
|
+
cursor: pointer;
|
|
622
|
+
padding: 0;
|
|
623
|
+
transition: background 0.3s ease, transform 0.3s ease;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.carousel-dot.active {
|
|
627
|
+
background: rgba(255,255,255,0.9);
|
|
628
|
+
transform: scale(1.2);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
.carousel-dot:hover {
|
|
632
|
+
background: rgba(255,255,255,0.7);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
.carousel-label {
|
|
636
|
+
position: absolute;
|
|
637
|
+
top: 16px;
|
|
638
|
+
left: 16px;
|
|
639
|
+
display: flex;
|
|
640
|
+
flex-direction: column;
|
|
641
|
+
gap: 2px;
|
|
642
|
+
background: rgba(0,0,0,0.55);
|
|
643
|
+
backdrop-filter: blur(12px);
|
|
644
|
+
-webkit-backdrop-filter: blur(12px);
|
|
645
|
+
padding: 8px 14px;
|
|
646
|
+
border-radius: 10px;
|
|
647
|
+
z-index: 4;
|
|
648
|
+
pointer-events: none;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
.carousel-label-title {
|
|
652
|
+
font-size: 0.95rem;
|
|
653
|
+
font-weight: 700;
|
|
654
|
+
color: #fff;
|
|
655
|
+
letter-spacing: 0.02em;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
.carousel-label-desc {
|
|
659
|
+
font-size: 0.72rem;
|
|
660
|
+
color: rgba(255,255,255,0.75);
|
|
661
|
+
font-weight: 400;
|
|
662
|
+
}
|
|
663
|
+
|
|
567
664
|
/* ── Divider ── */
|
|
568
665
|
.section-divider {
|
|
569
666
|
max-width: 200px;
|
|
@@ -669,6 +766,60 @@
|
|
|
669
766
|
.bento-icon.amber { background: linear-gradient(135deg, rgba(245,158,11,0.2), rgba(245,158,11,0.05)); color: var(--amber); }
|
|
670
767
|
.bento-icon.blue { background: linear-gradient(135deg, rgba(96,165,250,0.2), rgba(96,165,250,0.05)); color: var(--blue); }
|
|
671
768
|
|
|
769
|
+
/* Mode toggle visual */
|
|
770
|
+
.mode-toggle {
|
|
771
|
+
display: flex;
|
|
772
|
+
gap: 0;
|
|
773
|
+
background: rgba(255,255,255,0.04);
|
|
774
|
+
border: 1px solid var(--border);
|
|
775
|
+
border-radius: 12px;
|
|
776
|
+
overflow: hidden;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
.mode-toggle-item {
|
|
780
|
+
flex: 1;
|
|
781
|
+
text-align: center;
|
|
782
|
+
padding: 0.7rem 1rem;
|
|
783
|
+
position: relative;
|
|
784
|
+
transition: all 0.3s;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
.mode-toggle-item:not(:last-child) {
|
|
788
|
+
border-right: 1px solid var(--border);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
.mode-toggle-item.active {
|
|
792
|
+
background: rgba(59,130,246,0.12);
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
.mode-toggle-item .mode-icon {
|
|
796
|
+
width: 32px; height: 32px;
|
|
797
|
+
margin: 0 auto 0.4rem;
|
|
798
|
+
border-radius: 8px;
|
|
799
|
+
display: flex;
|
|
800
|
+
align-items: center;
|
|
801
|
+
justify-content: center;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
.mode-toggle-item .mode-icon svg { width: 18px; height: 18px; }
|
|
805
|
+
|
|
806
|
+
.mode-toggle-item .mode-icon.chat-icon { background: rgba(59,130,246,0.15); color: var(--accent); }
|
|
807
|
+
.mode-toggle-item .mode-icon.team-icon { background: rgba(96,165,250,0.15); color: var(--blue); }
|
|
808
|
+
.mode-toggle-item .mode-icon.loop-icon { background: rgba(52,211,153,0.15); color: var(--green); }
|
|
809
|
+
|
|
810
|
+
.mode-toggle-item .mode-name {
|
|
811
|
+
font-size: 0.8rem;
|
|
812
|
+
font-weight: 600;
|
|
813
|
+
margin-bottom: 0.2rem;
|
|
814
|
+
color: var(--text);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
.mode-toggle-item .mode-desc {
|
|
818
|
+
font-size: 0.68rem;
|
|
819
|
+
color: var(--text-dim);
|
|
820
|
+
line-height: 1.4;
|
|
821
|
+
}
|
|
822
|
+
|
|
672
823
|
/* Encryption visual */
|
|
673
824
|
.encrypt-visual {
|
|
674
825
|
display: flex;
|
|
@@ -927,6 +1078,11 @@
|
|
|
927
1078
|
align-self: auto;
|
|
928
1079
|
}
|
|
929
1080
|
.device-iphone:hover { transform: translateY(-3%); }
|
|
1081
|
+
.carousel-dots { bottom: 8px; gap: 6px; }
|
|
1082
|
+
.carousel-dot { width: 6px; height: 6px; }
|
|
1083
|
+
.carousel-label { top: 8px; left: 8px; padding: 5px 10px; border-radius: 8px; }
|
|
1084
|
+
.carousel-label-title { font-size: 0.8rem; }
|
|
1085
|
+
.carousel-label-desc { font-size: 0.62rem; }
|
|
930
1086
|
.terminal { margin: 0 1rem; max-width: calc(100vw - 2rem); }
|
|
931
1087
|
.terminal-body { padding: 1rem; font-size: 0.75rem; overflow-x: auto; }
|
|
932
1088
|
.terminal-line { gap: 0.4rem; white-space: nowrap; }
|
|
@@ -943,18 +1099,6 @@
|
|
|
943
1099
|
.workflow-steps::before { left: 19px; }
|
|
944
1100
|
}
|
|
945
1101
|
|
|
946
|
-
/* ── Scroll animations ── */
|
|
947
|
-
.reveal {
|
|
948
|
-
opacity: 0;
|
|
949
|
-
transform: translateY(30px);
|
|
950
|
-
transition: opacity 0.8s ease, transform 0.8s ease;
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
.reveal.visible {
|
|
954
|
-
opacity: 1;
|
|
955
|
-
transform: translateY(0);
|
|
956
|
-
}
|
|
957
|
-
|
|
958
1102
|
.sr-only {
|
|
959
1103
|
position: absolute;
|
|
960
1104
|
width: 1px; height: 1px;
|
|
@@ -1010,7 +1154,7 @@
|
|
|
1010
1154
|
<span class="line"><em>开源版远程控制。</em></span>
|
|
1011
1155
|
</h1>
|
|
1012
1156
|
<p class="hero-sub">
|
|
1013
|
-
在开发机器上启动 Agent,出门遛弯期间用<strong
|
|
1157
|
+
在开发机器上启动 Agent,出门遛弯期间用<strong>手机对话、组建 Agent 团队、或跑定时任务</strong> —
|
|
1014
1158
|
不用装 App,不用注册账号,打开浏览器就能用。
|
|
1015
1159
|
</p>
|
|
1016
1160
|
<div class="cta-group">
|
|
@@ -1049,40 +1193,104 @@
|
|
|
1049
1193
|
</section>
|
|
1050
1194
|
|
|
1051
1195
|
<!-- Device Showcase -->
|
|
1052
|
-
<section class="showcase
|
|
1196
|
+
<section class="showcase">
|
|
1053
1197
|
<div class="device device-ipad">
|
|
1054
|
-
<
|
|
1055
|
-
<
|
|
1056
|
-
|
|
1057
|
-
|
|
1198
|
+
<div class="ipad-carousel">
|
|
1199
|
+
<div class="carousel-track">
|
|
1200
|
+
<div class="carousel-slide active">
|
|
1201
|
+
<img src="/images/chat-iPad.webp" alt="AgentLink 聊天模式 iPad 界面" loading="eager">
|
|
1202
|
+
<div class="carousel-label">
|
|
1203
|
+
<span class="carousel-label-title">Chat</span>
|
|
1204
|
+
<span class="carousel-label-desc">远程与 Claude Code 结对编程</span>
|
|
1205
|
+
</div>
|
|
1206
|
+
</div>
|
|
1207
|
+
<div class="carousel-slide">
|
|
1208
|
+
<img src="/images/team-iPad.webp" alt="AgentLink 团队模式 iPad 界面" loading="eager">
|
|
1209
|
+
<div class="carousel-label">
|
|
1210
|
+
<span class="carousel-label-title">Teams</span>
|
|
1211
|
+
<span class="carousel-label-desc">并行编排多个 Agent 协同工作</span>
|
|
1212
|
+
</div>
|
|
1213
|
+
</div>
|
|
1214
|
+
<div class="carousel-slide">
|
|
1215
|
+
<img src="/images/loop-iPad.webp" alt="AgentLink 循环模式 iPad 界面" loading="eager">
|
|
1216
|
+
<div class="carousel-label">
|
|
1217
|
+
<span class="carousel-label-title">Loop</span>
|
|
1218
|
+
<span class="carousel-label-desc">通过 Cron 定时调度自动化任务</span>
|
|
1219
|
+
</div>
|
|
1220
|
+
</div>
|
|
1221
|
+
</div>
|
|
1222
|
+
<div class="carousel-dots">
|
|
1223
|
+
<button class="carousel-dot active" data-index="0" aria-label="聊天模式"></button>
|
|
1224
|
+
<button class="carousel-dot" data-index="1" aria-label="团队模式"></button>
|
|
1225
|
+
<button class="carousel-dot" data-index="2" aria-label="循环模式"></button>
|
|
1226
|
+
</div>
|
|
1227
|
+
</div>
|
|
1058
1228
|
</div>
|
|
1059
1229
|
<div class="device device-iphone">
|
|
1060
|
-
<
|
|
1061
|
-
<source srcset="/iPhone.webp" type="image/webp">
|
|
1062
|
-
<img src="/iPhone.png" alt="AgentLink 手机端界面" loading="eager">
|
|
1063
|
-
</picture>
|
|
1230
|
+
<img src="/images/chat-iPhone.webp" alt="AgentLink 手机端界面" loading="eager">
|
|
1064
1231
|
</div>
|
|
1065
1232
|
</section>
|
|
1066
1233
|
|
|
1067
1234
|
<div class="section-divider"></div>
|
|
1068
1235
|
|
|
1069
1236
|
<!-- Philosophy -->
|
|
1070
|
-
<section class="philosophy
|
|
1237
|
+
<section class="philosophy">
|
|
1071
1238
|
<div class="philosophy-label">为什么做这个</div>
|
|
1072
1239
|
<h2>写代码不应该<em>被绑在电脑前。</em></h2>
|
|
1073
1240
|
<p>
|
|
1074
1241
|
Claude Code 很强,但只能在终端里用。AgentLink 把它变成一个可以随身携带的体验 —
|
|
1075
|
-
|
|
1242
|
+
一行命令,一个链接,在手机上对话、启动 Agent 团队、或调度定时任务。不需要账号,不需要配置,端到端加密。
|
|
1076
1243
|
</p>
|
|
1077
1244
|
</section>
|
|
1078
1245
|
|
|
1079
1246
|
<div class="section-divider"></div>
|
|
1080
1247
|
|
|
1081
1248
|
<!-- Bento Features -->
|
|
1082
|
-
<section class="bento
|
|
1249
|
+
<section class="bento" id="features">
|
|
1083
1250
|
<h2 class="sr-only">功能</h2>
|
|
1084
1251
|
|
|
1085
|
-
<!--
|
|
1252
|
+
<!-- Row 1: Chat | Team | Loop (wide) + Any Device -->
|
|
1253
|
+
<div class="bento-card wide">
|
|
1254
|
+
<div class="bento-visual">
|
|
1255
|
+
<div class="mode-toggle">
|
|
1256
|
+
<div class="mode-toggle-item active">
|
|
1257
|
+
<div class="mode-icon chat-icon">
|
|
1258
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
|
|
1259
|
+
</div>
|
|
1260
|
+
<div class="mode-name">Chat</div>
|
|
1261
|
+
<div class="mode-desc">交互式编程对话</div>
|
|
1262
|
+
</div>
|
|
1263
|
+
<div class="mode-toggle-item">
|
|
1264
|
+
<div class="mode-icon team-icon">
|
|
1265
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
|
|
1266
|
+
</div>
|
|
1267
|
+
<div class="mode-name">Team</div>
|
|
1268
|
+
<div class="mode-desc">并行子 Agent 协作</div>
|
|
1269
|
+
</div>
|
|
1270
|
+
<div class="mode-toggle-item">
|
|
1271
|
+
<div class="mode-icon loop-icon">
|
|
1272
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path></svg>
|
|
1273
|
+
</div>
|
|
1274
|
+
<div class="mode-name">Loop</div>
|
|
1275
|
+
<div class="mode-desc">定时 Cron 任务</div>
|
|
1276
|
+
</div>
|
|
1277
|
+
</div>
|
|
1278
|
+
</div>
|
|
1279
|
+
<h3>三大模式,一个界面</h3>
|
|
1280
|
+
<p>和 Claude 交互对话、启动 Agent 团队处理复杂任务、或用 Cron 调度定时 Loop 任务 — 全在同一个浏览器标签页里。</p>
|
|
1281
|
+
</div>
|
|
1282
|
+
|
|
1283
|
+
<div class="bento-card">
|
|
1284
|
+
<div class="bento-visual">
|
|
1285
|
+
<div class="bento-icon cyan">
|
|
1286
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect><line x1="12" y1="18" x2="12.01" y2="18"></line></svg>
|
|
1287
|
+
</div>
|
|
1288
|
+
</div>
|
|
1289
|
+
<h3>任何设备</h3>
|
|
1290
|
+
<p>手机、平板、笔记本 — 有浏览器就行,随时切到你的 Claude。</p>
|
|
1291
|
+
</div>
|
|
1292
|
+
|
|
1293
|
+
<!-- Row 2: E2E Encryption (wide) + Self-Hostable -->
|
|
1086
1294
|
<div class="bento-card wide">
|
|
1087
1295
|
<div class="bento-visual">
|
|
1088
1296
|
<div class="encrypt-visual">
|
|
@@ -1097,18 +1305,17 @@
|
|
|
1097
1305
|
<p>XSalsa20-Poly1305 加密。中继服务器只是个盲转发器 — 看不到你的代码、提示词或任何数据。</p>
|
|
1098
1306
|
</div>
|
|
1099
1307
|
|
|
1100
|
-
<!-- Zero Config -->
|
|
1101
1308
|
<div class="bento-card">
|
|
1102
1309
|
<div class="bento-visual">
|
|
1103
|
-
<div class="bento-icon
|
|
1104
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><
|
|
1310
|
+
<div class="bento-icon green">
|
|
1311
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6.01" y2="6"></line><line x1="6" y1="18" x2="6.01" y2="18"></line></svg>
|
|
1105
1312
|
</div>
|
|
1106
1313
|
</div>
|
|
1107
|
-
<h3
|
|
1108
|
-
<p
|
|
1314
|
+
<h3>可自建部署</h3>
|
|
1315
|
+
<p>一条命令启动你自己的中继服务器。你的基础设施,你的规则。</p>
|
|
1109
1316
|
</div>
|
|
1110
1317
|
|
|
1111
|
-
<!--
|
|
1318
|
+
<!-- Row 3: Multi-Agent Teams + Multi Session + Zero Config -->
|
|
1112
1319
|
<div class="bento-card">
|
|
1113
1320
|
<div class="bento-visual">
|
|
1114
1321
|
<div class="bento-icon blue">
|
|
@@ -1119,7 +1326,6 @@
|
|
|
1119
1326
|
<p>启动多个 Claude 子 Agent 并行处理复杂任务,实时看板面板、活动动态、团队历史记录。</p>
|
|
1120
1327
|
</div>
|
|
1121
1328
|
|
|
1122
|
-
<!-- Multi Session -->
|
|
1123
1329
|
<div class="bento-card">
|
|
1124
1330
|
<div class="bento-visual">
|
|
1125
1331
|
<div class="bento-icon blue">
|
|
@@ -1130,84 +1336,21 @@
|
|
|
1130
1336
|
<p>同时跑多个对话,自由切换,互不干扰。</p>
|
|
1131
1337
|
</div>
|
|
1132
1338
|
|
|
1133
|
-
<!-- Any Device -->
|
|
1134
|
-
<div class="bento-card">
|
|
1135
|
-
<div class="bento-visual">
|
|
1136
|
-
<div class="bento-icon cyan">
|
|
1137
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect><line x1="12" y1="18" x2="12.01" y2="18"></line></svg>
|
|
1138
|
-
</div>
|
|
1139
|
-
</div>
|
|
1140
|
-
<h3>任何设备</h3>
|
|
1141
|
-
<p>手机、平板、笔记本 — 有浏览器就行,随时切到你的 Claude。</p>
|
|
1142
|
-
</div>
|
|
1143
|
-
|
|
1144
|
-
<!-- Full Claude Code — wide -->
|
|
1145
|
-
<div class="bento-card wide">
|
|
1146
|
-
<div class="bento-visual">
|
|
1147
|
-
<div class="device-flow">
|
|
1148
|
-
<div class="device-pill">
|
|
1149
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line></svg>
|
|
1150
|
-
终端
|
|
1151
|
-
</div>
|
|
1152
|
-
<div class="flow-line"></div>
|
|
1153
|
-
<div class="device-pill">
|
|
1154
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path><polyline points="14 2 14 8 20 8"></polyline></svg>
|
|
1155
|
-
文件
|
|
1156
|
-
</div>
|
|
1157
|
-
<div class="flow-line"></div>
|
|
1158
|
-
<div class="device-pill">
|
|
1159
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
|
|
1160
|
-
搜索
|
|
1161
|
-
</div>
|
|
1162
|
-
<div class="flow-line"></div>
|
|
1163
|
-
<div class="device-pill">
|
|
1164
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
|
|
1165
|
-
对话
|
|
1166
|
-
</div>
|
|
1167
|
-
</div>
|
|
1168
|
-
</div>
|
|
1169
|
-
<h3>完整的 Claude Code 体验</h3>
|
|
1170
|
-
<p>文件编辑、Shell 命令、代码搜索、多轮对话 — 所有能力,现在搬到了浏览器里。</p>
|
|
1171
|
-
</div>
|
|
1172
|
-
|
|
1173
|
-
<!-- Self-hostable -->
|
|
1174
|
-
<div class="bento-card">
|
|
1175
|
-
<div class="bento-visual">
|
|
1176
|
-
<div class="bento-icon green">
|
|
1177
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6.01" y2="6"></line><line x1="6" y1="18" x2="6.01" y2="18"></line></svg>
|
|
1178
|
-
</div>
|
|
1179
|
-
</div>
|
|
1180
|
-
<h3>可自建部署</h3>
|
|
1181
|
-
<p>一条命令启动你自己的中继服务器。你的基础设施,你的规则。</p>
|
|
1182
|
-
</div>
|
|
1183
|
-
|
|
1184
|
-
<!-- Password Protection -->
|
|
1185
1339
|
<div class="bento-card">
|
|
1186
1340
|
<div class="bento-visual">
|
|
1187
|
-
<div class="bento-icon
|
|
1188
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><
|
|
1189
|
-
</div>
|
|
1190
|
-
</div>
|
|
1191
|
-
<h3>密码保护</h3>
|
|
1192
|
-
<p>加个 <code style="color:var(--green);font-family:'JetBrains Mono',monospace;font-size:0.8rem">--password</code> 参数锁住会话,自带暴力破解防护。</p>
|
|
1193
|
-
</div>
|
|
1194
|
-
|
|
1195
|
-
<!-- File Preview -->
|
|
1196
|
-
<div class="bento-card wide">
|
|
1197
|
-
<div class="bento-visual">
|
|
1198
|
-
<div class="bento-icon rose">
|
|
1199
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path><line x1="12" y1="11" x2="12" y2="17"></line><line x1="9" y1="14" x2="15" y2="14"></line></svg>
|
|
1341
|
+
<div class="bento-icon purple">
|
|
1342
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg>
|
|
1200
1343
|
</div>
|
|
1201
1344
|
</div>
|
|
1202
|
-
<h3
|
|
1203
|
-
<p
|
|
1345
|
+
<h3>开箱即用</h3>
|
|
1346
|
+
<p>不用注册账号,不用配置环境。安装、启动、打开链接,三步搞定。</p>
|
|
1204
1347
|
</div>
|
|
1205
1348
|
</section>
|
|
1206
1349
|
|
|
1207
1350
|
<div class="section-divider"></div>
|
|
1208
1351
|
|
|
1209
1352
|
<!-- How It Works -->
|
|
1210
|
-
<section class="workflow
|
|
1353
|
+
<section class="workflow" id="how-it-works">
|
|
1211
1354
|
<div class="workflow-label">使用方式</div>
|
|
1212
1355
|
<h2>三步,就这么简单。</h2>
|
|
1213
1356
|
<div class="workflow-steps">
|
|
@@ -1228,8 +1371,8 @@
|
|
|
1228
1371
|
<div class="workflow-step">
|
|
1229
1372
|
<div class="step-marker">03</div>
|
|
1230
1373
|
<div class="step-content">
|
|
1231
|
-
<h3
|
|
1232
|
-
<p
|
|
1374
|
+
<h3>对话、协作、自动化</h3>
|
|
1375
|
+
<p>交互式编程、启动 Agent 团队处理复杂任务、或设置定时 Loop 任务 — 同一个链接,完整历史随时恢复。</p>
|
|
1233
1376
|
</div>
|
|
1234
1377
|
</div>
|
|
1235
1378
|
</div>
|
|
@@ -1267,16 +1410,79 @@ function showToast() {
|
|
|
1267
1410
|
setTimeout(() => toast.classList.remove('show'), 1800);
|
|
1268
1411
|
}
|
|
1269
1412
|
|
|
1270
|
-
//
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1413
|
+
// iPad carousel
|
|
1414
|
+
(function() {
|
|
1415
|
+
const slides = document.querySelectorAll('.carousel-slide');
|
|
1416
|
+
const dots = document.querySelectorAll('.carousel-dot');
|
|
1417
|
+
if (!slides.length) return;
|
|
1418
|
+
let current = 0;
|
|
1419
|
+
let interval;
|
|
1420
|
+
|
|
1421
|
+
function goTo(i) {
|
|
1422
|
+
slides[current].classList.remove('active');
|
|
1423
|
+
dots[current].classList.remove('active');
|
|
1424
|
+
current = (i + slides.length) % slides.length;
|
|
1425
|
+
slides[current].classList.add('active');
|
|
1426
|
+
dots[current].classList.add('active');
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
function startAuto() {
|
|
1430
|
+
interval = setInterval(() => goTo(current + 1), 4000);
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
function resetAuto() {
|
|
1434
|
+
clearInterval(interval);
|
|
1435
|
+
startAuto();
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
dots.forEach(dot => {
|
|
1439
|
+
dot.addEventListener('click', () => {
|
|
1440
|
+
goTo(Number(dot.dataset.index));
|
|
1441
|
+
resetAuto();
|
|
1442
|
+
});
|
|
1443
|
+
});
|
|
1444
|
+
|
|
1445
|
+
// Touch/swipe support
|
|
1446
|
+
const track = document.querySelector('.ipad-carousel');
|
|
1447
|
+
let startX = 0, startY = 0, dragging = false;
|
|
1448
|
+
|
|
1449
|
+
track.addEventListener('touchstart', e => {
|
|
1450
|
+
startX = e.touches[0].clientX;
|
|
1451
|
+
startY = e.touches[0].clientY;
|
|
1452
|
+
dragging = true;
|
|
1453
|
+
}, { passive: true });
|
|
1454
|
+
|
|
1455
|
+
track.addEventListener('touchend', e => {
|
|
1456
|
+
if (!dragging) return;
|
|
1457
|
+
dragging = false;
|
|
1458
|
+
const dx = e.changedTouches[0].clientX - startX;
|
|
1459
|
+
const dy = e.changedTouches[0].clientY - startY;
|
|
1460
|
+
if (Math.abs(dx) > 50 && Math.abs(dx) > Math.abs(dy)) {
|
|
1461
|
+
goTo(dx < 0 ? current + 1 : current - 1);
|
|
1462
|
+
resetAuto();
|
|
1463
|
+
}
|
|
1464
|
+
}, { passive: true });
|
|
1465
|
+
|
|
1466
|
+
// Mouse drag support for desktop
|
|
1467
|
+
track.addEventListener('mousedown', e => {
|
|
1468
|
+
startX = e.clientX;
|
|
1469
|
+
dragging = true;
|
|
1470
|
+
track.style.cursor = 'grabbing';
|
|
1471
|
+
});
|
|
1472
|
+
|
|
1473
|
+
document.addEventListener('mouseup', e => {
|
|
1474
|
+
if (!dragging) return;
|
|
1475
|
+
dragging = false;
|
|
1476
|
+
track.style.cursor = '';
|
|
1477
|
+
const dx = e.clientX - startX;
|
|
1478
|
+
if (Math.abs(dx) > 50) {
|
|
1479
|
+
goTo(dx < 0 ? current + 1 : current - 1);
|
|
1480
|
+
resetAuto();
|
|
1275
1481
|
}
|
|
1276
1482
|
});
|
|
1277
|
-
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
|
|
1278
1483
|
|
|
1279
|
-
|
|
1484
|
+
startAuto();
|
|
1485
|
+
})();
|
|
1280
1486
|
</script>
|
|
1281
1487
|
|
|
1282
1488
|
</body>
|
package/web/iPad.png
DELETED
|
Binary file
|
package/web/iPad.webp
DELETED
|
Binary file
|
package/web/iPhone.png
DELETED
|
Binary file
|
package/web/iPhone.webp
DELETED
|
Binary file
|