@ofidj/entry 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/style.css ADDED
@@ -0,0 +1,1157 @@
1
+ @import "./tokens.css";
2
+ @import "./fonts.css";
3
+
4
+ /* The generated shell. Flat surfaces, 1px rules, one accent — the look is
5
+ * carried by type and by borders, never by elevation or rounding. Values come
6
+ * from tokens.css; nothing below may introduce a literal color. */
7
+
8
+ :root {
9
+ font-family: var(--fidj-font-sans);
10
+ color: var(--fidj-text);
11
+ background: var(--fidj-paper);
12
+ font-synthesis: none;
13
+ line-height: 1.55;
14
+ -webkit-font-smoothing: antialiased;
15
+ }
16
+ * {
17
+ box-sizing: border-box;
18
+ }
19
+ body {
20
+ margin: 0;
21
+ background: var(--fidj-paper);
22
+ }
23
+ button,
24
+ input,
25
+ textarea,
26
+ select {
27
+ font: inherit;
28
+ }
29
+ a {
30
+ color: inherit;
31
+ text-decoration: none;
32
+ }
33
+ a:hover {
34
+ color: var(--fidj-accent);
35
+ }
36
+ ::placeholder {
37
+ color: var(--fidj-placeholder);
38
+ }
39
+
40
+ /* Type scale. Display serif for page titles, mono for every label and eyebrow,
41
+ * sans for everything a person actually reads. */
42
+ h1 {
43
+ font-family: var(--fidj-font-display);
44
+ font-weight: 400;
45
+ font-size: clamp(32px, 4vw, 44px);
46
+ line-height: 1.08;
47
+ letter-spacing: -0.01em;
48
+ margin: 10px 0 20px;
49
+ text-wrap: balance;
50
+ }
51
+ h2 {
52
+ font-size: 15px;
53
+ font-weight: 600;
54
+ letter-spacing: -0.005em;
55
+ margin: 0 0 12px;
56
+ }
57
+ h3 {
58
+ margin: 12px 0 8px;
59
+ font-size: 15px;
60
+ font-weight: 600;
61
+ }
62
+ p {
63
+ color: var(--fidj-text-faint);
64
+ text-wrap: pretty;
65
+ }
66
+ small {
67
+ font-size: 12.5px;
68
+ color: var(--fidj-text-faint);
69
+ }
70
+ .eyebrow {
71
+ font-family: var(--fidj-font-mono);
72
+ font-size: 11px;
73
+ font-weight: 400;
74
+ letter-spacing: 0.12em;
75
+ text-transform: uppercase;
76
+ color: var(--fidj-text-faint);
77
+ margin: 0;
78
+ }
79
+
80
+ .topbar {
81
+ background: var(--fidj-ink);
82
+ color: var(--fidj-on-ink);
83
+ padding: 0 clamp(20px, 4vw, 56px);
84
+ display: flex;
85
+ justify-content: space-between;
86
+ align-items: center;
87
+ gap: 20px;
88
+ height: 60px;
89
+ }
90
+ .brand {
91
+ display: flex;
92
+ align-items: center;
93
+ gap: 12px;
94
+ font-weight: 600;
95
+ font-size: 16px;
96
+ letter-spacing: 0.02em;
97
+ }
98
+ .brand img {
99
+ height: 20px;
100
+ width: auto;
101
+ max-width: 80px;
102
+ object-fit: contain;
103
+ display: block;
104
+ }
105
+ .brand:hover {
106
+ color: var(--fidj-on-ink);
107
+ }
108
+ .app-symbol {
109
+ font-size: 15px;
110
+ color: var(--fidj-accent);
111
+ }
112
+ .fidj-brand {
113
+ display: flex;
114
+ align-items: center;
115
+ gap: 10px;
116
+ font-family: var(--fidj-font-mono);
117
+ font-size: 11px;
118
+ letter-spacing: 0.08em;
119
+ text-transform: uppercase;
120
+ color: var(--fidj-on-ink-faint);
121
+ }
122
+ .fidj-brand:hover {
123
+ color: var(--fidj-on-ink);
124
+ }
125
+ .fidj-brand img {
126
+ width: 18px;
127
+ height: 18px;
128
+ }
129
+ main {
130
+ max-width: var(--fidj-shell-max);
131
+ margin: auto;
132
+ padding: clamp(32px, 5vw, 56px) clamp(20px, 4vw, 56px) 80px;
133
+ }
134
+
135
+ .card {
136
+ background: var(--fidj-surface);
137
+ border: 1px solid var(--fidj-line);
138
+ border-radius: var(--fidj-radius);
139
+ padding: 24px;
140
+ }
141
+ .promise {
142
+ display: flex;
143
+ gap: 12px;
144
+ align-items: center;
145
+ font-size: 13px;
146
+ color: var(--fidj-text-faint);
147
+ border-top: 1px solid var(--fidj-line-soft);
148
+ padding-top: 20px;
149
+ margin-top: 32px;
150
+ }
151
+ .promise img {
152
+ width: 22px;
153
+ height: 22px;
154
+ }
155
+
156
+ label {
157
+ display: block;
158
+ font-family: var(--fidj-font-mono);
159
+ font-size: 11px;
160
+ letter-spacing: 0.1em;
161
+ text-transform: uppercase;
162
+ color: var(--fidj-text-faint);
163
+ margin: 18px 0 7px;
164
+ }
165
+ input,
166
+ textarea,
167
+ select {
168
+ display: block;
169
+ width: 100%;
170
+ padding: 13px 14px;
171
+ border: 1px solid var(--fidj-line-strong);
172
+ border-radius: var(--fidj-radius);
173
+ background: var(--fidj-surface);
174
+ color: var(--fidj-text);
175
+ font-size: 15px;
176
+ }
177
+ input:focus,
178
+ textarea:focus,
179
+ select:focus {
180
+ outline: none;
181
+ border-color: var(--fidj-ink);
182
+ box-shadow: var(--fidj-focus-ring);
183
+ }
184
+ button {
185
+ border: 1px solid var(--fidj-line-strong);
186
+ border-radius: var(--fidj-radius);
187
+ color: var(--fidj-text);
188
+ background: transparent;
189
+ padding: 11px 16px;
190
+ cursor: pointer;
191
+ font-size: 13.5px;
192
+ font-weight: 500;
193
+ }
194
+ button:hover:not(:disabled) {
195
+ border-color: var(--fidj-ink);
196
+ }
197
+ button:disabled {
198
+ opacity: 0.45;
199
+ cursor: not-allowed;
200
+ }
201
+ .primary {
202
+ background: var(--fidj-ink);
203
+ color: var(--fidj-paper);
204
+ border-color: var(--fidj-ink);
205
+ display: block;
206
+ width: 100%;
207
+ padding: 14px 18px;
208
+ font-size: 15px;
209
+ font-weight: 600;
210
+ margin: 20px 0 10px;
211
+ }
212
+ .primary:hover:not(:disabled) {
213
+ background: var(--fidj-ink-raised);
214
+ border-color: var(--fidj-ink-raised);
215
+ }
216
+ .danger {
217
+ color: var(--fidj-danger);
218
+ border-color: var(--fidj-danger-line);
219
+ }
220
+ .danger:hover:not(:disabled) {
221
+ border-color: var(--fidj-danger);
222
+ background: var(--fidj-danger-tint);
223
+ }
224
+
225
+ .demo {
226
+ background: var(--fidj-surface-sunk);
227
+ border: 1px solid var(--fidj-line-soft);
228
+ border-radius: var(--fidj-radius);
229
+ padding: 16px;
230
+ margin-top: 24px;
231
+ font-size: 12.5px;
232
+ }
233
+ .demo strong {
234
+ font-family: var(--fidj-font-mono);
235
+ font-size: 11px;
236
+ letter-spacing: 0.1em;
237
+ text-transform: uppercase;
238
+ color: var(--fidj-text-faint);
239
+ font-weight: 400;
240
+ }
241
+ .demo button {
242
+ margin: 4px 6px 0 0;
243
+ font-size: 12px;
244
+ padding: 8px 10px;
245
+ }
246
+ .demo p {
247
+ margin: 8px 0 12px;
248
+ }
249
+
250
+ .page-heading,
251
+ .section-heading {
252
+ display: flex;
253
+ justify-content: space-between;
254
+ align-items: center;
255
+ gap: 20px;
256
+ }
257
+ .section-heading {
258
+ align-items: baseline;
259
+ border-bottom: 1px solid var(--fidj-line-soft);
260
+ padding-bottom: 10px;
261
+ margin-bottom: 16px;
262
+ }
263
+ .section-heading span {
264
+ font-family: var(--fidj-font-mono);
265
+ font-size: 11px;
266
+ letter-spacing: 0.1em;
267
+ color: var(--fidj-text-faint);
268
+ }
269
+ .roles {
270
+ font-family: var(--fidj-font-mono);
271
+ font-size: 10.5px;
272
+ letter-spacing: 0.06em;
273
+ text-transform: uppercase;
274
+ color: var(--fidj-text-faint);
275
+ border: 1px solid var(--fidj-line);
276
+ border-radius: var(--fidj-radius);
277
+ padding: 5px 9px;
278
+ margin-left: 8px;
279
+ }
280
+
281
+ nav {
282
+ display: flex;
283
+ flex-wrap: wrap;
284
+ gap: 2px;
285
+ border-bottom: 1px solid var(--fidj-line-soft);
286
+ margin: 10px 0 32px;
287
+ }
288
+ nav button {
289
+ border: 0;
290
+ border-bottom: 2px solid transparent;
291
+ border-radius: 0;
292
+ background: transparent;
293
+ padding: 16px 14px;
294
+ font-size: 14px;
295
+ color: var(--fidj-text-faint);
296
+ }
297
+ nav button:hover:not(:disabled) {
298
+ color: var(--fidj-text);
299
+ }
300
+ nav button.selected {
301
+ color: var(--fidj-text);
302
+ border-bottom-color: var(--fidj-ink);
303
+ }
304
+ nav button:last-child {
305
+ margin-left: auto;
306
+ }
307
+
308
+ .workspace {
309
+ display: grid;
310
+ grid-template-columns: 1.2fr 1fr;
311
+ gap: 24px;
312
+ align-items: start;
313
+ }
314
+ .privacy-grid {
315
+ display: grid;
316
+ grid-template-columns: 1fr 1fr;
317
+ gap: 24px;
318
+ align-items: start;
319
+ }
320
+ .privacy-grid button {
321
+ margin-top: 16px;
322
+ }
323
+ .note {
324
+ margin-top: 16px;
325
+ }
326
+ .note p {
327
+ white-space: pre-wrap;
328
+ overflow-wrap: anywhere;
329
+ color: var(--fidj-text-muted);
330
+ }
331
+ .empty {
332
+ text-align: center;
333
+ padding: 56px 28px;
334
+ }
335
+ .empty > span {
336
+ font-size: 28px;
337
+ color: var(--fidj-accent);
338
+ }
339
+
340
+ .notice,
341
+ .error {
342
+ border: 1px solid var(--fidj-line);
343
+ border-left: 2px solid var(--fidj-ok);
344
+ border-radius: var(--fidj-radius);
345
+ background: var(--fidj-surface);
346
+ font-size: 13.5px;
347
+ color: var(--fidj-text-muted);
348
+ padding: 14px 18px;
349
+ margin-bottom: 24px;
350
+ }
351
+ .error {
352
+ border-left-color: var(--fidj-danger);
353
+ background: var(--fidj-danger-tint);
354
+ color: var(--fidj-danger-strong);
355
+ }
356
+
357
+ .agreement {
358
+ background: var(--fidj-surface-sunk);
359
+ border: 1px solid var(--fidj-line-soft);
360
+ border-radius: var(--fidj-radius);
361
+ padding: 16px;
362
+ font-size: 13px;
363
+ margin: 24px 0;
364
+ }
365
+ .agreement strong {
366
+ font-size: 13.5px;
367
+ }
368
+ .agreement span {
369
+ float: right;
370
+ font-family: var(--fidj-font-mono);
371
+ font-size: 10.5px;
372
+ letter-spacing: 0.06em;
373
+ text-transform: uppercase;
374
+ color: var(--fidj-text-faint);
375
+ }
376
+ .agreement p {
377
+ font-size: 12.5px;
378
+ }
379
+ .toggle {
380
+ display: flex;
381
+ align-items: center;
382
+ justify-content: space-between;
383
+ gap: 20px;
384
+ padding: 18px 0;
385
+ margin: 0;
386
+ border-bottom: 1px solid var(--fidj-line-soft);
387
+ font-family: var(--fidj-font-sans);
388
+ font-size: 14px;
389
+ letter-spacing: 0;
390
+ text-transform: none;
391
+ color: var(--fidj-text);
392
+ }
393
+ .toggle small {
394
+ display: block;
395
+ font-weight: 400;
396
+ margin-top: 5px;
397
+ }
398
+ .toggle input {
399
+ width: 18px;
400
+ height: 18px;
401
+ accent-color: var(--fidj-ink);
402
+ }
403
+ .fineprint {
404
+ font-size: 12px;
405
+ color: var(--fidj-text-faint);
406
+ margin-top: 24px;
407
+ }
408
+ hr {
409
+ border: 0;
410
+ border-top: 1px solid var(--fidj-line-soft);
411
+ margin: 28px 0;
412
+ }
413
+ footer {
414
+ text-align: center;
415
+ font-family: var(--fidj-font-mono);
416
+ font-size: 10.5px;
417
+ letter-spacing: 0.06em;
418
+ color: var(--fidj-text-faint);
419
+ border-top: 1px solid var(--fidj-line-soft);
420
+ padding: 28px 0 10px;
421
+ }
422
+ .fidj-version {
423
+ position: fixed;
424
+ right: 10px;
425
+ bottom: 8px;
426
+ z-index: 1000;
427
+ padding: 4px 7px;
428
+ border: 1px solid var(--fidj-line-soft);
429
+ border-radius: var(--fidj-radius);
430
+ background: var(--fidj-paper);
431
+ color: var(--fidj-text-faint);
432
+ font-family: var(--fidj-font-mono);
433
+ font-size: 10px;
434
+ line-height: 1;
435
+ opacity: 0.9;
436
+ }
437
+
438
+ @media (max-width: 760px) {
439
+ main {
440
+ padding: 28px 18px 56px;
441
+ }
442
+ .topbar {
443
+ padding: 0 18px;
444
+ }
445
+ .workspace,
446
+ .privacy-grid {
447
+ grid-template-columns: 1fr;
448
+ }
449
+ .card {
450
+ padding: 20px;
451
+ }
452
+ .fidj-brand {
453
+ font-size: 0;
454
+ gap: 0;
455
+ }
456
+ .roles {
457
+ display: inline-block;
458
+ margin: 8px 0 0;
459
+ }
460
+ .page-heading {
461
+ align-items: flex-start;
462
+ }
463
+ }
464
+
465
+ /* The sign-in entry: ink panel carrying the app's identity, paper panel
466
+ * carrying the form. It stacks below 860px, ink first. It is full-bleed, so
467
+ * the shell's own header, padding and footer step aside while it is shown. */
468
+ body.signin-view .topbar,
469
+ body.signin-view main > footer {
470
+ display: none;
471
+ }
472
+ body.signin-view main {
473
+ max-width: none;
474
+ margin: 0;
475
+ padding: 0;
476
+ }
477
+ /* A mounted app takes the document: the shell removes its own chrome rather
478
+ * than hiding it, so nothing of the shell's layout reaches the app. The class
479
+ * stays as the hook for anything an app's own stylesheet wants to key on. */
480
+ body.has-module {
481
+ margin: 0;
482
+ }
483
+ /* The sign-in entry: ink panel carrying the app's identity, paper panel
484
+ * carrying the form. It stacks below 860px, ink first. */
485
+ .signin-shell {
486
+ display: flex;
487
+ flex-wrap: wrap;
488
+ align-items: stretch;
489
+ min-height: 100vh;
490
+ width: 100%;
491
+ background: var(--fidj-paper);
492
+ }
493
+ .signin-form [role="alert"],
494
+ .signin-form [role="status"] {
495
+ margin: 0 0 20px;
496
+ }
497
+ .signin-intro {
498
+ flex: 1.35 1 520px;
499
+ background: var(--fidj-ink);
500
+ color: var(--fidj-on-ink);
501
+ padding: 56px clamp(32px, 5vw, 80px) 44px;
502
+ display: flex;
503
+ flex-direction: column;
504
+ gap: 52px;
505
+ justify-content: space-between;
506
+ }
507
+ .signin-masthead {
508
+ display: flex;
509
+ align-items: center;
510
+ gap: 12px;
511
+ }
512
+ /* The app's own mark, beside its name. An app that supplied none borrows the
513
+ * Fidj mark, which keeps the corner from being blank without pretending the
514
+ * app is Fidj — the trust line below always names the provider explicitly. */
515
+ .signin-masthead .app-mark {
516
+ height: 22px;
517
+ width: auto;
518
+ max-width: 88px;
519
+ object-fit: contain;
520
+ display: block;
521
+ flex: none;
522
+ }
523
+ .signin-masthead strong {
524
+ font-size: 17px;
525
+ font-weight: 600;
526
+ letter-spacing: 0.02em;
527
+ }
528
+ .signin-identity {
529
+ display: flex;
530
+ flex-direction: column;
531
+ gap: 28px;
532
+ max-width: 620px;
533
+ }
534
+ /* An app that supplies no highlights would leave the panel hollow under
535
+ * space-between; centre its identity in the space instead. */
536
+ .signin-intro.is-plain .signin-identity {
537
+ margin-block: auto;
538
+ }
539
+ .signin-intro h1 {
540
+ margin: 0;
541
+ font-size: clamp(40px, 5.2vw, 68px);
542
+ line-height: 1.03;
543
+ letter-spacing: -0.015em;
544
+ }
545
+ .signin-description {
546
+ margin: 0;
547
+ font-size: 17px;
548
+ line-height: 1.6;
549
+ color: var(--fidj-on-ink-muted);
550
+ max-width: 52ch;
551
+ }
552
+ /* One hairline grid: the 1px gap is the parent background showing through. */
553
+ .signin-highlights {
554
+ display: grid;
555
+ grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
556
+ gap: 1px;
557
+ background: var(--fidj-ink-raised);
558
+ border: 1px solid var(--fidj-ink-raised);
559
+ }
560
+ .signin-highlights article {
561
+ background: var(--fidj-ink);
562
+ padding: 22px 20px 24px;
563
+ display: flex;
564
+ flex-direction: column;
565
+ gap: 9px;
566
+ }
567
+ .signin-highlights .eyebrow {
568
+ color: var(--fidj-accent);
569
+ letter-spacing: 0.12em;
570
+ }
571
+ .signin-highlights h2 {
572
+ margin: 0;
573
+ font-size: 15px;
574
+ }
575
+ .signin-highlights p {
576
+ margin: 0;
577
+ font-size: 13.5px;
578
+ line-height: 1.55;
579
+ color: var(--fidj-on-ink-faint);
580
+ }
581
+ /* No rule of its own: the disclosure above already draws one across the panel,
582
+ * and two lines a few pixels apart read as a mistake rather than as structure. */
583
+ .signin-trust {
584
+ display: flex;
585
+ flex-direction: column;
586
+ gap: 12px;
587
+ padding-top: 20px;
588
+ }
589
+ .signin-trust-head {
590
+ display: flex;
591
+ align-items: center;
592
+ gap: 10px;
593
+ }
594
+ .signin-trust .signin-logo {
595
+ width: 18px;
596
+ height: 18px;
597
+ flex: none;
598
+ }
599
+ .signin-trust strong {
600
+ font-size: 13px;
601
+ color: var(--fidj-text);
602
+ }
603
+ .signin-trust p:not(.signin-trust-head) {
604
+ display: flex;
605
+ align-items: baseline;
606
+ gap: 10px;
607
+ margin: 0;
608
+ font-size: 13px;
609
+ line-height: 1.55;
610
+ color: var(--fidj-text-muted);
611
+ }
612
+ .signin-trust p:not(.signin-trust-head)::before {
613
+ content: "";
614
+ width: 5px;
615
+ height: 5px;
616
+ border-radius: 50%;
617
+ background: var(--fidj-accent);
618
+ flex: none;
619
+ transform: translateY(-2px);
620
+ }
621
+
622
+ .signin-form {
623
+ flex: 1 1 420px;
624
+ background: var(--fidj-paper);
625
+ padding: 56px clamp(28px, 4vw, 64px) 44px;
626
+ display: flex;
627
+ flex-direction: column;
628
+ gap: 28px;
629
+ }
630
+ .signin-form > * {
631
+ max-width: 400px;
632
+ width: 100%;
633
+ margin-inline: auto;
634
+ }
635
+ .signin-form h2 {
636
+ font-family: var(--fidj-font-display);
637
+ font-weight: 400;
638
+ font-size: 34px;
639
+ line-height: 1.1;
640
+ letter-spacing: -0.01em;
641
+ margin: 0 0 20px;
642
+ }
643
+ .signin-form > p {
644
+ margin: 0;
645
+ font-size: 14px;
646
+ }
647
+ .signin-form input {
648
+ min-height: 48px;
649
+ }
650
+ /* The app's own buttons sit one level deeper now that the credential form is
651
+ * inside a disclosure, so the rule follows them in rather than losing them. */
652
+ .signin-form form > button,
653
+ .signin-form form #email-entry > button {
654
+ min-height: 48px;
655
+ width: 100%;
656
+ margin-top: 12px;
657
+ }
658
+ .signin-form .secondary {
659
+ background: transparent;
660
+ margin-top: 8px;
661
+ font-weight: 500;
662
+ }
663
+ /* The label row carries its own escape hatch, as the mockup does: the reset
664
+ * link sits with the field it is about, not adrift under the form. */
665
+ .field-head {
666
+ display: flex;
667
+ align-items: center;
668
+ justify-content: space-between;
669
+ gap: 12px;
670
+ margin: 18px 0 7px;
671
+ }
672
+ .field-head label {
673
+ margin: 0;
674
+ }
675
+ .field-head a {
676
+ font-size: 12px;
677
+ color: var(--fidj-text-faint);
678
+ text-decoration: underline;
679
+ text-underline-offset: 3px;
680
+ }
681
+ .password-field {
682
+ position: relative;
683
+ display: block;
684
+ }
685
+ .password-field input {
686
+ padding-right: 68px;
687
+ }
688
+ .password-field button {
689
+ position: absolute;
690
+ right: 5px;
691
+ top: 50%;
692
+ transform: translateY(-50%);
693
+ border: 0;
694
+ background: none;
695
+ font-family: var(--fidj-font-mono);
696
+ font-size: 11px;
697
+ letter-spacing: 0.06em;
698
+ text-transform: uppercase;
699
+ color: var(--fidj-text-faint);
700
+ padding: 8px;
701
+ }
702
+ .password-field button:hover:not(:disabled) {
703
+ color: var(--fidj-text);
704
+ }
705
+ .signin-divider {
706
+ display: flex;
707
+ align-items: center;
708
+ gap: 12px;
709
+ font-family: var(--fidj-font-mono);
710
+ font-size: 10.5px;
711
+ letter-spacing: 0.1em;
712
+ text-transform: uppercase;
713
+ color: var(--fidj-text-faint);
714
+ margin: 0;
715
+ }
716
+ .signin-divider::before,
717
+ .signin-divider::after {
718
+ content: "";
719
+ height: 1px;
720
+ flex: 1;
721
+ background: var(--fidj-line);
722
+ }
723
+ .anonymous-entry {
724
+ display: flex;
725
+ justify-content: space-between;
726
+ align-items: center;
727
+ width: 100%;
728
+ min-height: 46px;
729
+ }
730
+ .signin-form .signin-footnote {
731
+ font-size: 12px;
732
+ text-align: center;
733
+ margin: 0;
734
+ }
735
+ .signin-badges {
736
+ margin-top: auto;
737
+ padding-top: 24px;
738
+ display: flex;
739
+ flex-wrap: wrap;
740
+ gap: 8px;
741
+ }
742
+ .signin-badges span {
743
+ font-family: var(--fidj-font-mono);
744
+ font-size: 10.5px;
745
+ letter-spacing: 0.06em;
746
+ text-transform: uppercase;
747
+ color: var(--fidj-text-faint);
748
+ border: 1px solid var(--fidj-line);
749
+ padding: 5px 9px;
750
+ }
751
+
752
+ @media (max-width: 860px) {
753
+ .signin-intro {
754
+ gap: 32px;
755
+ padding: 36px 24px 32px;
756
+ }
757
+ .signin-form {
758
+ padding: 36px 24px 32px;
759
+ }
760
+ .signin-description {
761
+ font-size: 15px;
762
+ }
763
+ }
764
+
765
+ .public-content {
766
+ text-align: center;
767
+ margin: 2rem 0;
768
+ }
769
+ .public-content img {
770
+ display: inline-block;
771
+ width: min(100%, 520px);
772
+ height: auto;
773
+ }
774
+ .public-content h1 {
775
+ font-size: clamp(2rem, 5vw, 3.5rem);
776
+ }
777
+ .content-account {
778
+ max-width: 680px;
779
+ margin: 2rem auto;
780
+ }
781
+ .content-account button {
782
+ margin: 0.4rem 0.4rem 0.4rem 0;
783
+ }
784
+ .content-account input:not([type="checkbox"]) {
785
+ width: 100%;
786
+ }
787
+ /* The app's navigation lives in the app's own bar, past its mark and its name
788
+ * and past a rule — the shape Fidj's console uses for the same job. It used to
789
+ * sit in the page under a bar that carried only a name, which read as two
790
+ * headers for one app and put the way out a scroll away from the way in. */
791
+ .topbar .content-nav {
792
+ border: 0;
793
+ border-left: 1px solid var(--fidj-ink-line-soft);
794
+ border-radius: 0;
795
+ margin: 0 auto 0 0;
796
+ padding-left: clamp(12px, 2vw, 20px);
797
+ gap: 2px;
798
+ flex-wrap: nowrap;
799
+ }
800
+ .topbar .content-nav button {
801
+ padding: 8px 12px;
802
+ font-size: 13.5px;
803
+ color: var(--fidj-on-ink-faint);
804
+ border-bottom: 0;
805
+ white-space: nowrap;
806
+ }
807
+ .topbar .content-nav button:hover:not(:disabled) {
808
+ color: var(--fidj-on-ink);
809
+ }
810
+ .topbar .content-nav button.selected {
811
+ color: var(--fidj-on-ink);
812
+ font-weight: 600;
813
+ }
814
+ .topbar .content-nav button:last-child {
815
+ margin-left: 0;
816
+ }
817
+ /* Who you are, said where it can be checked against what follows. */
818
+ .account-identity {
819
+ font-size: 15px;
820
+ }
821
+ /* The two ways out of this screen, last and together. */
822
+ .account-actions {
823
+ display: flex;
824
+ flex-wrap: wrap;
825
+ align-items: center;
826
+ gap: 10px;
827
+ margin-top: 28px;
828
+ padding-top: 22px;
829
+ border-top: 1px solid var(--fidj-line-soft);
830
+ }
831
+ .account-actions .primary {
832
+ width: auto;
833
+ flex: 1;
834
+ min-width: 200px;
835
+ margin: 0;
836
+ }
837
+
838
+ /* The account tab carries the address it is about, and that address is long.
839
+ * It gives way before the app's own name does. */
840
+ .topbar .content-nav #account-tab {
841
+ overflow: hidden;
842
+ text-overflow: ellipsis;
843
+ min-width: 0;
844
+ }
845
+ .signin-logo {
846
+ width: 22px;
847
+ height: 22px;
848
+ }
849
+
850
+ button:focus-visible,
851
+ a:focus-visible,
852
+ input:focus-visible,
853
+ summary:focus-visible {
854
+ outline: 2px solid var(--fidj-ink);
855
+ outline-offset: 3px;
856
+ }
857
+
858
+ /* The personal site layout mleweb builds from --content. Same system, wider
859
+ * measure: the supplied HTML is developer-authored and styled, not sanitised. */
860
+ .site-nav {
861
+ border: 0;
862
+ margin: 0;
863
+ padding: 0;
864
+ align-items: center;
865
+ gap: 24px;
866
+ font-size: 13px;
867
+ }
868
+ .workspace-link {
869
+ border: 1px solid var(--fidj-line-strong);
870
+ border-radius: var(--fidj-radius);
871
+ padding: 9px 14px;
872
+ }
873
+ .personal-hero {
874
+ display: grid;
875
+ grid-template-columns: 1.1fr 1fr;
876
+ gap: 36px;
877
+ align-items: center;
878
+ min-height: 590px;
879
+ }
880
+ .mario-scene {
881
+ text-align: center;
882
+ }
883
+ .mario-scene img {
884
+ width: 100%;
885
+ max-width: 570px;
886
+ height: auto;
887
+ object-fit: contain;
888
+ image-rendering: pixelated;
889
+ }
890
+ .personal-intro h1 {
891
+ font-size: clamp(44px, 6vw, 66px);
892
+ line-height: 1.05;
893
+ max-width: 480px;
894
+ }
895
+ .personal-tagline {
896
+ font-size: 19px;
897
+ color: var(--fidj-text-muted);
898
+ }
899
+ .personal-intro > p {
900
+ max-width: 440px;
901
+ }
902
+ .site-links {
903
+ display: flex;
904
+ align-items: center;
905
+ gap: 24px;
906
+ margin: 28px 0;
907
+ }
908
+ .site-primary {
909
+ display: inline-block;
910
+ padding: 13px 19px;
911
+ border-radius: var(--fidj-radius);
912
+ background: var(--fidj-ink);
913
+ color: var(--fidj-paper);
914
+ font-weight: 600;
915
+ font-size: 14px;
916
+ }
917
+ .site-primary:hover {
918
+ background: var(--fidj-ink-raised);
919
+ color: var(--fidj-paper);
920
+ }
921
+ .personal-contact {
922
+ font-size: 13px;
923
+ line-height: 2;
924
+ }
925
+ .resume-section {
926
+ scroll-margin-top: 30px;
927
+ display: grid;
928
+ grid-template-columns: 0.7fr 1.3fr;
929
+ gap: 70px;
930
+ border-top: 1px solid var(--fidj-line-soft);
931
+ padding: 60px 0;
932
+ }
933
+ .resume-intro h2 {
934
+ font-family: var(--fidj-font-display);
935
+ font-weight: 400;
936
+ font-size: 34px;
937
+ }
938
+ .resume-timeline article {
939
+ padding: 0 0 26px 24px;
940
+ border-left: 1px solid var(--fidj-line);
941
+ }
942
+ .resume-timeline h3 {
943
+ margin: 4px 0 8px;
944
+ }
945
+ .resume-timeline h3 span {
946
+ font-weight: 400;
947
+ }
948
+ .resume-period {
949
+ font-family: var(--fidj-font-mono);
950
+ font-size: 11px;
951
+ letter-spacing: 0.08em;
952
+ text-transform: uppercase;
953
+ margin: 0;
954
+ color: var(--fidj-text-faint);
955
+ }
956
+ .resume-timeline article > p:last-child {
957
+ margin-bottom: 0;
958
+ }
959
+ .personal-footer {
960
+ display: flex;
961
+ justify-content: space-between;
962
+ align-items: center;
963
+ gap: 25px;
964
+ }
965
+ .personal-footer p {
966
+ margin-bottom: 0;
967
+ }
968
+
969
+ @media (max-width: 760px) {
970
+ .personal-hero,
971
+ .resume-section {
972
+ grid-template-columns: 1fr;
973
+ gap: 28px;
974
+ min-height: 0;
975
+ }
976
+ .resume-section {
977
+ padding: 36px 0;
978
+ }
979
+ .personal-footer,
980
+ .site-links {
981
+ flex-wrap: wrap;
982
+ gap: 16px;
983
+ }
984
+ }
985
+
986
+ .signin-agreement { margin-block: 1rem; }
987
+ .agreement-choice { display: flex; align-items: flex-start; gap: 0.75rem; font-family: var(--fidj-font-sans); font-size: 14px; letter-spacing: normal; text-transform: none; line-height: 1.45; color: var(--fidj-text-muted); }
988
+ .agreement-choice input[type="checkbox"] { width: 1.15rem; height: 1.15rem; min-height: 0; flex: 0 0 auto; margin: 0.15rem 0 0; padding: 0; accent-color: var(--fidj-ink); }
989
+ .signin-agreement button { margin-block: 0.5rem; padding: 0; border: 0; background: transparent; text-decoration: underline; }
990
+ #agreement-dialog { color: var(--fidj-text); background: var(--fidj-paper); border: 1px solid var(--fidj-line); border-radius: var(--fidj-radius); padding: 1.5rem; max-width: min(40rem, calc(100vw - 2rem)); max-height: 80vh; overflow: auto; }
991
+ #agreement-text { white-space: pre-wrap; overflow-wrap: anywhere; }
992
+
993
+ /* The entry explains itself before it offers its button. A person whose account
994
+ * lives somewhere else needs to know that before they look for the form that is
995
+ * not coming, so this is body text above the action, not fineprint below it. */
996
+ .signin-lead {
997
+ margin: 0 0 18px;
998
+ color: var(--fidj-ink-soft, inherit);
999
+ line-height: 1.5;
1000
+ }
1001
+ /* Present but not competing: "use a different account" is the way out of a
1002
+ * remembered address, not an alternative worth the weight of the primary. */
1003
+ button.quiet {
1004
+ margin-top: 10px;
1005
+ background: none;
1006
+ border: none;
1007
+ color: inherit;
1008
+ text-decoration: underline;
1009
+ padding: 6px 0;
1010
+ font: inherit;
1011
+ cursor: pointer;
1012
+ width: auto;
1013
+ }
1014
+
1015
+ /* The Fidj door.
1016
+ *
1017
+ * The accent is the Fidj mark, and this is the one control on an app's entry
1018
+ * that belongs to Fidj rather than to the app. It is also the door the app
1019
+ * would rather people took — the one where the password is never typed here —
1020
+ * and those two reasons happen to want the same paint. Nothing else on the
1021
+ * screen wears it, which is what makes it read as the way in rather than as one
1022
+ * option among several. */
1023
+ .primary.fidj-entry {
1024
+ background: var(--fidj-accent);
1025
+ border-color: var(--fidj-accent);
1026
+ color: var(--fidj-on-accent);
1027
+ margin-top: 0;
1028
+ }
1029
+ .primary.fidj-entry:hover:not(:disabled) {
1030
+ background: var(--fidj-accent-strong);
1031
+ border-color: var(--fidj-accent-strong);
1032
+ }
1033
+ /* While the Fidj window is open, the door is no longer the way in — it is the
1034
+ * way back to the window doing the work. So it reads as a state rather than an
1035
+ * invitation, and keeps the pointer, because it is the one thing on the screen
1036
+ * somebody who has lost that window behind this page needs to be able to press. */
1037
+ .primary.fidj-entry.is-waiting,
1038
+ .primary.fidj-entry.is-waiting:hover:not(:disabled) {
1039
+ background: var(--fidj-surface-sunk);
1040
+ border-color: var(--fidj-line);
1041
+ color: var(--fidj-text-faint);
1042
+ cursor: pointer;
1043
+ }
1044
+ .primary.fidj-entry.is-waiting:hover:not(:disabled) {
1045
+ border-color: var(--fidj-line-hover);
1046
+ color: var(--fidj-text-muted);
1047
+ }
1048
+
1049
+ /* The app's own form, second. A disclosure rather than a second button of equal
1050
+ * weight: it costs the person who wants it one click, and costs everybody else
1051
+ * nothing — where two buttons side by side charged every arrival a decision.
1052
+ *
1053
+ * It sits with the button it is an alternative to, not a rule and a gap away:
1054
+ * separated, the two read as unrelated parts of the screen rather than as the
1055
+ * two ways in. */
1056
+ .signin-alternate {
1057
+ margin-top: 2px;
1058
+ }
1059
+ /* A seam across the panel rather than a link hanging off its left edge: the
1060
+ * label in the middle with a rule running out to each side, which is what says
1061
+ * "below this, a different way in" instead of "here is one more control". */
1062
+ .signin-toggle {
1063
+ display: flex;
1064
+ align-items: center;
1065
+ gap: 12px;
1066
+ width: 100%;
1067
+ margin: 0;
1068
+ padding: 8px 0;
1069
+ min-height: 0;
1070
+ background: none;
1071
+ border: none;
1072
+ font: inherit;
1073
+ font-size: 13.5px;
1074
+ color: var(--fidj-text-muted);
1075
+ cursor: pointer;
1076
+ }
1077
+ .signin-toggle::before,
1078
+ .signin-toggle::after {
1079
+ content: "";
1080
+ height: 1px;
1081
+ flex: 1;
1082
+ background: var(--fidj-line);
1083
+ }
1084
+ .signin-toggle-label {
1085
+ display: inline-flex;
1086
+ align-items: center;
1087
+ gap: 7px;
1088
+ }
1089
+ .signin-toggle:hover:not(:disabled) {
1090
+ color: var(--fidj-text);
1091
+ }
1092
+ .signin-toggle:hover:not(:disabled)::before,
1093
+ .signin-toggle:hover:not(:disabled)::after {
1094
+ background: var(--fidj-line-hover);
1095
+ }
1096
+ /* The caret points at what pressing it does: down at a form that is not here
1097
+ * yet, and — turned over — up at the one it would put away again. */
1098
+ .signin-toggle .caret {
1099
+ width: 0;
1100
+ height: 0;
1101
+ border-left: 4px solid transparent;
1102
+ border-right: 4px solid transparent;
1103
+ border-top: 5px solid currentColor;
1104
+ transition: transform 220ms ease;
1105
+ }
1106
+ .signin-toggle[aria-expanded="true"] .caret {
1107
+ transform: rotate(180deg);
1108
+ }
1109
+ .signin-alternate #email-entry {
1110
+ margin-top: 6px;
1111
+ }
1112
+
1113
+ /* Opening the form folds the Fidj door away, because the two are alternatives
1114
+ * and only one of them is being used. Folding rather than vanishing is the part
1115
+ * that says so: the form visibly takes the room the door was holding. */
1116
+ .primary.fidj-entry {
1117
+ overflow: hidden;
1118
+ max-height: 64px;
1119
+ transition:
1120
+ max-height 220ms ease,
1121
+ min-height 220ms ease,
1122
+ opacity 140ms ease,
1123
+ margin 220ms ease,
1124
+ padding 220ms ease,
1125
+ border-width 220ms ease;
1126
+ }
1127
+ .primary.fidj-entry.is-folded {
1128
+ /* `min-height` wins over `max-height`, so the entry's own 48px floor has to
1129
+ * come down too or nothing moves. */
1130
+ min-height: 0;
1131
+ max-height: 0;
1132
+ opacity: 0;
1133
+ margin-top: 0;
1134
+ margin-bottom: 0;
1135
+ padding-top: 0;
1136
+ padding-bottom: 0;
1137
+ border-width: 0;
1138
+ pointer-events: none;
1139
+ }
1140
+ @media (prefers-reduced-motion: reduce) {
1141
+ .primary.fidj-entry,
1142
+ .signin-toggle .caret {
1143
+ transition: none;
1144
+ }
1145
+ }
1146
+
1147
+ /* A window that opened itself over the page somebody was on owes them the way
1148
+ * back before it asks for a password. */
1149
+ .signin-return {
1150
+ margin: 0 0 18px;
1151
+ padding: 10px 12px;
1152
+ background: var(--fidj-surface-sunk);
1153
+ border-left: 2px solid var(--fidj-accent);
1154
+ color: var(--fidj-text-muted);
1155
+ font-size: 13.5px;
1156
+ line-height: 1.5;
1157
+ }