···11+import { LitElement, html, css } from 'lit';
22+import '../atoms/grain-icon.js';
33+44+export class GrainTerms extends LitElement {
55+ static styles = css`
66+ :host {
77+ display: block;
88+ max-width: var(--feed-max-width);
99+ margin: 0 auto;
1010+ min-height: 100vh;
1111+ min-height: 100dvh;
1212+ padding-bottom: 80px;
1313+ background: var(--color-bg-primary);
1414+ }
1515+ .header {
1616+ display: flex;
1717+ align-items: center;
1818+ gap: var(--space-sm);
1919+ padding: var(--space-md) var(--space-sm);
2020+ }
2121+ @media (min-width: 600px) {
2222+ .header {
2323+ padding-left: 0;
2424+ padding-right: 0;
2525+ }
2626+ }
2727+ .back-button {
2828+ background: none;
2929+ border: none;
3030+ padding: 8px;
3131+ cursor: pointer;
3232+ color: var(--color-text-primary);
3333+ margin-left: -8px;
3434+ }
3535+ h1 {
3636+ font-size: var(--font-size-md);
3737+ font-weight: var(--font-weight-semibold);
3838+ color: var(--color-text-primary);
3939+ margin: 0;
4040+ }
4141+ .content {
4242+ padding: 0 var(--space-sm);
4343+ }
4444+ @media (min-width: 600px) {
4545+ .content {
4646+ padding: 0;
4747+ }
4848+ }
4949+ .last-updated {
5050+ font-size: var(--font-size-xs);
5151+ color: var(--color-text-secondary);
5252+ margin-bottom: var(--space-lg);
5353+ }
5454+ section {
5555+ margin-bottom: var(--space-lg);
5656+ }
5757+ h2 {
5858+ font-size: var(--font-size-sm);
5959+ font-weight: var(--font-weight-semibold);
6060+ color: var(--color-text-primary);
6161+ margin: 0 0 var(--space-xs) 0;
6262+ }
6363+ p {
6464+ font-size: var(--font-size-xs);
6565+ color: var(--color-text-secondary);
6666+ line-height: 1.5;
6767+ margin: 0 0 var(--space-sm) 0;
6868+ }
6969+ a {
7070+ color: var(--color-accent);
7171+ }
7272+ code {
7373+ background: var(--color-bg-elevated);
7474+ padding: 2px 4px;
7575+ border-radius: 4px;
7676+ font-size: var(--font-size-xs);
7777+ }
7878+ `;
7979+8080+ #goBack() {
8181+ history.back();
8282+ }
8383+8484+ render() {
8585+ return html`
8686+ <div class="header">
8787+ <button class="back-button" @click=${this.#goBack}>
8888+ <grain-icon name="back" size="20"></grain-icon>
8989+ </button>
9090+ <h1>Terms and Conditions</h1>
9191+ </div>
9292+ <div class="content">
9393+ <p class="last-updated">Last Updated: June 3, 2025</p>
9494+9595+ <section>
9696+ <h2>Overview</h2>
9797+ <p>
9898+ Grain is a photo sharing app built on the
9999+ <a href="https://atproto.com/" target="_blank" rel="noopener noreferrer">AT Protocol</a>.
100100+ All data, including photos, galleries, favorites, and metadata, is public and stored on the AT Protocol network.
101101+ Users can upload photos, create and favorite galleries, and view non-location EXIF metadata.
102102+ </p>
103103+ <p>
104104+ Grain is an open source project. These Terms apply to your use of the hosted version at
105105+ <code>grain.social</code>, not to self-hosted instances or forks of the source code.
106106+ </p>
107107+ </section>
108108+109109+ <section>
110110+ <h2>Account and Data Ownership</h2>
111111+ <p>
112112+ Grain uses the AT Protocol, so users retain full control over their data.
113113+ We are an independent project and not affiliated with Bluesky or the AT Protocol.
114114+ </p>
115115+ <p>
116116+ If you use a <code>grain.social</code> handle, your data may be stored on our own self-hosted
117117+ <a href="https://atproto.com/guides/glossary#pds-personal-data-server" target="_blank" rel="noopener noreferrer">PDS (Personal Data Server)</a>
118118+ in accordance with protocol standards.
119119+ </p>
120120+ </section>
121121+122122+ <section>
123123+ <h2>Content</h2>
124124+ <p>
125125+ You are responsible for any content you share. Do not upload content you do not have rights to.
126126+ All uploads are publicly visible and cannot currently be set as private.
127127+ </p>
128128+ </section>
129129+130130+ <section>
131131+ <h2>Analytics</h2>
132132+ <p>
133133+ We use <a href="https://www.goatcounter.com/" target="_blank" rel="noopener noreferrer">Goatcounter</a>
134134+ for basic analytics. No personal data is collected, tracked, or sold.
135135+ </p>
136136+ </section>
137137+138138+ <section>
139139+ <h2>Prohibited Conduct</h2>
140140+ <p>
141141+ Do not upload illegal content, harass users, impersonate others, or attempt to disrupt the network.
142142+ </p>
143143+ </section>
144144+145145+ <section>
146146+ <h2>Disclaimers</h2>
147147+ <p>
148148+ Grain is provided "as is." We do not guarantee uptime, data retention, or uninterrupted access.
149149+ </p>
150150+ </section>
151151+152152+ <section>
153153+ <h2>Termination</h2>
154154+ <p>
155155+ We reserve the right to suspend or terminate your access to Grain at any time, without prior notice,
156156+ for conduct that we believe violates these Terms, our community standards, or is harmful to other users
157157+ or the AT Protocol network. Terminated accounts may lose access to uploaded content unless retained
158158+ through the protocol's data persistence mechanisms.
159159+ </p>
160160+ </section>
161161+162162+ <section>
163163+ <h2>Changes</h2>
164164+ <p>
165165+ We may update these terms periodically. Continued use means acceptance of any changes.
166166+ </p>
167167+ </section>
168168+169169+ <section>
170170+ <h2>Contact</h2>
171171+ <p>
172172+ For any questions about these Terms, your account, or issues with the app, you can contact us at
173173+ <a href="mailto:support@grain.social">support@grain.social</a>.
174174+ </p>
175175+ </section>
176176+ </div>
177177+ `;
178178+ }
179179+}
180180+181181+customElements.define('grain-terms', GrainTerms);