Sarolanda commited on
Commit
17c32d2
·
1 Parent(s): c003727

Adjusts IA rules

Browse files
Files changed (1) hide show
  1. index.html +624 -571
index.html CHANGED
@@ -1,571 +1,624 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8"/>
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
6
- <title>PawMap</title>
7
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.css"/>
8
- <link rel="preconnect" href="https://fonts.googleapis.com"/>
9
- <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,400;0,14..32,500;0,14..32,600;0,14..32,700;1,14..32,400&display=swap" rel="stylesheet"/>
10
- <link rel="stylesheet" href="/static/style.css"/>
11
- <script src="https://cdn.jsdelivr.net/npm/lucide@0.454.0/dist/umd/lucide.min.js"></script>
12
- <script src="https://cdn.jsdelivr.net/npm/lottie-web@5.12.2/build/player/lottie.min.js"></script>
13
- <script src="https://cdn.jsdelivr.net/npm/exifr@7.1.3/dist/full.umd.js"></script>
14
- </head>
15
- <body>
16
- <div id="desktop-layout">
17
-
18
- <!-- ══ LEFT SIDEBAR (desktop only) ══ -->
19
- <aside id="sidebar-left">
20
- <div class="sidebar-logo">
21
- <span class="sidebar-paw">🐾</span>
22
- <span class="sidebar-brand">PawMap</span>
23
- </div>
24
- <p class="sidebar-tagline">Collaborative stray animal mapping, powered by AI.</p>
25
-
26
- <div class="sidebar-divider"></div>
27
-
28
- <div class="sidebar-section">
29
- <h3>The problem</h3>
30
- <p>Independent rescuers in Brasília, DF keep track of entire stray animal colonies in their heads — which ones were neutered, which one got hurt last winter, which one hasn't shown up this week. That knowledge lives in WhatsApp groups and fades when people move on.</p>
31
- <p>PawMap turns those scattered sightings into a shared, persistent map — one photo at a time.</p>
32
- </div>
33
-
34
- <div class="sidebar-divider"></div>
35
-
36
- <div class="sidebar-section">
37
- <h3>How it works</h3>
38
- <div class="how-steps">
39
- <div class="how-step">
40
- <div class="how-num"><i data-lucide="camera"></i></div>
41
- <div class="how-content">
42
- <strong>Snap a photo</strong>
43
- <span>Point your camera at any stray dog or cat.</span>
44
- </div>
45
- </div>
46
- <div class="how-connector"></div>
47
- <div class="how-step">
48
- <div class="how-num"><i data-lucide="scan-line"></i></div>
49
- <div class="how-content">
50
- <strong>AI identifies</strong>
51
- <span>Species, breed, color and condition — automatically.</span>
52
- </div>
53
- </div>
54
- <div class="how-connector"></div>
55
- <div class="how-step">
56
- <div class="how-num"><i data-lucide="git-merge"></i></div>
57
- <div class="how-content">
58
- <strong>Smart matching</strong>
59
- <span>Checks if this animal has been seen before.</span>
60
- </div>
61
- </div>
62
- <div class="how-connector"></div>
63
- <div class="how-step">
64
- <div class="how-num"><i data-lucide="map-pin"></i></div>
65
- <div class="how-content">
66
- <strong>Map updates</strong>
67
- <span>Sighting linked to the animal's profile — or a new one is created.</span>
68
- </div>
69
- </div>
70
- </div>
71
- </div>
72
-
73
- </aside>
74
-
75
- <div class="phone-wrap">
76
- <div class="better-on-mobile"><i data-lucide="smartphone"></i> Better on mobile</div>
77
- <div class="phone-frame">
78
- <div class="phone-btn phone-btn-vol-up"></div>
79
- <div class="phone-btn phone-btn-vol-down"></div>
80
- <div class="phone-btn phone-btn-power"></div>
81
- <div id="app">
82
-
83
- <!-- ══ ONBOARDING ══ -->
84
- <div id="screen-splash">
85
- <button id="ob-skip">Skip</button>
86
-
87
- <!-- Steps -->
88
- <div id="ob-track">
89
-
90
- <!-- Step 1 -->
91
- <div class="ob-step">
92
- <div class="ob-lottie-wrap">
93
- <div id="lottie-1" class="ob-lottie"></div>
94
- <div class="ob-lottie-fallback"><i data-lucide="camera"></i></div>
95
- </div>
96
- <div class="ob-text">
97
- <div class="ob-step-label">Step 1 of 4</div>
98
- <h2>Help a stray find its way</h2>
99
- <p>Every street dog and cat deserves to be seen. PawMap lets your community map them together — one photo at a time.</p>
100
- </div>
101
- </div>
102
-
103
- <!-- Step 2 -->
104
- <div class="ob-step">
105
- <div class="ob-lottie-wrap">
106
- <div id="lottie-2" class="ob-lottie"></div>
107
- <div class="ob-lottie-fallback"><i data-lucide="scan-line"></i></div>
108
- </div>
109
- <div class="ob-text">
110
- <div class="ob-step-label">Step 2 of 4</div>
111
- <h2>Snap a photo — AI does the rest</h2>
112
- <p>Point your camera and tap. Our AI instantly identifies species, breed, color, and condition. No forms to fill.</p>
113
- </div>
114
- </div>
115
-
116
- <!-- Step 3 -->
117
- <div class="ob-step">
118
- <div class="ob-lottie-wrap">
119
- <div id="lottie-3" class="ob-lottie"></div>
120
- <div class="ob-lottie-fallback"><i data-lucide="refresh-cw"></i></div>
121
- </div>
122
- <div class="ob-text">
123
- <div class="ob-step-label">Step 3 of 4</div>
124
- <h2>AI matches the same animal</h2>
125
- <p>Seen this dog before? The AI compares your photo with previous sightings and links them automatically — building each animal's story.</p>
126
- </div>
127
- </div>
128
-
129
- <!-- Step 4 -->
130
- <div class="ob-step">
131
- <div class="ob-lottie-wrap">
132
- <div id="lottie-4" class="ob-lottie"></div>
133
- <div class="ob-lottie-fallback"><i data-lucide="home"></i></div>
134
- </div>
135
- <div class="ob-text">
136
- <div class="ob-step-label">Step 4 of 4</div>
137
- <h2>Every map pin is a chance</h2>
138
- <p>Mapping a dog brings more chances to find a forever family — or get help from the community when it's needed most.</p>
139
- </div>
140
- </div>
141
-
142
- </div><!-- /ob-track -->
143
-
144
- <!-- Dots -->
145
- <div id="ob-dots">
146
- <span class="ob-dot active"></span>
147
- <span class="ob-dot"></span>
148
- <span class="ob-dot"></span>
149
- <span class="ob-dot"></span>
150
- </div>
151
-
152
- <!-- Actions -->
153
- <div id="ob-actions">
154
- <button id="ob-next">Next →</button>
155
- </div>
156
-
157
- </div><!-- /screen-splash -->
158
-
159
- <!-- ══ HEADER ══ -->
160
- <header id="header">
161
- <button class="icon-btn" id="menu-btn" aria-label="Menu">
162
- <svg viewBox="0 0 24 24"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
163
- </button>
164
- <span class="logo">PawMap</span>
165
- <button class="icon-btn" aria-label="Options">
166
- <svg viewBox="0 0 24 24"><circle cx="12" cy="5" r="1.5" fill="#fff" stroke="none"/><circle cx="12" cy="12" r="1.5" fill="#fff" stroke="none"/><circle cx="12" cy="19" r="1.5" fill="#fff" stroke="none"/></svg>
167
- </button>
168
- </header>
169
-
170
- <!-- ══ FILTER ROW ══ -->
171
- <div id="filter-row">
172
- <button class="chip active" data-species="all">All</button>
173
- <button class="chip" data-species="dog"><i data-lucide="dog"></i> Dogs</button>
174
- <button class="chip" data-species="cat"><i data-lucide="cat"></i> Cats</button>
175
- <button class="chip" data-timeframe="today">Today</button>
176
- <button class="chip" data-timeframe="week">This Week</button>
177
- </div>
178
-
179
- <!-- ══ SCREEN: MAP ══ -->
180
- <div id="screen-map" class="screen active">
181
- <div id="map"></div>
182
- <div id="map-empty">No sightings yet</div>
183
- <div id="sighting-card" class="hidden">
184
- <div class="card-photo" id="card-photo"><i data-lucide="paw-print"></i></div>
185
- <div class="card-info">
186
- <div class="card-top"><span class="badge" id="card-badge">Dog</span><span class="card-time" id="card-time"></span></div>
187
- <div class="card-location" id="card-location"></div>
188
- <div class="card-sub" id="card-sub"></div>
189
- </div>
190
- <button class="btn-ficha" id="card-btn">View profile</button>
191
- </div>
192
- </div>
193
-
194
- <!-- ══ SCREEN: REGISTER ══ -->
195
- <div id="screen-register" class="screen">
196
- <input type="file" id="photo-input" accept="image/*"/>
197
- <div id="viewfinder">
198
- <div id="gps-pill">
199
- <svg viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/></svg>
200
- <span id="gps-text">Add a photo to detect location</span>
201
- </div>
202
- <img id="photo-preview" src="" alt="photo"/>
203
- <div id="camera-placeholder">
204
- <svg viewBox="0 0 24 24"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>
205
- <p>Tap the button to take a photo</p>
206
- </div>
207
- <button id="shutter-btn" aria-label="Take photo">
208
- <svg viewBox="0 0 24 24"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>
209
- </button>
210
- </div>
211
- <div id="reg-sheet">
212
- <div class="drag-handle"></div>
213
- <div id="notes-row">
214
- <svg viewBox="0 0 24 24"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
215
- <textarea id="notes-input" rows="1" placeholder="Add a note (optional)"></textarea>
216
- </div>
217
- <div id="locate-options" style="display:none">
218
- <button class="btn-locate" id="gps-btn">
219
- <svg viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/></svg>
220
- Usar localização atual
221
- </button>
222
- <button class="btn-locate alt" id="map-btn">
223
- <svg viewBox="0 0 24 24"><polygon points="3 6 9 3 15 6 21 3 21 18 15 21 9 18 3 21"/><line x1="9" y1="3" x2="9" y2="18"/><line x1="15" y1="6" x2="15" y2="21"/></svg>
224
- Selecionar no mapa
225
- </button>
226
- </div>
227
- <button class="btn-primary" id="submit-reg-btn" disabled>
228
- <svg viewBox="0 0 24 24"><path d="M22 2L11 13"/><path d="M22 2l-7 20-4-9-9-4 20-7z"/></svg>
229
- Report Sighting
230
- </button>
231
- </div>
232
- </div>
233
-
234
- <!-- ══ SCREEN: ANALYSIS ══ -->
235
- <div id="screen-analysis" class="screen">
236
- <div class="flow-header">
237
- <button class="back-btn" id="analysis-back"><svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg></button>
238
- <h2>Analyzing Sighting</h2>
239
- </div>
240
- <div id="analysis-photo-wrap">
241
- <img id="analysis-photo" src="" alt="photo"/>
242
- <div id="ai-badge"><span class="dot"></span><span id="ai-badge-text">AI Analyzing...</span></div>
243
- <div id="animal-result-badge"><svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg><span id="result-badge-text">Caramel Dog</span></div>
244
- </div>
245
- <div class="analysis-card">
246
- <h3>Identified Details <button id="edit-btn"><i data-lucide="pencil"></i></button></h3>
247
- <p class="subtitle">AI filled in these details. Correct if needed.</p>
248
- <div class="dropdowns-grid">
249
- <div class="dropdown-field"><label>Species</label><select id="sel-species"><option value="dog">Dog</option><option value="cat">Cat</option></select></div>
250
- <div class="dropdown-field"><label>Breed (Estimated)</label><select id="sel-breed"></select></div>
251
- <div class="dropdown-field"><label>Primary Color</label><select id="sel-color"><option value="Black">Black</option><option value="White">White</option><option value="Gray">Gray</option><option value="Brown">Brown</option><option value="Chocolate">Chocolate</option><option value="Caramel">Caramel</option><option value="Tan">Tan</option><option value="Golden">Golden</option><option value="Cream">Cream</option><option value="Fawn">Fawn</option><option value="Orange">Orange</option><option value="Ginger">Ginger</option><option value="Red">Red</option><option value="Sable">Sable</option><option value="Cinnamon">Cinnamon</option><option value="Blue">Blue (gray)</option><option value="Lilac">Lilac</option><option value="Tabby">Tabby</option><option value="Tuxedo">Tuxedo</option><option value="Calico">Calico</option><option value="Tortoiseshell">Tortoiseshell</option><option value="Tricolor">Tricolor</option><option value="Bicolor">Bicolor</option><option value="Brindle">Brindle</option><option value="Merle">Merle</option><option value="Spotted">Spotted</option><option value="Mixed">Mixed</option></select></div>
252
- <div class="dropdown-field"><label>Size</label><select id="sel-size"><option value="Tiny">Tiny</option><option value="Small">Small</option><option value="Medium">Medium</option><option value="Large">Large</option><option value="Extra Large">Extra Large</option><option value="Giant">Giant</option></select></div>
253
- </div>
254
- <div class="condition-label">Condition (Optional)</div>
255
- <div class="condition-chips">
256
- <button class="cond-chip" data-val="Injured"><span class="check"><i data-lucide="check"></i></span> Injured</button>
257
- <button class="cond-chip" data-val="Looks Healthy"><span class="check"><i data-lucide="check"></i></span> Looks Healthy</button>
258
- <button class="cond-chip" data-val="Has Collar"><span class="check"><i data-lucide="check"></i></span> Has Collar</button>
259
- </div>
260
- </div>
261
- <div class="analysis-card" id="similar-section">
262
- <h3>Similar animals nearby</h3>
263
- <p class="subtitle">Found by AI for context — recognition is automatic.</p>
264
- <div class="similar-scroll" id="similar-scroll"></div>
265
- </div>
266
- <div class="analysis-card">
267
- <div class="dropdown-field">
268
- <label>Name <span class="optional-tag">optional</span></label>
269
- <input type="text" id="animal-name-input" placeholder="e.g. Caputino, Bolinha, Luna…" maxlength="40" autocomplete="off"/>
270
- </div>
271
- </div>
272
- <div id="analysis-actions">
273
- <button class="btn-primary" id="confirm-btn">Confirm & Report →</button>
274
- <button class="btn-outline" id="discard-btn">Discard Photo</button>
275
- </div>
276
- </div>
277
-
278
- <!-- ══ SCREEN: CONFIRM ══ -->
279
- <div id="screen-confirm" class="screen">
280
- <div id="confirm-inner">
281
- <div id="confirm-photo-wrap">
282
- <div id="confirm-photo"><i data-lucide="paw-print"></i></div>
283
- <div id="confirm-check"><svg viewBox="0 0 24 24"><polyline points="20 6 9 20 4 14"/></svg></div>
284
- </div>
285
- <div id="confirm-title">Sighting<br>Reported!</div>
286
- <div id="confirm-card">
287
- <div class="confirm-row">
288
- <span class="confirm-row-label"><svg viewBox="0 0 24 24"><path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>Animal:</span>
289
- <span class="confirm-row-value" id="confirm-animal">—</span>
290
- </div>
291
- <div class="confirm-row">
292
- <span class="confirm-row-label"><svg viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/></svg>Location:</span>
293
- <span class="confirm-row-value" id="confirm-local">���</span>
294
- </div>
295
- <div class="confirm-row">
296
- <span class="confirm-row-label"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>Time:</span>
297
- <span class="confirm-row-value" id="confirm-hora">—</span>
298
- </div>
299
- </div>
300
- <div id="confirm-id-grid" class="confirm-id-grid"></div>
301
- <div class="confirm-btns">
302
- <button class="btn-primary" id="register-another-btn"><svg viewBox="0 0 24 24"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>Report Another</button>
303
- <button class="btn-secondary" id="go-map-btn"><svg viewBox="0 0 24 24"><polygon points="3 6 9 3 15 6 21 3 21 18 15 21 9 18 3 21"/></svg>View on Map</button>
304
- </div>
305
- </div>
306
- </div>
307
-
308
- <!-- ══ SCREEN: SIGHTINGS LIST ══ -->
309
- <div id="screen-sightings" class="screen">
310
- <div id="sightings-header">
311
- <span id="sightings-count">Loading...</span>
312
- <button id="refresh-btn" title="Refresh"><i data-lucide="refresh-cw"></i></button>
313
- </div>
314
- <div id="animals-list"></div>
315
- </div>
316
-
317
- <!-- ══ SCREEN: PROFILE / FICHA ══ -->
318
- <div id="screen-profile" class="screen">
319
- <div class="profile-scroll">
320
- <!-- Hero -->
321
- <div class="profile-hero">
322
- <img class="profile-hero-img" id="profile-hero-img" src="" alt=""/>
323
- <div class="hero-gradient"></div>
324
- <div class="hero-top-btns">
325
- <button class="hero-btn" id="profile-back-btn"><svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg></button>
326
- <button class="hero-btn" id="profile-share-btn"><svg viewBox="0 0 24 24"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg></button>
327
- </div>
328
- <div id="profile-sightings-badge">
329
- <svg viewBox="0 0 24 24"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
330
- <span id="profile-badge-text">0 sightings</span>
331
- </div>
332
- </div>
333
-
334
- <!-- Content -->
335
- <div class="profile-content">
336
- <h1 id="profile-title">...</h1>
337
- <div id="profile-status"><span class="status-dot"></span><span id="profile-status-text">...</span></div>
338
- <div id="profile-helped-banner" style="display:none">
339
- <i data-lucide="heart"></i>
340
- <span>This animal has been helped by the community</span>
341
- </div>
342
- <div id="profile-ai-desc" class="ai-desc-callout" style="display:none">
343
- <span class="ai-label">AI</span>
344
- <p id="profile-ai-text"></p>
345
- </div>
346
-
347
- <!-- Identification -->
348
- <div class="profile-section">
349
- <div class="section-title">Identification</div>
350
- <div class="id-grid">
351
- <div class="id-cell"><div class="id-cell-label">Species</div><div class="id-cell-value" id="prof-species">—</div></div>
352
- <div class="id-cell"><div class="id-cell-label">Breed</div><div class="id-cell-value" id="prof-breed">—</div></div>
353
- <div class="id-cell"><div class="id-cell-label">Size</div><div class="id-cell-value" id="prof-size">—</div></div>
354
- <div class="id-cell"><div class="id-cell-label">Color</div><div class="id-cell-value" id="prof-color">—</div></div>
355
- </div>
356
- </div>
357
-
358
- <!-- Gallery -->
359
- <div class="profile-section">
360
- <div class="gallery-header">
361
- <div class="section-title" style="margin-bottom:0">Sightings Gallery</div>
362
- <button class="gallery-see-all">See all</button>
363
- </div>
364
- <div class="gallery-scroll" id="profile-gallery"></div>
365
- </div>
366
-
367
- <!-- Community Help -->
368
- <div class="profile-section" id="profile-help-section" style="display:none">
369
- <div class="section-title help-section-title">
370
- <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="var(--green)" stroke-width="2"><path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"/></svg>
371
- Community Help
372
- </div>
373
- <div id="profile-help-list"></div>
374
- </div>
375
-
376
- <!-- Trajectory -->
377
- <div class="profile-section">
378
- <div class="section-title">Recent Path</div>
379
- <div id="trajectory-map"></div>
380
- </div>
381
- </div>
382
- </div>
383
-
384
- <!-- Footer -->
385
- <div class="profile-footer">
386
- <button class="btn-adopt" id="btn-adopt"><i data-lucide="heart"></i> I Want to Adopt / Help</button>
387
- </div>
388
- </div>
389
-
390
- <!-- ══ HELP BOTTOM SHEET ══ -->
391
- <div id="help-overlay" class="hidden"></div>
392
- <div id="help-sheet" class="help-sheet hidden">
393
- <div class="drag-handle"></div>
394
- <div id="help-animal-row">
395
- <div id="help-animal-photo"></div>
396
- <div id="help-animal-info">
397
- <div id="help-animal-name">—</div>
398
- <div id="help-animal-sub">—</div>
399
- </div>
400
- </div>
401
- <div class="help-actions">
402
- <button class="help-action-btn" id="help-share">
403
- <span class="help-action-icon"><i data-lucide="share-2"></i></span>
404
- <span class="help-action-text">
405
- <strong>Share this animal</strong>
406
- <small>Send via WhatsApp or copy link</small>
407
- </span>
408
- <svg class="help-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
409
- </button>
410
- <button class="help-action-btn" id="help-directions">
411
- <span class="help-action-icon"><i data-lucide="map-pin"></i></span>
412
- <span class="help-action-text">
413
- <strong>Get directions</strong>
414
- <small>Navigate to last known location</small>
415
- </span>
416
- <svg class="help-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
417
- </button>
418
- <button class="help-action-btn" id="help-helped">
419
- <span class="help-action-icon"><i data-lucide="check-circle"></i></span>
420
- <span class="help-action-text">
421
- <strong>I helped this animal</strong>
422
- <small>Log that you fed, treated, or fostered them</small>
423
- </span>
424
- <svg class="help-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
425
- </button>
426
- </div>
427
- <button class="help-cancel" id="help-cancel">Cancel</button>
428
- </div>
429
-
430
- <!-- ══ HELPED CONFIRM ══ -->
431
- <div id="helped-confirm" class="helped-confirm hidden">
432
- <div class="helped-inner">
433
- <div class="helped-icon-wrap"><i data-lucide="heart"></i></div>
434
- <h3>Thank you</h3>
435
- <p>Your help has been recorded.<br>Every act of care makes a difference.</p>
436
- <button id="helped-ok">Done</button>
437
- </div>
438
- </div>
439
-
440
- <!-- ══ IMAGE SOURCE CHOOSER ══ -->
441
- <div id="source-overlay" class="hidden"></div>
442
- <div id="source-sheet" class="help-sheet hidden">
443
- <div class="drag-handle"></div>
444
- <div class="help-actions">
445
- <button class="help-action-btn" id="source-camera">
446
- <span class="help-action-icon"><i data-lucide="camera"></i></span>
447
- <span class="help-action-text">
448
- <strong>Tirar foto</strong>
449
- <small>Abrir a câmera</small>
450
- </span>
451
- <svg class="help-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
452
- </button>
453
- <button class="help-action-btn" id="source-gallery">
454
- <span class="help-action-icon"><i data-lucide="image"></i></span>
455
- <span class="help-action-text">
456
- <strong>Escolher da galeria</strong>
457
- <small>Selecionar uma foto existente</small>
458
- </span>
459
- <svg class="help-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
460
- </button>
461
- </div>
462
- <button class="help-cancel" id="source-cancel">Cancelar</button>
463
- </div>
464
-
465
- <!-- ══ MAP LOCATION PICKER ══ -->
466
- <div id="map-picker" class="map-picker hidden">
467
- <div class="map-picker-header">
468
- <button class="back-btn" id="map-picker-cancel"><svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg></button>
469
- <h2>Onde você viu o animal?</h2>
470
- </div>
471
- <div class="map-picker-search">
472
- <svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
473
- <input type="text" id="map-picker-input" placeholder="Buscar endereço ou bairro…" autocomplete="off"/>
474
- <button id="map-picker-locate" title="Usar minha localização">
475
- <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/></svg>
476
- </button>
477
- </div>
478
- <div id="map-picker-results"></div>
479
- <div id="map-picker-map"></div>
480
- <div class="map-picker-pin"><svg viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/></svg></div>
481
- <div class="map-picker-footer">
482
- <div id="map-picker-coords" class="map-picker-coords">Arraste o mapa para posicionar o pin</div>
483
- <button class="btn-primary" id="map-picker-confirm">Confirmar localização</button>
484
- </div>
485
- </div>
486
-
487
- <!-- ══ SCREEN: HELP PROOF ══ -->
488
- <div id="screen-help-proof" class="screen">
489
- <div class="flow-header">
490
- <button class="back-btn" id="help-proof-back"><svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg></button>
491
- <h2>I Helped This Animal</h2>
492
- </div>
493
- <div id="help-proof-animal-row">
494
- <div id="help-proof-animal-photo" class="help-proof-thumb"></div>
495
- <div>
496
- <div id="help-proof-animal-name" class="help-proof-animal-name">—</div>
497
- <div id="help-proof-animal-sub" class="help-proof-animal-sub">—</div>
498
- </div>
499
- </div>
500
- <div class="help-proof-section">
501
- <div class="help-proof-label">What did you do?</div>
502
- <div class="help-type-chips" id="help-type-chips">
503
- <button class="help-type-chip active" data-type="fed"><i data-lucide="utensils"></i> Fed</button>
504
- <button class="help-type-chip" data-type="vet"><i data-lucide="stethoscope"></i> Took to vet</button>
505
- <button class="help-type-chip" data-type="adopted"><i data-lucide="home"></i> Adopted</button>
506
- <button class="help-type-chip" data-type="rescued"><i data-lucide="shield-check"></i> Rescued</button>
507
- <button class="help-type-chip" data-type="other"><i data-lucide="heart"></i> Other</button>
508
- </div>
509
- </div>
510
- <div class="help-proof-section">
511
- <div class="help-proof-label">Add a photo <span class="optional-tag">optional</span></div>
512
- <div id="help-proof-viewfinder" class="help-proof-viewfinder">
513
- <input type="file" id="help-proof-input" accept="image/*"/>
514
- <img id="help-proof-preview" src="" alt="" class="hidden"/>
515
- <div id="help-proof-placeholder">
516
- <svg viewBox="0 0 24 24"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>
517
- <span>Tap to add photo proof</span>
518
- </div>
519
- <div id="help-proof-ai-badge" class="help-proof-ai-badge hidden">
520
- <span class="dot"></span><span id="help-proof-ai-text">Verifying with AI…</span>
521
- </div>
522
- <div id="help-proof-verified-badge" class="help-proof-verified-badge hidden">
523
- <svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
524
- <span id="help-proof-verified-text">Same animal confirmed</span>
525
- </div>
526
- </div>
527
- </div>
528
- <div class="help-proof-section">
529
- <div class="help-proof-label">Tell the story <span class="optional-tag">optional</span></div>
530
- <textarea id="help-proof-notes" rows="3" placeholder="What happened? Where did you take them?"></textarea>
531
- </div>
532
- <button class="btn-primary help-proof-submit" id="help-proof-submit">
533
- <svg viewBox="0 0 24 24"><path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"/></svg>
534
- Register Help
535
- </button>
536
- </div>
537
-
538
- <!-- ══ PHOTO LIGHTBOX ══ -->
539
- <div id="photo-lightbox" class="photo-lightbox hidden" role="dialog">
540
- <div class="lightbox-backdrop"></div>
541
- <div class="lightbox-inner">
542
- <img id="lightbox-img" src="" alt="photo" />
543
- <button id="lightbox-close" aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
544
- </div>
545
- </div>
546
-
547
- <!-- ══ PHOTO CONTEXT MENU ══ -->
548
- <div id="photo-menu" class="photo-menu hidden">
549
- <button id="photo-menu-download">
550
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
551
- Download photo
552
- </button>
553
- </div>
554
-
555
- <!-- ══ BOTTOM NAV ══ -->
556
- <nav id="bottom-nav">
557
- <button class="nav-btn active" data-screen="map"><span class="nav-icon"><i data-lucide="map"></i></span><span>Map</span></button>
558
- <button class="nav-btn" data-screen="register"><span class="nav-icon"><i data-lucide="camera"></i></span><span>Report</span></button>
559
- <button class="nav-btn" data-screen="sightings"><span class="nav-icon"><i data-lucide="eye"></i></span><span>Sightings</span></button>
560
- </nav>
561
- </div><!-- /#app -->
562
- </div><!-- /.phone-frame -->
563
- </div><!-- /.phone-wrap -->
564
-
565
- <!-- ══ RIGHT SIDEBAR (desktop only) ══ -->
566
- <aside id="sidebar-right">
567
- <div class="sidebar-section">
568
- <div class="sidebar-badge-title">Built for</div>
569
- <a class="hackathon-badge" href="https://huggingface.co/build-small-hackathon" target="_blank" rel="noopener">
570
- <span class="hb-icon">🏡</span>
571
- <span class="hb-text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
6
+ <title>PawMap</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.css"/>
8
+ <link rel="preconnect" href="https://fonts.googleapis.com"/>
9
+ <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,400;0,14..32,500;0,14..32,600;0,14..32,700;1,14..32,400&display=swap" rel="stylesheet"/>
10
+ <link rel="stylesheet" href="/static/style.css"/>
11
+ <script src="https://cdn.jsdelivr.net/npm/lucide@0.454.0/dist/umd/lucide.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/lottie-web@5.12.2/build/player/lottie.min.js"></script>
13
+ <script src="https://cdn.jsdelivr.net/npm/exifr@7.1.3/dist/full.umd.js"></script>
14
+ </head>
15
+ <body>
16
+ <div id="desktop-layout">
17
+
18
+ <!-- ══ LEFT SIDEBAR (desktop only) ══ -->
19
+ <aside id="sidebar-left">
20
+ <div class="sidebar-logo">
21
+ <span class="sidebar-paw">🐾</span>
22
+ <span class="sidebar-brand">PawMap</span>
23
+ </div>
24
+ <p class="sidebar-tagline">Collaborative stray animal mapping, powered by AI.</p>
25
+
26
+ <div class="sidebar-divider"></div>
27
+
28
+ <div class="sidebar-section">
29
+ <h3>The problem</h3>
30
+ <p>Independent rescuers in Brasília, DF keep track of entire stray animal colonies in their heads — which ones were neutered, which one got hurt last winter, which one hasn't shown up this week. That knowledge lives in WhatsApp groups and fades when people move on.</p>
31
+ <p>PawMap turns those scattered sightings into a shared, persistent map — one photo at a time.</p>
32
+ </div>
33
+
34
+ <div class="sidebar-divider"></div>
35
+
36
+ <div class="sidebar-section">
37
+ <h3>How it works</h3>
38
+ <div class="how-steps">
39
+ <div class="how-step">
40
+ <div class="how-num"><i data-lucide="camera"></i></div>
41
+ <div class="how-content">
42
+ <strong>Snap a photo</strong>
43
+ <span>Point your camera at any stray dog or cat.</span>
44
+ </div>
45
+ </div>
46
+ <div class="how-connector"></div>
47
+ <div class="how-step">
48
+ <div class="how-num"><i data-lucide="scan-line"></i></div>
49
+ <div class="how-content">
50
+ <strong>AI identifies</strong>
51
+ <span>Species, breed, color and condition — automatically.</span>
52
+ </div>
53
+ </div>
54
+ <div class="how-connector"></div>
55
+ <div class="how-step">
56
+ <div class="how-num"><i data-lucide="git-merge"></i></div>
57
+ <div class="how-content">
58
+ <strong>Smart matching</strong>
59
+ <span>Checks if this animal has been seen before.</span>
60
+ </div>
61
+ </div>
62
+ <div class="how-connector"></div>
63
+ <div class="how-step">
64
+ <div class="how-num"><i data-lucide="map-pin"></i></div>
65
+ <div class="how-content">
66
+ <strong>Map updates</strong>
67
+ <span>Sighting linked to the animal's profile — or a new one is created.</span>
68
+ </div>
69
+ </div>
70
+ </div>
71
+ </div>
72
+
73
+ </aside>
74
+
75
+ <div class="phone-wrap">
76
+ <div class="better-on-mobile"><i data-lucide="smartphone"></i> Better on mobile</div>
77
+ <div class="phone-frame">
78
+ <div class="phone-btn phone-btn-vol-up"></div>
79
+ <div class="phone-btn phone-btn-vol-down"></div>
80
+ <div class="phone-btn phone-btn-power"></div>
81
+ <div id="app">
82
+
83
+ <!-- ══ ONBOARDING ══ -->
84
+ <div id="screen-splash">
85
+ <button id="ob-skip">Skip</button>
86
+
87
+ <!-- Steps -->
88
+ <div id="ob-track">
89
+
90
+ <!-- Step 1 -->
91
+ <div class="ob-step">
92
+ <div class="ob-lottie-wrap">
93
+ <div id="lottie-1" class="ob-lottie"></div>
94
+ <div class="ob-lottie-fallback"><i data-lucide="camera"></i></div>
95
+ </div>
96
+ <div class="ob-text">
97
+ <div class="ob-step-label">Step 1 of 4</div>
98
+ <h2>Help a stray find its way</h2>
99
+ <p>Every street dog and cat deserves to be seen. PawMap lets your community map them together — one photo at a time.</p>
100
+ </div>
101
+ </div>
102
+
103
+ <!-- Step 2 -->
104
+ <div class="ob-step">
105
+ <div class="ob-lottie-wrap">
106
+ <div id="lottie-2" class="ob-lottie"></div>
107
+ <div class="ob-lottie-fallback"><i data-lucide="scan-line"></i></div>
108
+ </div>
109
+ <div class="ob-text">
110
+ <div class="ob-step-label">Step 2 of 4</div>
111
+ <h2>Snap a photo — AI does the rest</h2>
112
+ <p>Point your camera and tap. Our AI instantly identifies species, breed, color, and condition. No forms to fill.</p>
113
+ </div>
114
+ </div>
115
+
116
+ <!-- Step 3 -->
117
+ <div class="ob-step">
118
+ <div class="ob-lottie-wrap">
119
+ <div id="lottie-3" class="ob-lottie"></div>
120
+ <div class="ob-lottie-fallback"><i data-lucide="refresh-cw"></i></div>
121
+ </div>
122
+ <div class="ob-text">
123
+ <div class="ob-step-label">Step 3 of 4</div>
124
+ <h2>AI matches the same animal</h2>
125
+ <p>Seen this dog before? The AI compares your photo with previous sightings and links them automatically — building each animal's story.</p>
126
+ </div>
127
+ </div>
128
+
129
+ <!-- Step 4 -->
130
+ <div class="ob-step">
131
+ <div class="ob-lottie-wrap">
132
+ <div id="lottie-4" class="ob-lottie"></div>
133
+ <div class="ob-lottie-fallback"><i data-lucide="home"></i></div>
134
+ </div>
135
+ <div class="ob-text">
136
+ <div class="ob-step-label">Step 4 of 4</div>
137
+ <h2>Every map pin is a chance</h2>
138
+ <p>Mapping a dog brings more chances to find a forever family — or get help from the community when it's needed most.</p>
139
+ </div>
140
+ </div>
141
+
142
+ </div><!-- /ob-track -->
143
+
144
+ <!-- Dots -->
145
+ <div id="ob-dots">
146
+ <span class="ob-dot active"></span>
147
+ <span class="ob-dot"></span>
148
+ <span class="ob-dot"></span>
149
+ <span class="ob-dot"></span>
150
+ </div>
151
+
152
+ <!-- Actions -->
153
+ <div id="ob-actions">
154
+ <button id="ob-next">Next →</button>
155
+ </div>
156
+
157
+ </div><!-- /screen-splash -->
158
+
159
+ <!-- ══ HEADER ══ -->
160
+ <header id="header">
161
+ <button class="icon-btn" id="menu-btn" aria-label="Menu">
162
+ <svg viewBox="0 0 24 24"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
163
+ </button>
164
+ <span class="logo">PawMap</span>
165
+ <button class="icon-btn" aria-label="Options">
166
+ <svg viewBox="0 0 24 24"><circle cx="12" cy="5" r="1.5" fill="#fff" stroke="none"/><circle cx="12" cy="12" r="1.5" fill="#fff" stroke="none"/><circle cx="12" cy="19" r="1.5" fill="#fff" stroke="none"/></svg>
167
+ </button>
168
+ </header>
169
+
170
+ <!-- ══ FILTER ROW ══ -->
171
+ <div id="filter-row">
172
+ <button class="chip active" data-species="all">All</button>
173
+ <button class="chip" data-species="dog"><i data-lucide="dog"></i> Dogs</button>
174
+ <button class="chip" data-species="cat"><i data-lucide="cat"></i> Cats</button>
175
+ <button class="chip" data-timeframe="today">Today</button>
176
+ <button class="chip" data-timeframe="week">This Week</button>
177
+ </div>
178
+
179
+ <!-- ══ SCREEN: MAP ══ -->
180
+ <div id="screen-map" class="screen active">
181
+ <div id="map"></div>
182
+ <div id="map-empty">No sightings yet</div>
183
+ <div id="sighting-card" class="hidden">
184
+ <div class="card-photo" id="card-photo"><i data-lucide="paw-print"></i></div>
185
+ <div class="card-info">
186
+ <div class="card-top"><span class="badge" id="card-badge">Dog</span><span class="card-time" id="card-time"></span></div>
187
+ <div class="card-location" id="card-location"></div>
188
+ <div class="card-sub" id="card-sub"></div>
189
+ </div>
190
+ <button class="btn-ficha" id="card-btn">View profile</button>
191
+ </div>
192
+ </div>
193
+
194
+ <!-- ══ SCREEN: REGISTER ══ -->
195
+ <div id="screen-register" class="screen">
196
+ <input type="file" id="photo-input" accept="image/*"/>
197
+ <div id="viewfinder">
198
+ <div id="gps-pill">
199
+ <svg viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/></svg>
200
+ <span id="gps-text">Add a photo to detect location</span>
201
+ </div>
202
+ <img id="photo-preview" src="" alt="photo"/>
203
+ <div id="camera-placeholder">
204
+ <svg viewBox="0 0 24 24"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>
205
+ <p>Tap the button to take a photo</p>
206
+ </div>
207
+ <button id="shutter-btn" aria-label="Take photo">
208
+ <svg viewBox="0 0 24 24"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>
209
+ </button>
210
+ </div>
211
+ <div id="reg-sheet">
212
+ <div class="drag-handle"></div>
213
+ <div id="notes-row">
214
+ <svg viewBox="0 0 24 24"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
215
+ <textarea id="notes-input" rows="1" placeholder="Add a note (optional)"></textarea>
216
+ </div>
217
+ <div id="locate-options" style="display:none">
218
+ <button class="btn-locate" id="gps-btn">
219
+ <svg viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/></svg>
220
+ Usar localização atual
221
+ </button>
222
+ <button class="btn-locate alt" id="map-btn">
223
+ <svg viewBox="0 0 24 24"><polygon points="3 6 9 3 15 6 21 3 21 18 15 21 9 18 3 21"/><line x1="9" y1="3" x2="9" y2="18"/><line x1="15" y1="6" x2="15" y2="21"/></svg>
224
+ Selecionar no mapa
225
+ </button>
226
+ </div>
227
+ <button class="btn-primary" id="submit-reg-btn" disabled>
228
+ <svg viewBox="0 0 24 24"><path d="M22 2L11 13"/><path d="M22 2l-7 20-4-9-9-4 20-7z"/></svg>
229
+ Report Sighting
230
+ </button>
231
+ </div>
232
+ </div>
233
+
234
+ <!-- ══ SCREEN: ANALYSIS ══ -->
235
+ <div id="screen-analysis" class="screen">
236
+ <div class="flow-header">
237
+ <button class="back-btn" id="analysis-back"><svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg></button>
238
+ <h2>Analyzing Sighting</h2>
239
+ </div>
240
+ <div id="analysis-photo-wrap">
241
+ <img id="analysis-photo" src="" alt="photo"/>
242
+ <div id="ai-badge"><span class="dot"></span><span id="ai-badge-text">AI Analyzing...</span></div>
243
+ <div id="animal-result-badge"><svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg><span id="result-badge-text">Caramel Dog</span></div>
244
+ </div>
245
+ <div class="analysis-card">
246
+ <h3>Identified Details <button id="edit-btn"><i data-lucide="pencil"></i></button></h3>
247
+ <p class="subtitle">AI filled in these details. Correct if needed.</p>
248
+ <div class="dropdowns-grid">
249
+ <div class="dropdown-field"><label>Species</label><select id="sel-species"><option value="dog">Dog</option><option value="cat">Cat</option></select></div>
250
+ <div class="dropdown-field"><label>Breed (Estimated)</label><select id="sel-breed"></select></div>
251
+ <div class="dropdown-field"><label>Primary Color</label><select id="sel-color"><option value="Black">Black</option><option value="White">White</option><option value="Gray">Gray</option><option value="Brown">Brown</option><option value="Chocolate">Chocolate</option><option value="Caramel">Caramel</option><option value="Tan">Tan</option><option value="Golden">Golden</option><option value="Cream">Cream</option><option value="Fawn">Fawn</option><option value="Orange">Orange</option><option value="Ginger">Ginger</option><option value="Red">Red</option><option value="Sable">Sable</option><option value="Cinnamon">Cinnamon</option><option value="Blue">Blue (gray)</option><option value="Lilac">Lilac</option><option value="Tabby">Tabby</option><option value="Tuxedo">Tuxedo</option><option value="Calico">Calico</option><option value="Tortoiseshell">Tortoiseshell</option><option value="Tricolor">Tricolor</option><option value="Bicolor">Bicolor</option><option value="Brindle">Brindle</option><option value="Merle">Merle</option><option value="Spotted">Spotted</option><option value="Mixed">Mixed</option></select></div>
252
+ <div class="dropdown-field"><label>Size</label><select id="sel-size"><option value="Tiny">Tiny</option><option value="Small">Small</option><option value="Medium">Medium</option><option value="Large">Large</option><option value="Extra Large">Extra Large</option><option value="Giant">Giant</option></select></div>
253
+ </div>
254
+ <div class="condition-label">Condition (Optional)</div>
255
+ <div class="condition-chips">
256
+ <button class="cond-chip" data-val="Injured"><span class="check"><i data-lucide="check"></i></span> Injured</button>
257
+ <button class="cond-chip" data-val="Looks Healthy"><span class="check"><i data-lucide="check"></i></span> Looks Healthy</button>
258
+ <button class="cond-chip" data-val="Has Collar"><span class="check"><i data-lucide="check"></i></span> Has Collar</button>
259
+ </div>
260
+ </div>
261
+ <div class="analysis-card" id="similar-section">
262
+ <h3>Similar animals nearby</h3>
263
+ <p class="subtitle">Found by AI for context — recognition is automatic.</p>
264
+ <div class="similar-scroll" id="similar-scroll"></div>
265
+ </div>
266
+ <div class="analysis-card">
267
+ <div class="dropdown-field">
268
+ <label>Name <span class="optional-tag">optional</span></label>
269
+ <input type="text" id="animal-name-input" placeholder="e.g. Caputino, Bolinha, Luna…" maxlength="40" autocomplete="off"/>
270
+ </div>
271
+ </div>
272
+ <div id="analysis-actions">
273
+ <button class="btn-primary" id="confirm-btn">Confirm & Report →</button>
274
+ <button class="btn-outline" id="discard-btn">Discard Photo</button>
275
+ </div>
276
+ </div>
277
+
278
+ <!-- ══ SCREEN: CONFIRM ══ -->
279
+ <div id="screen-confirm" class="screen">
280
+ <div id="confirm-inner">
281
+ <div id="confirm-photo-wrap">
282
+ <div id="confirm-photo"><i data-lucide="paw-print"></i></div>
283
+ <div id="confirm-check"><svg viewBox="0 0 24 24"><polyline points="20 6 9 20 4 14"/></svg></div>
284
+ </div>
285
+ <div id="confirm-title">Sighting<br>Reported!</div>
286
+ <div id="confirm-card">
287
+ <div class="confirm-row">
288
+ <span class="confirm-row-label"><svg viewBox="0 0 24 24"><path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>Animal:</span>
289
+ <span class="confirm-row-value" id="confirm-animal">—</span>
290
+ </div>
291
+ <div class="confirm-row">
292
+ <span class="confirm-row-label"><svg viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/></svg>Location:</span>
293
+ <span class="confirm-row-value" id="confirm-local"></span>
294
+ </div>
295
+ <div class="confirm-row">
296
+ <span class="confirm-row-label"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>Time:</span>
297
+ <span class="confirm-row-value" id="confirm-hora">—</span>
298
+ </div>
299
+ </div>
300
+ <div id="confirm-id-grid" class="confirm-id-grid"></div>
301
+ <div class="confirm-btns">
302
+ <button class="btn-primary" id="register-another-btn"><svg viewBox="0 0 24 24"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>Report Another</button>
303
+ <button class="btn-secondary" id="go-map-btn"><svg viewBox="0 0 24 24"><polygon points="3 6 9 3 15 6 21 3 21 18 15 21 9 18 3 21"/></svg>View on Map</button>
304
+ </div>
305
+ </div>
306
+ </div>
307
+
308
+ <!-- ══ SCREEN: SIGHTINGS LIST ══ -->
309
+ <div id="screen-sightings" class="screen">
310
+ <div id="sightings-header">
311
+ <span id="sightings-count">Loading...</span>
312
+ <button id="refresh-btn" title="Refresh"><i data-lucide="refresh-cw"></i></button>
313
+ </div>
314
+ <div id="animals-list"></div>
315
+ </div>
316
+
317
+ <!-- ══ SCREEN: PROFILE / FICHA ══ -->
318
+ <div id="screen-profile" class="screen">
319
+ <div class="profile-scroll">
320
+ <!-- Hero -->
321
+ <div class="profile-hero">
322
+ <img class="profile-hero-img" id="profile-hero-img" src="" alt=""/>
323
+ <div class="hero-gradient"></div>
324
+ <div class="hero-top-btns">
325
+ <button class="hero-btn" id="profile-back-btn"><svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg></button>
326
+ <button class="hero-btn" id="profile-share-btn"><svg viewBox="0 0 24 24"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg></button>
327
+ </div>
328
+ <div id="profile-sightings-badge">
329
+ <svg viewBox="0 0 24 24"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
330
+ <span id="profile-badge-text">0 sightings</span>
331
+ </div>
332
+ </div>
333
+
334
+ <!-- Content -->
335
+ <div class="profile-content">
336
+ <h1 id="profile-title">...</h1>
337
+ <div id="profile-status"><span class="status-dot"></span><span id="profile-status-text">...</span></div>
338
+ <div id="profile-helped-banner" style="display:none">
339
+ <i data-lucide="heart"></i>
340
+ <span>This animal has been helped by the community</span>
341
+ </div>
342
+ <div id="profile-ai-desc" class="ai-desc-callout" style="display:none">
343
+ <span class="ai-label">AI</span>
344
+ <p id="profile-ai-text"></p>
345
+ </div>
346
+
347
+ <!-- Identification -->
348
+ <div class="profile-section">
349
+ <div class="section-title">Identification</div>
350
+ <div class="id-grid">
351
+ <div class="id-cell"><div class="id-cell-label">Species</div><div class="id-cell-value" id="prof-species">—</div></div>
352
+ <div class="id-cell"><div class="id-cell-label">Breed</div><div class="id-cell-value" id="prof-breed">—</div></div>
353
+ <div class="id-cell"><div class="id-cell-label">Size</div><div class="id-cell-value" id="prof-size">—</div></div>
354
+ <div class="id-cell"><div class="id-cell-label">Color</div><div class="id-cell-value" id="prof-color">—</div></div>
355
+ </div>
356
+ </div>
357
+
358
+ <!-- Gallery -->
359
+ <div class="profile-section">
360
+ <div class="gallery-header">
361
+ <div class="section-title" style="margin-bottom:0">Sightings Gallery</div>
362
+ <button class="gallery-see-all">See all</button>
363
+ </div>
364
+ <div class="gallery-scroll" id="profile-gallery"></div>
365
+ </div>
366
+
367
+ <!-- Community Help -->
368
+ <div class="profile-section" id="profile-help-section" style="display:none">
369
+ <div class="section-title help-section-title">
370
+ <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="var(--green)" stroke-width="2"><path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"/></svg>
371
+ Community Help
372
+ </div>
373
+ <div id="profile-help-list"></div>
374
+ </div>
375
+
376
+ <!-- Trajectory -->
377
+ <div class="profile-section">
378
+ <div class="section-title">Recent Path</div>
379
+ <div id="trajectory-map"></div>
380
+ </div>
381
+ </div>
382
+ </div>
383
+
384
+ <!-- Footer -->
385
+ <div class="profile-footer">
386
+ <button class="btn-adopt" id="btn-adopt"><i data-lucide="heart"></i> I Want to Adopt / Help</button>
387
+ </div>
388
+ </div>
389
+
390
+ <!-- ══ HELP BOTTOM SHEET ══ -->
391
+ <div id="help-overlay" class="hidden"></div>
392
+ <div id="help-sheet" class="help-sheet hidden">
393
+ <div class="drag-handle"></div>
394
+ <div id="help-animal-row">
395
+ <div id="help-animal-photo"></div>
396
+ <div id="help-animal-info">
397
+ <div id="help-animal-name">—</div>
398
+ <div id="help-animal-sub">—</div>
399
+ </div>
400
+ </div>
401
+ <div class="help-actions">
402
+ <button class="help-action-btn" id="help-share">
403
+ <span class="help-action-icon"><i data-lucide="share-2"></i></span>
404
+ <span class="help-action-text">
405
+ <strong>Share this animal</strong>
406
+ <small>Send via WhatsApp or copy link</small>
407
+ </span>
408
+ <svg class="help-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
409
+ </button>
410
+ <button class="help-action-btn" id="help-directions">
411
+ <span class="help-action-icon"><i data-lucide="map-pin"></i></span>
412
+ <span class="help-action-text">
413
+ <strong>Get directions</strong>
414
+ <small>Navigate to last known location</small>
415
+ </span>
416
+ <svg class="help-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
417
+ </button>
418
+ <button class="help-action-btn" id="help-helped">
419
+ <span class="help-action-icon"><i data-lucide="check-circle"></i></span>
420
+ <span class="help-action-text">
421
+ <strong>I helped this animal</strong>
422
+ <small>Log that you fed, treated, or fostered them</small>
423
+ </span>
424
+ <svg class="help-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
425
+ </button>
426
+ </div>
427
+ <button class="help-cancel" id="help-cancel">Cancel</button>
428
+ </div>
429
+
430
+ <!-- ══ HELPED CONFIRM ══ -->
431
+ <div id="helped-confirm" class="helped-confirm hidden">
432
+ <div class="helped-inner">
433
+ <div class="helped-icon-wrap"><i data-lucide="heart"></i></div>
434
+ <h3>Thank you</h3>
435
+ <p>Your help has been recorded.<br>Every act of care makes a difference.</p>
436
+ <button id="helped-ok">Done</button>
437
+ </div>
438
+ </div>
439
+
440
+ <!-- ══ IMAGE SOURCE CHOOSER ══ -->
441
+ <div id="source-overlay" class="hidden"></div>
442
+ <div id="source-sheet" class="help-sheet hidden">
443
+ <div class="drag-handle"></div>
444
+ <div class="help-actions">
445
+ <button class="help-action-btn" id="source-camera">
446
+ <span class="help-action-icon"><i data-lucide="camera"></i></span>
447
+ <span class="help-action-text">
448
+ <strong>Tirar foto</strong>
449
+ <small>Abrir a câmera</small>
450
+ </span>
451
+ <svg class="help-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
452
+ </button>
453
+ <button class="help-action-btn" id="source-gallery">
454
+ <span class="help-action-icon"><i data-lucide="image"></i></span>
455
+ <span class="help-action-text">
456
+ <strong>Escolher da galeria</strong>
457
+ <small>Selecionar uma foto existente</small>
458
+ </span>
459
+ <svg class="help-chevron" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
460
+ </button>
461
+ </div>
462
+ <button class="help-cancel" id="source-cancel">Cancelar</button>
463
+ </div>
464
+
465
+ <!-- ══ MAP LOCATION PICKER ══ -->
466
+ <div id="map-picker" class="map-picker hidden">
467
+ <div class="map-picker-header">
468
+ <button class="back-btn" id="map-picker-cancel"><svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg></button>
469
+ <h2>Onde você viu o animal?</h2>
470
+ </div>
471
+ <div class="map-picker-search">
472
+ <svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
473
+ <input type="text" id="map-picker-input" placeholder="Buscar endereço ou bairro…" autocomplete="off"/>
474
+ <button id="map-picker-locate" title="Usar minha localização">
475
+ <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/></svg>
476
+ </button>
477
+ </div>
478
+ <div id="map-picker-results"></div>
479
+ <div id="map-picker-map"></div>
480
+ <div class="map-picker-pin"><svg viewBox="0 0 24 24"><path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"/><circle cx="12" cy="9" r="2.5"/></svg></div>
481
+ <div class="map-picker-footer">
482
+ <div id="map-picker-coords" class="map-picker-coords">Arraste o mapa para posicionar o pin</div>
483
+ <button class="btn-primary" id="map-picker-confirm">Confirmar localização</button>
484
+ </div>
485
+ </div>
486
+
487
+ <!-- ══ SCREEN: HELP PROOF ══ -->
488
+ <div id="screen-help-proof" class="screen">
489
+ <div class="flow-header">
490
+ <button class="back-btn" id="help-proof-back"><svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg></button>
491
+ <h2>I Helped This Animal</h2>
492
+ </div>
493
+ <div id="help-proof-animal-row">
494
+ <div id="help-proof-animal-photo" class="help-proof-thumb"></div>
495
+ <div>
496
+ <div id="help-proof-animal-name" class="help-proof-animal-name">—</div>
497
+ <div id="help-proof-animal-sub" class="help-proof-animal-sub">—</div>
498
+ </div>
499
+ </div>
500
+ <div class="help-proof-section">
501
+ <div class="help-proof-label">What did you do?</div>
502
+ <div class="help-type-chips" id="help-type-chips">
503
+ <button class="help-type-chip active" data-type="fed"><i data-lucide="utensils"></i> Fed</button>
504
+ <button class="help-type-chip" data-type="vet"><i data-lucide="stethoscope"></i> Took to vet</button>
505
+ <button class="help-type-chip" data-type="adopted"><i data-lucide="home"></i> Adopted</button>
506
+ <button class="help-type-chip" data-type="rescued"><i data-lucide="shield-check"></i> Rescued</button>
507
+ <button class="help-type-chip" data-type="other"><i data-lucide="heart"></i> Other</button>
508
+ </div>
509
+ </div>
510
+ <div class="help-proof-section">
511
+ <div class="help-proof-label">Add a photo <span class="optional-tag">optional</span></div>
512
+ <div id="help-proof-viewfinder" class="help-proof-viewfinder">
513
+ <input type="file" id="help-proof-input" accept="image/*"/>
514
+ <img id="help-proof-preview" src="" alt="" class="hidden"/>
515
+ <div id="help-proof-placeholder">
516
+ <svg viewBox="0 0 24 24"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>
517
+ <span>Tap to add photo proof</span>
518
+ </div>
519
+ <div id="help-proof-ai-badge" class="help-proof-ai-badge hidden">
520
+ <span class="dot"></span><span id="help-proof-ai-text">Verifying with AI…</span>
521
+ </div>
522
+ <div id="help-proof-verified-badge" class="help-proof-verified-badge hidden">
523
+ <svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>
524
+ <span id="help-proof-verified-text">Same animal confirmed</span>
525
+ </div>
526
+ </div>
527
+ </div>
528
+ <div class="help-proof-section">
529
+ <div class="help-proof-label">Tell the story <span class="optional-tag">optional</span></div>
530
+ <textarea id="help-proof-notes" rows="3" placeholder="What happened? Where did you take them?"></textarea>
531
+ </div>
532
+ <button class="btn-primary help-proof-submit" id="help-proof-submit">
533
+ <svg viewBox="0 0 24 24"><path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"/></svg>
534
+ Register Help
535
+ </button>
536
+ </div>
537
+
538
+ <!-- ══ PHOTO LIGHTBOX ══ -->
539
+ <div id="photo-lightbox" class="photo-lightbox hidden" role="dialog">
540
+ <div class="lightbox-backdrop"></div>
541
+ <div class="lightbox-inner">
542
+ <img id="lightbox-img" src="" alt="photo" />
543
+ <button id="lightbox-close" aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
544
+ </div>
545
+ </div>
546
+
547
+ <!-- ══ PHOTO CONTEXT MENU ══ -->
548
+ <div id="photo-menu" class="photo-menu hidden">
549
+ <button id="photo-menu-download">
550
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
551
+ Download photo
552
+ </button>
553
+ </div>
554
+
555
+ <!-- ══ BOTTOM NAV ══ -->
556
+ <nav id="bottom-nav">
557
+ <button class="nav-btn active" data-screen="map"><span class="nav-icon"><i data-lucide="map"></i></span><span>Map</span></button>
558
+ <button class="nav-btn" data-screen="register"><span class="nav-icon"><i data-lucide="camera"></i></span><span>Report</span></button>
559
+ <button class="nav-btn" data-screen="sightings"><span class="nav-icon"><i data-lucide="eye"></i></span><span>Sightings</span></button>
560
+ </nav>
561
+ </div><!-- /#app -->
562
+ </div><!-- /.phone-frame -->
563
+ </div><!-- /.phone-wrap -->
564
+
565
+ <!-- ══ RIGHT SIDEBAR (desktop only) ══ -->
566
+ <aside id="sidebar-right">
567
+ <div class="sidebar-section">
568
+ <div class="sidebar-badge-title">Built for</div>
569
+ <a class="hackathon-badge" href="https://huggingface.co/build-small-hackathon" target="_blank" rel="noopener">
570
+ <span class="hb-icon">🏡</span>
571
+ <span class="hb-text">
572
+ <strong>Build Small Hackathon 2026</strong>
573
+ <small>Backyard AI track · Hugging Face</small>
574
+ </span>
575
+ </a>
576
+ </div>
577
+
578
+ <div class="sidebar-divider"></div>
579
+
580
+ <div class="sidebar-section">
581
+ <h3>Tech stack</h3>
582
+ <div class="stack-list">
583
+ <div class="stack-row"><span class="stack-label">Vision AI</span><span class="stack-value">Nemotron Omni 30B</span></div>
584
+ <div class="stack-row"><span class="stack-label">Embeddings</span><span class="stack-value">all-MiniLM-L6-v2</span></div>
585
+ <div class="stack-row"><span class="stack-label">Matching</span><span class="stack-value">Cosine similarity</span></div>
586
+ <div class="stack-row"><span class="stack-label">Map</span><span class="stack-value">Leaflet.js + OSM</span></div>
587
+ <div class="stack-row"><span class="stack-label">Frontend</span><span class="stack-value">gr.Server SPA</span></div>
588
+ <div class="stack-row"><span class="stack-label">Storage</span><span class="stack-value">SQLite</span></div>
589
+ </div>
590
+ </div>
591
+
592
+ <div class="sidebar-divider"></div>
593
+
594
+ <div class="sidebar-section">
595
+ <h3>Help an animal today</h3>
596
+ <p>Open a profile from the map, tap <strong>I Want to Help</strong>, and log what you did — fed, treated, fostered. A photo proves it; the AI verifies it's the same animal.</p>
597
+ </div>
598
+
599
+ <div class="sidebar-divider"></div>
600
+
601
+ <div class="sidebar-section sidebar-links">
602
+ <a href="https://huggingface.co/spaces/build-small-hackathon/viralata-mapper" target="_blank" rel="noopener">Live Space ↗</a>
603
+ <a href="https://huggingface.co/datasets/build-small-hackathon/viralata-mapper-storage" target="_blank" rel="noopener">Dataset ↗</a>
604
+ </div>
605
+ </aside>
606
+
607
+ </div><!-- /desktop-layout -->
608
+
609
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.min.js"></script>
610
+ <script src="/static/app.js"></script>
611
+ <script src="/static/help-proof.js"></script>
612
+ <script>
613
+ [1,2,3,4].forEach(function(i) {
614
+ lottie.loadAnimation({
615
+ container: document.getElementById('lottie-' + i),
616
+ renderer: 'svg',
617
+ loop: true,
618
+ autoplay: true,
619
+ path: '/static/lottie/step' + i + '.json'
620
+ });
621
+ });
622
+ </script>
623
+ </body>
624
+ </html>