forked from
grain.social/grain-pwa
WIP PWA for Grain
1import { LitElement, html, css } from 'lit';
2import '../atoms/grain-icon.js';
3
4export class GrainPrivacy extends LitElement {
5 static styles = css`
6 :host {
7 display: block;
8 width: 100%;
9 max-width: var(--feed-max-width);
10 min-height: 100%;
11 padding-bottom: 80px;
12 background: var(--color-bg-primary);
13 align-self: center;
14 }
15 .header {
16 display: flex;
17 align-items: center;
18 gap: var(--space-sm);
19 padding: var(--space-md) var(--space-sm);
20 }
21 @media (min-width: 600px) {
22 .header {
23 padding-left: 0;
24 padding-right: 0;
25 }
26 }
27 .back-button {
28 background: none;
29 border: none;
30 padding: 8px;
31 cursor: pointer;
32 color: var(--color-text-primary);
33 margin-left: -8px;
34 }
35 h1 {
36 font-size: var(--font-size-md);
37 font-weight: var(--font-weight-semibold);
38 color: var(--color-text-primary);
39 margin: 0;
40 }
41 .content {
42 padding: 0 var(--space-sm);
43 }
44 @media (min-width: 600px) {
45 .content {
46 padding: 0;
47 }
48 }
49 .last-updated {
50 font-size: var(--font-size-xs);
51 color: var(--color-text-secondary);
52 margin-bottom: var(--space-lg);
53 }
54 section {
55 margin-bottom: var(--space-lg);
56 }
57 h2 {
58 font-size: var(--font-size-sm);
59 font-weight: var(--font-weight-semibold);
60 color: var(--color-text-primary);
61 margin: 0 0 var(--space-xs) 0;
62 }
63 p {
64 font-size: var(--font-size-xs);
65 color: var(--color-text-secondary);
66 line-height: 1.5;
67 margin: 0 0 var(--space-sm) 0;
68 }
69 a {
70 color: var(--color-accent);
71 }
72 code {
73 background: var(--color-bg-elevated);
74 padding: 2px 4px;
75 border-radius: 4px;
76 font-size: var(--font-size-xs);
77 }
78 `;
79
80 #goBack() {
81 history.back();
82 }
83
84 render() {
85 return html`
86 <div class="header">
87 <button class="back-button" @click=${this.#goBack}>
88 <grain-icon name="back" size="20"></grain-icon>
89 </button>
90 <h1>Privacy Policy</h1>
91 </div>
92 <div class="content">
93 <p class="last-updated">Last Updated: June 3, 2025</p>
94
95 <section>
96 <h2>Data Storage and Access</h2>
97 <p>
98 Your data is stored on the AT Protocol. If you use a <code>grain.social</code> handle,
99 it may be stored on our PDS. We do not store or access data beyond the protocol's standard behavior.
100 </p>
101 </section>
102
103 <section>
104 <h2>Public Data</h2>
105 <p>
106 All content on Grain is public. Private uploads are not currently supported.
107 </p>
108 </section>
109
110 <section>
111 <h2>EXIF Metadata</h2>
112 <p>
113 We optionally collect and display EXIF metadata from your photos. At upload time, you can choose
114 whether to allow this metadata to be collected. The metadata is stored according to standard
115 AT Protocol storage mechanisms and is not retained outside the protocol or used for other purposes.
116 We do not collect GPS or location data from your photos.
117 </p>
118 <p>
119 You can learn more about the types of metadata commonly embedded in photos at
120 <a href="https://exiv2.org/tags.html" target="_blank" rel="noopener noreferrer">exiv2.org</a>.
121 </p>
122 </section>
123
124 <section>
125 <h2>Analytics</h2>
126 <p>
127 We use <a href="https://www.goatcounter.com/" target="_blank" rel="noopener noreferrer">Goatcounter</a>
128 for analytics. It is privacy-focused: no IP addresses, cookies, or personal data is collected.
129 </p>
130 </section>
131
132 <section>
133 <h2>No Ads or Tracking</h2>
134 <p>
135 We do not serve ads, use third-party tracking, or sell user data.
136 </p>
137 </section>
138
139 <section>
140 <h2>Children's Privacy</h2>
141 <p>
142 Grain is not intended for users under 13 years of age.
143 </p>
144 </section>
145
146 <section>
147 <h2>Changes to Policy</h2>
148 <p>
149 This policy may be updated. Material changes will be communicated via the app or site.
150 </p>
151 </section>
152
153 <section>
154 <h2>Contact</h2>
155 <p>
156 For privacy questions, contact us at
157 <a href="mailto:support@grain.social">support@grain.social</a>.
158 </p>
159 </section>
160 </div>
161 `;
162 }
163}
164
165customElements.define('grain-privacy', GrainPrivacy);