grain.social is a photo sharing platform built on atproto.
1import { ComponentChildren } from "preact";
2import { Breadcrumb } from "./components/Breadcrumb.tsx";
3
4type SectionProps = {
5 title: string;
6 children: ComponentChildren;
7};
8
9const Section = ({ title, children }: SectionProps) => (
10 <section className="mb-8">
11 <h2 className="text-xl font-bold mb-2 text-zinc-800 dark:text-zinc-100">
12 {title}
13 </h2>
14 <div className="space-y-2 text-zinc-700 dark:text-zinc-300 text-sm">
15 {children}
16 </div>
17 </section>
18);
19
20export function Terms() {
21 return (
22 <div className="px-4 py-4">
23 <Breadcrumb
24 items={[{ label: "support", href: "/support" }, { label: "terms" }]}
25 />
26 <h1 className="text-3xl font-bold mb-6 text-zinc-900 dark:text-white">
27 Terms and Conditions
28 </h1>
29 <div className="mb-6 text-sm text-zinc-900 dark:text-white">
30 Last Updated: June 3, 2025
31 </div>
32 <Section title="Overview">
33 <p>
34 Grain is a photo sharing app built on the{" "}
35 <a
36 href="https://atproto.com/"
37 className="text-sky-500 hover:underline"
38 target="_blank"
39 rel="noopener noreferrer"
40 />
41 AT Protocol . All data, including photos, galleries, favorites, and
42 metadata, is public and stored on the AT Protocol network. Users can
43 upload photos, create and favorite galleries, and view non-location
44 EXIF metadata.
45 </p>
46 <p>
47 Grain is an open source project. These Terms apply to your use of the
48 hosted version at{" "}
49 <code>grain.social</code>, not to self-hosted instances or forks of
50 the source code.
51 </p>
52 </Section>
53
54 <Section title="Account and Data Ownership">
55 <p>
56 Grain uses the AT Protocol, so users retain full control over their
57 data. We are an independent project and not affiliated with Bluesky or
58 the AT Protocol.
59 </p>
60 <p>
61 If you use a <code>grain.social</code>{" "}
62 handle, your data may be stored on our own self-hosted{" "}
63 <a
64 href="https://atproto.com/guides/glossary#pds-personal-data-server"
65 className="text-sky-500 hover:underline"
66 target="_blank"
67 rel="noopener noreferrer"
68 >
69 PDS (Personal Data Server)
70 </a>{" "}
71 in accordance with protocol standards.
72 </p>
73 </Section>
74
75 <Section title="Content">
76 <p>
77 You are responsible for any content you share. Do not upload content
78 you do not have rights to. All uploads are publicly visible and cannot
79 currently be set as private.
80 </p>
81 </Section>
82
83 <Section title="Analytics">
84 <p>
85 We use{" "}
86 <a
87 href="https://www.goatcounter.com/"
88 className="text-sky-500 hover:underline"
89 >
90 Goatcounter
91 </a>{" "}
92 for basic analytics. No personal data is collected, tracked, or sold.
93 </p>
94 </Section>
95
96 <Section title="Prohibited Conduct">
97 <p>
98 Do not upload illegal content, harass users, impersonate others, or
99 attempt to disrupt the network.
100 </p>
101 </Section>
102
103 <Section title="Disclaimers">
104 <p>
105 Grain is provided "as is." We do not guarantee uptime, data retention,
106 or uninterrupted access.
107 </p>
108 </Section>
109
110 <Section title="Termination">
111 <p>
112 We reserve the right to suspend or terminate your access to Grain at
113 any time, without prior notice, for conduct that we believe violates
114 these Terms, our community standards, or is harmful to other users or
115 the AT Protocol network. Terminated accounts may lose access to
116 uploaded content unless retained through the protocol’s data
117 persistence mechanisms.
118 </p>
119 </Section>
120
121 <Section title="Changes">
122 <p>
123 We may update these terms periodically. Continued use means acceptance
124 of any changes.
125 </p>
126 </Section>
127
128 <Section title="Contact">
129 <p>
130 For any questions about these Terms, your account, or issues with the
131 app, you can contact us at{" "}
132 <a
133 href="mailto:support@grain.social"
134 className="text-sky-500 hover:underline"
135 >
136 support@grain.social
137 </a>.
138 </p>
139 </Section>
140 </div>
141 );
142}
143
144export function PrivacyPolicy() {
145 return (
146 <div className="px-4 py-4">
147 <Breadcrumb
148 items={[{ label: "support", href: "/support" }, { label: "privacy" }]}
149 />
150 <h1 className="text-3xl font-bold mb-6 text-zinc-900 dark:text-white">
151 Privacy Policy
152 </h1>
153 <div className="mb-6 text-sm text-zinc-900 dark:text-white">
154 Last Updated: June 3, 2025
155 </div>
156 <Section title="Data Storage and Access">
157 <p>
158 Your data is stored on the AT Protocol. If you use a{" "}
159 <code>grain.social</code>{" "}
160 handle, it may be stored on our PDS. We do not store or access data
161 beyond the protocol’s standard behavior.
162 </p>
163 </Section>
164
165 <Section title="Public Data">
166 <p>
167 All content on Grain is public. Private uploads are not currently
168 supported.
169 </p>
170 </Section>
171
172 <Section title="EXIF Metadata">
173 <p>
174 We optionally collect and display EXIF metadata from your photos. At
175 upload time, you can choose whether to allow this metadata to be
176 collected. The metadata is stored according to standard AT Protocol
177 storage mechanisms and is not retained outside the protocol or used
178 for other purposes. We do not collect GPS or location data from your
179 photos.
180 </p>
181 <p>
182 You can learn more about the types of metadata commonly embedded in
183 photos at{" "}
184 <a
185 href="https://exiv2.org/tags.html"
186 className="text-sky-500 hover:underline"
187 target="_blank"
188 rel="noopener noreferrer"
189 >
190 exiv2.org
191 </a>
192 .
193 </p>
194 </Section>
195
196 <Section title="Analytics">
197 <p>
198 We use{" "}
199 <a
200 href="https://www.goatcounter.com/"
201 className="text-sky-500 hover:underline"
202 >
203 Goatcounter
204 </a>{" "}
205 for analytics. It is privacy-focused: no IP addresses, cookies, or
206 personal data is collected.
207 </p>
208 </Section>
209
210 <Section title="No Ads or Tracking">
211 <p>We do not serve ads, use third-party tracking, or sell user data.</p>
212 </Section>
213
214 <Section title="Children’s Privacy">
215 <p>Grain is not intended for users under 13 years of age.</p>
216 </Section>
217
218 <Section title="Changes to Policy">
219 <p>
220 This policy may be updated. Material changes will be communicated via
221 the app or site.
222 </p>
223 </Section>
224
225 <Section title="Contact">
226 <p>
227 For privacy questions, contact us at{" "}
228 <a
229 href="mailto:support@grain.social"
230 className="text-sky-500 hover:underline"
231 >
232 support@grain.social
233 </a>.
234 </p>
235 </Section>
236 </div>
237 );
238}
239
240export function CopyrightPolicy() {
241 return (
242 <div className="px-4 py-4">
243 <Breadcrumb
244 items={[{ label: "support", href: "/support" }, { label: "copyright" }]}
245 />
246 <h1 className="text-3xl font-bold mb-6 text-zinc-900 dark:text-white">
247 Copyright Policy
248 </h1>
249 <div className="mb-6 text-sm text-zinc-900 dark:text-white">
250 Last Updated: June 3, 2025
251 </div>
252 <Section title="Copyright Infringement">
253 <p>
254 Grain respects the intellectual property rights of others and expects
255 users to do the same. If you believe your copyrighted work has been
256 used in a way that constitutes infringement, please notify us
257 promptly.
258 </p>
259 </Section>
260
261 <Section title="Notice Requirements">
262 <p>
263 Your infringement notice must include: (1) a description of the
264 copyrighted work, (2) the location of the infringing material, (3)
265 your contact information, (4) a statement that you believe in good
266 faith the use is not authorized, and (5) a statement, under penalty of
267 perjury, that the information is accurate.
268 </p>
269 </Section>
270
271 <Section title="DMCA Compliance">
272 <p>
273 Grain complies with the Digital Millennium Copyright Act (DMCA). If
274 you are a copyright holder and believe your rights have been violated,
275 you may file a DMCA notice with the required information to our
276 designated agent. We will promptly respond to all valid DMCA notices
277 and take appropriate action, including removal of the infringing
278 content and disabling access.
279 </p>
280 </Section>
281
282 <Section title="Repeat Infringers">
283 <p>
284 Accounts that repeatedly infringe copyright may be suspended or
285 removed in accordance with AT Protocol and Grain Social’s moderation
286 guidelines.
287 </p>
288 </Section>
289
290 <Section title="Contact">
291 <p>
292 To report infringement or submit a DMCA notice, contact us at{" "}
293 <a
294 href="mailto:support@grain.social"
295 className="text-sky-500 hover:underline"
296 >
297 support@grain.social
298 </a>.
299 </p>
300 </Section>
301 </div>
302 );
303}