a a vibe-coded abomination experiment of a fragrance review platform built on the atmosphere. drydown.social

adding a disclaimer that this is an experiment

+106 -2
+52
src/app.css
··· 611 611 white-space: nowrap; 612 612 border-width: 0; 613 613 } 614 + 615 + /* App Disclaimer - Very Subtle Footer */ 616 + .app-disclaimer { 617 + margin-top: 3rem; 618 + padding-top: 2rem; 619 + border-top: 1px solid var(--border-color); 620 + opacity: 0.7; 621 + transition: opacity 0.2s ease; 622 + } 623 + 624 + .app-disclaimer:hover { 625 + opacity: 0.9; 626 + } 627 + 628 + .app-disclaimer.minimal { 629 + text-align: center; 630 + } 631 + 632 + .app-disclaimer.minimal p { 633 + font-size: 0.75rem; 634 + color: var(--text-secondary); 635 + margin: 0; 636 + line-height: 1.4; 637 + text-wrap: pretty; 638 + } 639 + 640 + .app-disclaimer.detailed { 641 + max-width: 500px; 642 + margin-left: auto; 643 + margin-right: auto; 644 + } 645 + 646 + .app-disclaimer.detailed p { 647 + font-size: 0.85rem; 648 + color: var(--text-secondary); 649 + margin: 0 0 0.75rem 0; 650 + line-height: 1.6; 651 + text-wrap: pretty; 652 + } 653 + 654 + .app-disclaimer.detailed p:last-child { 655 + margin-bottom: 0; 656 + } 657 + 658 + .app-disclaimer a { 659 + color: var(--text-secondary); 660 + text-decoration: underline; 661 + } 662 + 663 + .app-disclaimer a:hover { 664 + text-decoration-thickness: 2px; 665 + }
+40
src/components/AppDisclaimer.tsx
··· 1 + interface AppDisclaimerProps { 2 + variant?: 'minimal' | 'detailed' 3 + } 4 + 5 + export function AppDisclaimer({ variant = 'minimal' }: AppDisclaimerProps) { 6 + if (variant === 'detailed') { 7 + return ( 8 + <footer class="app-disclaimer detailed"> 9 + <p> 10 + Drydown is an early experiment and subject to change. You may encounter bugs or incomplete features. The current lack of accessibility is not acceptable, and improvements are in progress. 11 + </p> 12 + <p> 13 + Please report issues or provide feedback at{' '} 14 + <a 15 + href="https://bsky.app/profile/taurean.bryant.land" 16 + target="_blank" 17 + rel="noopener noreferrer" 18 + > 19 + @taurean.bryant.land 20 + </a> 21 + </p> 22 + </footer> 23 + ) 24 + } 25 + 26 + return ( 27 + <footer class="app-disclaimer minimal"> 28 + <p> 29 + Drydown is an early experiment. Expect bugs and changes. Accessibility improvements are in progress. Report issues at{' '} 30 + <a 31 + href="https://bsky.app/profile/taurean.bryant.land" 32 + target="_blank" 33 + rel="noopener noreferrer" 34 + > 35 + @taurean.bryant.land 36 + </a>. 37 + </p> 38 + </footer> 39 + ) 40 + }
+2 -1
src/components/CreateReview.tsx
··· 1 1 import { useState, useEffect } from 'preact/hooks' 2 2 import { AtpBaseClient } from '../client/index' 3 3 import { Combobox } from './Combobox' 4 + import { AppDisclaimer } from './AppDisclaimer' 4 5 import type { OAuthSession } from '@atproto/oauth-client-browser' 5 6 import { DiscoveryService } from '@/services/discovery' 6 7 import { calculateWeightedScore, encodeWeightedScore } from '../utils/reviewUtils' ··· 341 342 {isSubmitting ? 'Starting Review...' : 'Start Reviewing'} 342 343 </button> 343 344 </form> 344 - 345 345 346 + <AppDisclaimer variant="minimal" /> 346 347 </div> 347 348 ) 348 349 }
+3
src/components/EditHousePage.tsx
··· 1 1 import { useState, useEffect } from 'preact/hooks' 2 2 import { useLocation, Link } from 'wouter' 3 3 import { AtpBaseClient } from '../client/index' 4 + import { AppDisclaimer } from './AppDisclaimer' 4 5 import type { OAuthSession } from '@atproto/oauth-client-browser' 5 6 6 7 interface EditHousePageProps { ··· 138 139 </button> 139 140 </div> 140 141 </form> 142 + 143 + <AppDisclaimer variant="minimal" /> 141 144 </div> 142 145 ) 143 146 }
+3
src/components/EditReview.tsx
··· 1 1 import { useState, useEffect } from 'preact/hooks' 2 2 import { AtpBaseClient } from '../client/index' 3 3 import { calculateWeightedScore, encodeWeightedScore } from '../utils/reviewUtils' 4 + import { AppDisclaimer } from './AppDisclaimer' 4 5 import type { OAuthSession } from '@atproto/oauth-client-browser' 5 6 import { WeatherService, type WeatherData } from '../services/weatherService' 6 7 import { validateEditPermissions, validateStageUpdate } from '../utils/reviewValidation' ··· 586 587 </button> 587 588 )} 588 589 </form> 590 + 591 + <AppDisclaimer variant="minimal" /> 589 592 </div> 590 593 ) 591 594 }
+4 -1
src/components/ExplorePage.tsx
··· 1 1 import { useState, useEffect } from 'preact/hooks' 2 2 import { Link, useLocation } from 'wouter' 3 3 import { SEO } from './SEO' 4 + import { AppDisclaimer } from './AppDisclaimer' 4 5 import { ReviewCard, type AuthorInfo } from './ReviewCard' 5 6 import { resolveIdentity } from '../utils/resolveIdentity' 6 7 import { cache, TTL } from '../services/cache' ··· 182 183 ) : ( 183 184 <div className="review-section"> 184 185 {reviews.map((review) => ( 185 - <ReviewCard 186 + <ReviewCard 186 187 key={review.uri} 187 188 review={review} 188 189 status="past" ··· 199 200 ))} 200 201 </div> 201 202 )} 203 + 204 + <AppDisclaimer variant="minimal" /> 202 205 </div> 203 206 ) 204 207 }
+2
src/components/LandingPage.tsx
··· 2 2 import { useLocation } from 'wouter' 3 3 import { SEO } from './SEO' 4 4 import { LoginForm } from './LoginForm' 5 + import { AppDisclaimer } from './AppDisclaimer' 5 6 import { ReviewCard, type AuthorInfo } from './ReviewCard' 6 7 import { HouseCard } from './HouseCard' 7 8 import { resolveIdentity } from '../utils/resolveIdentity' ··· 222 223 <h1>Drydown</h1> 223 224 <p>Discover & Review Fragrances</p> 224 225 <LoginForm /> 226 + <AppDisclaimer variant="detailed" /> 225 227 </section> 226 228 227 229 {/* Loading State */}