···
13
13
border: 1px solid var(--card-border);
14
14
border-radius: 12px;
15
15
box-shadow: var(--card-shadow, 0 2px 8px rgba(0,0,0,0.1));
16
16
-
padding: 30px 40px;
16
16
+
padding: 40px;
17
17
width: 100%;
18
18
max-width: 450px;
19
19
text-align: center;
···
55
55
.login-input-field {
56
56
border: 2px solid var(--card-border);
57
57
border-radius: 6px;
58
58
-
padding: 10px 12px;
58
58
+
padding: 9px;
59
59
font-size: 1em;
60
60
background-color: var(--navbar-bg);
61
61
color: var(--text);
62
62
transition: all 0.3s ease;
63
63
font-family: inherit;
64
64
text-align: center;
65
65
-
width: auto;
66
66
-
max-width: 100%;
65
65
+
width: 100%;
66
66
+
box-sizing: border-box;
67
67
+
margin: 0;
67
68
}
68
69
69
70
.login-input-field:hover,
···
78
79
color: var(--button-text);
79
80
border: none;
80
81
border-radius: 6px;
81
81
-
padding: 10px 20px;
82
82
+
padding: 10px 15px;
82
83
font-weight: 700;
83
84
font-size: 1em;
84
85
cursor: pointer;
85
86
transition: background-color 0.3s ease;
86
86
-
width: fit-content;
87
87
-
margin: 10px auto 0;
87
87
+
width: auto;
88
88
+
margin: 0 auto;
88
89
}
89
90
90
91
.login-submit-button:hover {
···
121
122
.login-privacy-note {
122
123
font-size: 0.85em;
123
124
color: var(--text-muted, #6c757d);
124
124
-
margin-top: 20px;
125
125
+
margin-top: 10px;
125
126
text-align: center;
126
127
}
127
128
···
40
40
return (
41
41
<div className="login-container">
42
42
<div className="login-card">
43
43
-
<h1>Login to Cred Blue</h1>
44
44
-
<p>Enter your Bluesky handle (e.g., yourname.bsky.social) or leave blank to use bsky.social.</p>
43
43
+
<h1>Login to cred.blue</h1>
44
44
+
<p>Enter your Bluesky or ATProto handle (e.g., yourname.bsky.social)</p>
45
45
<form onSubmit={handleSubmit} className="login-form">
46
46
<input
47
47
type="text"
···
59
59
disabled={loading}
60
60
className="login-submit-button"
61
61
>
62
62
-
{loading ? 'Processing...' : 'Login with Bluesky'}
62
62
+
{loading ? 'Processing...' : 'Login'}
63
63
</button>
64
64
</form>
65
65
<p className="login-privacy-note">
66
66
-
We use official Bluesky authentication. We don't see or store your password.
66
66
+
We use official Bluesky/ATProto OAuth to securely process your login.
67
67
</p>
68
68
</div>
69
69
</div>
···
38
38
gap: 10px;
39
39
}
40
40
41
41
+
.verifier-list {
42
42
+
margin-top: 10px;
43
43
+
}
44
44
+
41
45
.verifier-user-info {
42
46
font-size: 0.9em;
43
47
color: var(--text-muted, var(--text));
···
232
236
233
237
/* Verification Lists */
234
238
.verifier-list-header {
239
239
+
display: flex; /* Add this to make flexbox work */
235
240
justify-content: space-between; /* Align button to the right */
236
241
align-items: center;
237
237
-
margin-bottom: 10px; /* Space above list */
238
242
}
239
243
.verifier-list-header h2 {
240
244
margin: 0;
···
283
287
border-left: 5px solid var(--warning-border, orange); /* Highlight invalid items */
284
288
}
285
289
290
290
+
/* New styles for verification list profile links */
291
291
+
.verifier-profile-link {
292
292
+
display: flex;
293
293
+
flex-direction: column;
294
294
+
text-decoration: none;
295
295
+
color: var(--text);
296
296
+
margin-bottom: 5px;
297
297
+
}
298
298
+
299
299
+
.verifier-profile-link:hover {
300
300
+
text-decoration: underline;
301
301
+
}
302
302
+
303
303
+
.verifier-display-name {
304
304
+
font-weight: bold;
305
305
+
font-size: 1.05em;
306
306
+
margin-right: 5px;
307
307
+
}
308
308
+
309
309
+
/* Validity status indicators */
310
310
+
.verifier-validity-status {
311
311
+
display: inline-block;
312
312
+
font-size: 0.9em;
313
313
+
padding: 3px 6px;
314
314
+
border-radius: 4px;
315
315
+
margin-top: 5px;
316
316
+
}
317
317
+
318
318
+
.verifier-validity-status.valid {
319
319
+
background-color: var(--success-bg, rgba(0, 128, 0, 0.1));
320
320
+
color: var(--success-text, green);
321
321
+
}
322
322
+
323
323
+
.verifier-validity-status.invalid {
324
324
+
background-color: var(--error-bg, rgba(255, 0, 0, 0.1));
325
325
+
color: var(--error-text, red);
326
326
+
}
327
327
+
328
328
+
.verifier-validity-status.checking {
329
329
+
background-color: var(--warning-bg, rgba(255, 165, 0, 0.1));
330
330
+
color: var(--warning-text, orange);
331
331
+
}
332
332
+
333
333
+
/* Dark mode compatibility */
334
334
+
.dark-mode .verifier-validity-status.valid {
335
335
+
background-color: var(--success-bg-dark, rgba(0, 128, 0, 0.3));
336
336
+
color: var(--success-text-dark, #a3e9a4);
337
337
+
}
338
338
+
339
339
+
.dark-mode .verifier-validity-status.invalid {
340
340
+
background-color: var(--error-bg-dark, rgba(255, 0, 0, 0.2));
341
341
+
color: var(--error-text-dark, #f5c6cb);
342
342
+
}
343
343
+
344
344
+
.dark-mode .verifier-validity-status.checking {
345
345
+
background-color: var(--warning-bg-dark, rgba(255, 165, 0, 0.2));
346
346
+
color: var(--warning-text-dark, #ffe4b5);
347
347
+
}
348
348
+
349
349
+
/* Remove the now-unused validity warning box styles */
286
350
.verifier-validity-warning {
287
287
-
margin-top: 10px;
288
288
-
padding: 10px;
289
289
-
background-color: var(--warning-bg, #fff3cd);
290
290
-
border: 1px solid var(--warning-border, #ffeeba);
291
291
-
color: var(--warning-text, #856404);
292
292
-
border-radius: 4px;
293
293
-
font-size: 0.9em;
351
351
+
display: none;
294
352
}
295
295
-
.verifier-validity-warning p {
296
296
-
margin: 5px 0;
297
297
-
color: var(--warning-text, #856404); /* Ensure text color consistency */
298
298
-
text-align: left;
353
353
+
354
354
+
/* Media query for mobile optimization */
355
355
+
@media (max-width: 480px) {
356
356
+
.verifier-list-item {
357
357
+
flex-direction: column;
358
358
+
}
359
359
+
360
360
+
.verifier-list-item-content {
361
361
+
width: 100%;
362
362
+
margin-bottom: 10px;
363
363
+
}
364
364
+
365
365
+
.verifier-list-item-actions {
366
366
+
align-self: flex-end;
367
367
+
}
299
368
}
300
369
301
370
/* Network Verifications */
···
724
724
let message = '...'; let icon = '⏳'; let statusClass = 'verifier-idle-status';
725
725
switch (status) {
726
726
case 'checking': message = `Checking ${verifierId}...`; icon = '⏳'; statusClass = 'verifier-checking-status'; break;
727
727
-
case 'verified': message = `Verified by ${verifierId}.`; icon = '✅'; statusClass = 'verifier-verified-status'; break;
728
728
-
case 'not_verified': message = `Not verified by ${verifierId}.`; icon = '❌'; statusClass = 'verifier-not-verified-status'; break;
729
729
-
case 'error': message = `Error checking ${verifierId}.`; icon = '⚠️'; statusClass = 'verifier-error-status'; break;
730
730
-
default: message = `Pending check for ${verifierId}.`;
727
727
+
case 'verified': message = `Verified by ${verifierId}`; icon = '✅'; statusClass = 'verifier-verified-status'; break;
728
728
+
case 'not_verified': message = `Not verified by ${verifierId}`; icon = '❌'; statusClass = 'verifier-not-verified-status'; break;
729
729
+
case 'error': message = `Error checking ${verifierId}`; icon = '⚠️'; statusClass = 'verifier-error-status'; break;
730
730
+
default: message = `Pending check for ${verifierId}`;
731
731
}
732
732
return (<p key={verifierId} className={`verifier-official-verifier-note ${statusClass}`}>{icon} {message}</p>);
733
733
})}
···
785
785
{verifications.map((verification) => (
786
786
<li key={verification.uri} className={`verifier-list-item ${verification.validityChecked && !verification.isValid ? 'verifier-list-item-invalid' : ''}`}>
787
787
<div className="verifier-list-item-content">
788
788
-
<div style={{ fontWeight: 'bold' }}>{verification.displayName}</div>
789
789
-
<div className="verifier-list-item-handle">@{verification.handle}</div>
790
790
-
<div className="verifier-list-item-date">Verified: {new Date(verification.createdAt).toLocaleString()}</div>
791
791
-
{verification.validityChecked && !verification.isValid && (
792
792
-
<div className="verifier-validity-warning">
793
793
-
{verification.validityError ? (<p>⚠️ Couldn't check profile</p>) : (<><p><strong>⚠️ Profile changed</strong></p><p><span>Now: @{verification.currentHandle}</span><br /><span>Name: {verification.currentDisplayName}</span></p></>)}
794
794
-
</div>
788
788
+
<a href={`https://bsky.app/profile/${verification.handle}`} target="_blank" rel="noopener noreferrer" className="verifier-profile-link">
789
789
+
<span className="verifier-display-name">{verification.displayName}</span>
790
790
+
<span className="verifier-list-item-handle">@{verification.handle}</span>
791
791
+
</a>
792
792
+
{verification.validityChecked && (
793
793
+
<span className={`verifier-validity-status ${verification.isValid ? 'valid' : 'invalid'}`}>
794
794
+
{verification.isValid ? '✅ Valid' : '❌ Changed'}
795
795
+
</span>
796
796
+
)}
797
797
+
{!verification.validityChecked && isCheckingValidity && (
798
798
+
<span className="verifier-validity-status checking">⏳ Checking...</span>
795
799
)}
800
800
+
<div className="verifier-list-item-date">Verified: {new Date(verification.createdAt).toLocaleString()}</div>
796
801
</div>
797
802
<div className="verifier-list-item-actions">
798
803
<button onClick={() => handleRevoke(verification)} disabled={isRevoking || isLoadingVerifications} className="verifier-revoke-button">
799
799
-
{(isRevoking && statusMessage.includes(verification.handle)) ? 'Revoking...' : 'Revoke'}
804
804
+
{(isRevoking && revokeStatusMessage.includes(verification.handle)) ? 'Revoking...' : 'Revoke'}
800
805
</button>
801
806
</div>
802
807
</li>