+72
-4
src/templates.rs
+72
-4
src/templates.rs
···
878
878
.onboarding-progress span.done {{
879
879
background: var(--text-light);
880
880
}}
881
+
882
+
.stats-box {{
883
+
display: flex;
884
+
gap: 1.5rem;
885
+
margin: 1.5rem 0;
886
+
padding: 1rem;
887
+
background: var(--bg);
888
+
border-radius: 4px;
889
+
border: 1px solid var(--border);
890
+
}}
891
+
892
+
.stat {{
893
+
flex: 1;
894
+
text-align: center;
895
+
}}
896
+
897
+
.stat-value {{
898
+
font-size: 1.8rem;
899
+
font-weight: 600;
900
+
color: var(--text);
901
+
margin-bottom: 0.25rem;
902
+
}}
903
+
904
+
.stat-label {{
905
+
font-size: 0.65rem;
906
+
color: var(--text-light);
907
+
text-transform: uppercase;
908
+
letter-spacing: 0.05em;
909
+
}}
910
+
911
+
.ownership-box {{
912
+
margin: 1rem 0;
913
+
padding: 1rem;
914
+
background: var(--bg);
915
+
border-radius: 4px;
916
+
border: 1px solid var(--border);
917
+
}}
918
+
919
+
.ownership-box.yours {{
920
+
background: rgba(76, 175, 80, 0.05);
921
+
border-color: rgba(76, 175, 80, 0.3);
922
+
}}
923
+
924
+
@media (prefers-color-scheme: dark) {{
925
+
.ownership-box.yours {{
926
+
background: rgba(76, 175, 80, 0.08);
927
+
border-color: rgba(76, 175, 80, 0.4);
928
+
}}
929
+
}}
930
+
931
+
.ownership-header {{
932
+
font-size: 0.7rem;
933
+
font-weight: 600;
934
+
color: var(--text);
935
+
margin-bottom: 0.5rem;
936
+
text-transform: uppercase;
937
+
letter-spacing: 0.05em;
938
+
}}
939
+
940
+
.ownership-text {{
941
+
font-size: 0.7rem;
942
+
color: var(--text-lighter);
943
+
line-height: 1.5;
944
+
}}
945
+
946
+
.ownership-text strong {{
947
+
color: var(--text);
948
+
}}
881
949
</style>
882
950
</head>
883
951
<body>
···
886
954
887
955
<div class="overlay" id="overlay"></div>
888
956
<div class="info-modal" id="infoModal">
889
-
<h2>@me - your at protocol identity</h2>
890
-
<p>in decentralized social networks, you own your identity and your data lives in your personal data server (pds).</p>
891
-
<p>third-party applications create records in your repository using different lexicons (data schemas). for example, bluesky creates posts, white wind stores blog entries, tangled.org hosts code repositories, and frontpage aggregates links - all in the same place.</p>
892
-
<p>this visualization shows your identity at the center, surrounded by the third-party apps that have created data for you. click an app to see what types of records it stores, then click a record type to see the actual data.</p>
957
+
<h2>@me - your repository</h2>
958
+
<p>on instagram, facebook, or twitter: the platform owns your content. if they ban you, it's all gone. you can't move it, export it, or control who accesses it.</p>
959
+
<p>on atproto: you own everything. your data lives in your personal server. apps like bluesky, whitewind, and frontpage just write to YOUR repository. you can switch apps, move servers, or revoke access anytime.</p>
960
+
<p>click your @ in the center to see what you've built. click any app to see what it's stored in your space.</p>
893
961
<button id="closeInfo">got it</button>
894
962
<button id="restartTour" onclick="window.restartOnboarding()" style="margin-left: 0.5rem; background: var(--surface-hover);">restart tour</button>
895
963
</div>
+42
-18
static/app.js
+42
-18
static/app.js
···
93
93
// User may not have an avatar set
94
94
});
95
95
96
+
// Store collections for later use
97
+
let allCollections = [];
98
+
96
99
// Add identity click handler to show PDS info
97
100
document.querySelector('.identity').addEventListener('click', () => {
98
101
const detail = document.getElementById('detail');
99
102
const pdsHost = pds.replace('https://', '').replace('http://', '');
103
+
104
+
// Count total apps
105
+
const appCount = Object.keys(apps).length;
106
+
100
107
detail.innerHTML = `
101
108
<button class="detail-close" id="detailClose">×</button>
102
-
<h3>your identity</h3>
103
-
<div class="subtitle">decentralized identifier & storage</div>
104
-
<div class="tree-item">
105
-
<div class="tree-item-header">
106
-
<span style="color: var(--text-light);">did</span>
107
-
<span style="font-size: 0.6rem; color: var(--text);">${did}</span>
109
+
<h3>your repository</h3>
110
+
<div class="subtitle">what you've built</div>
111
+
112
+
<div class="stats-box">
113
+
<div class="stat">
114
+
<div class="stat-value">${allCollections.length}</div>
115
+
<div class="stat-label">record types</div>
108
116
</div>
109
-
</div>
110
-
<div class="tree-item">
111
-
<div class="tree-item-header">
112
-
<span style="color: var(--text-light);">handle</span>
113
-
<span style="font-size: 0.6rem; color: var(--text);">@${handle}</span>
117
+
<div class="stat">
118
+
<div class="stat-value">${appCount}</div>
119
+
<div class="stat-label">apps</div>
114
120
</div>
115
121
</div>
116
-
<div class="tree-item">
117
-
<div class="tree-item-header">
118
-
<span style="color: var(--text-light);">personal data server</span>
119
-
<span style="font-size: 0.6rem; color: var(--text);">${pds}</span>
120
-
</div>
122
+
123
+
<div class="ownership-box">
124
+
<div class="ownership-header">on walled gardens</div>
125
+
<div class="ownership-text">platform owns your content. account ban = everything gone. no export, no control.</div>
121
126
</div>
122
-
<div style="margin-top: 1rem; padding: 0.6rem; background: var(--bg); border-radius: 4px; font-size: 0.65rem; line-height: 1.5; color: var(--text-lighter);">
123
-
your data lives at <strong style="color: var(--text);">${pdsHost}</strong>. apps like bluesky write to and read from this server. you control @<strong style="color: var(--text);">${handle}</strong> and can move it to a different server anytime.
127
+
128
+
<div class="ownership-box yours">
129
+
<div class="ownership-header">on atproto</div>
130
+
<div class="ownership-text">you own it. lives at <strong>${pdsHost}</strong>. move servers, switch apps, export anytime. can't be taken away.</div>
131
+
</div>
132
+
133
+
<div style="margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--border);">
134
+
<div style="font-size: 0.65rem; color: var(--text-light); margin-bottom: 0.5rem;">technical details</div>
135
+
<div class="tree-item">
136
+
<div class="tree-item-header">
137
+
<span style="color: var(--text-light);">did</span>
138
+
<span style="font-size: 0.55rem; color: var(--text);">${did}</span>
139
+
</div>
140
+
</div>
141
+
<div class="tree-item">
142
+
<div class="tree-item-header">
143
+
<span style="color: var(--text-light);">handle</span>
144
+
<span style="font-size: 0.6rem; color: var(--text);">@${handle}</span>
145
+
</div>
146
+
</div>
124
147
</div>
125
148
`;
126
149
detail.classList.add('visible');
···
138
161
.then(r => r.json())
139
162
.then(repo => {
140
163
const collections = repo.collections || [];
164
+
allCollections = collections;
141
165
142
166
// Group by app namespace (first two parts of lexicon)
143
167
const apps = {};