WIP PWA for Grain
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add privacy policy page component

+165
+165
src/components/pages/grain-privacy.js
··· 1 + import { LitElement, html, css } from 'lit'; 2 + import '../atoms/grain-icon.js'; 3 + 4 + export class GrainPrivacy extends LitElement { 5 + static styles = css` 6 + :host { 7 + display: block; 8 + max-width: var(--feed-max-width); 9 + margin: 0 auto; 10 + min-height: 100vh; 11 + min-height: 100dvh; 12 + padding-bottom: 80px; 13 + background: var(--color-bg-primary); 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 + 165 + customElements.define('grain-privacy', GrainPrivacy);