@ofidj/generator-fidj 1.0.0 → 1.0.3

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.
Files changed (161) hide show
  1. package/README.md +136 -57
  2. package/bin/create-fidj.cjs +62 -0
  3. package/generators/app/index.js +100 -189
  4. package/generators/app/templates/typescript/README.md +82 -0
  5. package/generators/app/templates/typescript/app.config.json +14 -0
  6. package/generators/app/templates/typescript/gitignore +5 -0
  7. package/generators/app/templates/typescript/package.json +25 -0
  8. package/generators/app/templates/typescript/public/fidj-logo.png +0 -0
  9. package/generators/app/templates/typescript/public/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  10. package/generators/app/templates/typescript/public/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  11. package/generators/app/templates/typescript/public/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  12. package/generators/app/templates/typescript/public/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  13. package/generators/app/templates/typescript/public/fonts/IBMPlexSans-400_600-latin-ext.woff2 +0 -0
  14. package/generators/app/templates/typescript/public/fonts/IBMPlexSans-400_600-latin.woff2 +0 -0
  15. package/generators/app/templates/typescript/public/fonts/InstrumentSerif-400-latin-ext.woff2 +0 -0
  16. package/generators/app/templates/typescript/public/fonts/InstrumentSerif-400-latin.woff2 +0 -0
  17. package/generators/app/templates/typescript/public/index.html +16 -0
  18. package/generators/app/templates/typescript/scripts/build.mjs +49 -0
  19. package/generators/app/templates/typescript/scripts/privacy-check.mjs +21 -0
  20. package/generators/app/templates/typescript/scripts/render-content.mjs +14 -0
  21. package/generators/app/templates/typescript/server/data-store.ts +123 -0
  22. package/generators/app/templates/typescript/server/index.ts +338 -0
  23. package/generators/app/templates/typescript/server/privacy-adapter.ts +21 -0
  24. package/generators/app/templates/typescript/src/content.ts +491 -0
  25. package/generators/app/templates/typescript/src/fonts.css +92 -0
  26. package/generators/app/templates/typescript/src/main.ts +251 -0
  27. package/generators/app/templates/typescript/src/service-agreement.ts +40 -0
  28. package/generators/app/templates/typescript/src/style.css +916 -0
  29. package/generators/app/templates/typescript/src/tokens.css +56 -0
  30. package/generators/app/templates/typescript/test/server.test.mjs +287 -0
  31. package/generators/app/templates/typescript/tsconfig.json +15 -0
  32. package/lib/app-module.cjs +64 -0
  33. package/lib/scaffold.cjs +214 -0
  34. package/package.json +15 -13
  35. package/generators/app/templates/app2018/.travis.yml +0 -35
  36. package/generators/app/templates/app2018/LICENSE +0 -21
  37. package/generators/app/templates/app2018/Procfile +0 -1
  38. package/generators/app/templates/app2018/README.md +0 -49
  39. package/generators/app/templates/app2018/config.xml +0 -91
  40. package/generators/app/templates/app2018/gulpfile.js +0 -63
  41. package/generators/app/templates/app2018/ionic.config.json +0 -9
  42. package/generators/app/templates/app2018/package.json +0 -90
  43. package/generators/app/templates/app2018/platforms/README.md +0 -1
  44. package/generators/app/templates/app2018/resources/README.md +0 -6
  45. package/generators/app/templates/app2018/resources/icon.png +0 -0
  46. package/generators/app/templates/app2018/resources/marketing-01-ipad.png +0 -0
  47. package/generators/app/templates/app2018/resources/marketing-01-iphone.png +0 -0
  48. package/generators/app/templates/app2018/resources/marketing-02-ipad.png +0 -0
  49. package/generators/app/templates/app2018/resources/marketing-02-iphone.png +0 -0
  50. package/generators/app/templates/app2018/resources/marketing-03-ipad.png +0 -0
  51. package/generators/app/templates/app2018/resources/marketing-03-iphone.png +0 -0
  52. package/generators/app/templates/app2018/resources/marketing.json +0 -19
  53. package/generators/app/templates/app2018/resources/splash.png +0 -0
  54. package/generators/app/templates/app2018/src/app/app.component.ts +0 -88
  55. package/generators/app/templates/app2018/src/app/app.html +0 -19
  56. package/generators/app/templates/app2018/src/app/app.module.ts +0 -40
  57. package/generators/app/templates/app2018/src/app/app.scss +0 -16
  58. package/generators/app/templates/app2018/src/app/main.ts +0 -5
  59. package/generators/app/templates/app2018/src/app/shared/card.model.ts +0 -10
  60. package/generators/app/templates/app2018/src/app/shared/profile.service.ts +0 -46
  61. package/generators/app/templates/app2018/src/app/shared/shared.module.ts +0 -35
  62. package/generators/app/templates/app2018/src/app/shared/storage.service.ts +0 -11
  63. package/generators/app/templates/app2018/src/app/shared/version.const.ts +0 -5
  64. package/generators/app/templates/app2018/src/assets/icon/favicon.ico +0 -0
  65. package/generators/app/templates/app2018/src/assets/imgs/gg.png +0 -0
  66. package/generators/app/templates/app2018/src/assets/imgs/github.png +0 -0
  67. package/generators/app/templates/app2018/src/assets/imgs/login.svg +0 -5668
  68. package/generators/app/templates/app2018/src/assets/imgs/logo.png +0 -0
  69. package/generators/app/templates/app2018/src/index.html +0 -49
  70. package/generators/app/templates/app2018/src/manifest.json +0 -13
  71. package/generators/app/templates/app2018/src/pages/home/home.html +0 -56
  72. package/generators/app/templates/app2018/src/pages/home/home.scss +0 -3
  73. package/generators/app/templates/app2018/src/pages/home/home.ts +0 -126
  74. package/generators/app/templates/app2018/src/pages/login/login.html +0 -56
  75. package/generators/app/templates/app2018/src/pages/login/login.scss +0 -44
  76. package/generators/app/templates/app2018/src/pages/login/login.ts +0 -59
  77. package/generators/app/templates/app2018/src/pages/profile/profile.html +0 -33
  78. package/generators/app/templates/app2018/src/pages/profile/profile.scss +0 -3
  79. package/generators/app/templates/app2018/src/pages/profile/profile.ts +0 -36
  80. package/generators/app/templates/app2018/src/service-worker.js +0 -31
  81. package/generators/app/templates/app2018/src/theme/variables.scss +0 -88
  82. package/generators/app/templates/app2018/tests/karma.unit-tests.conf.js +0 -84
  83. package/generators/app/templates/app2018/tests/unit/app.test.js +0 -10
  84. package/generators/app/templates/app2018/tsconfig.json +0 -28
  85. package/generators/app/templates/app2018/tslint.json +0 -8
  86. package/generators/app/templates/app2018/web.js +0 -21
  87. package/generators/app/templates/app2021/.travis.yml +0 -32
  88. package/generators/app/templates/app2021/LICENSE +0 -21
  89. package/generators/app/templates/app2021/Procfile +0 -1
  90. package/generators/app/templates/app2021/README.md +0 -45
  91. package/generators/app/templates/app2021/angular.json +0 -188
  92. package/generators/app/templates/app2021/browserslist +0 -12
  93. package/generators/app/templates/app2021/ionic.config.json +0 -9
  94. package/generators/app/templates/app2021/karma.conf.js +0 -31
  95. package/generators/app/templates/app2021/package-lock.json +0 -5
  96. package/generators/app/templates/app2021/package.json +0 -77
  97. package/generators/app/templates/app2021/platforms/README.md +0 -1
  98. package/generators/app/templates/app2021/resources/README.md +0 -6
  99. package/generators/app/templates/app2021/resources/icon.png +0 -0
  100. package/generators/app/templates/app2021/resources/marketing-01-ipad.png +0 -0
  101. package/generators/app/templates/app2021/resources/marketing-01-iphone.png +0 -0
  102. package/generators/app/templates/app2021/resources/marketing-02-ipad.png +0 -0
  103. package/generators/app/templates/app2021/resources/marketing-02-iphone.png +0 -0
  104. package/generators/app/templates/app2021/resources/marketing-03-ipad.png +0 -0
  105. package/generators/app/templates/app2021/resources/marketing-03-iphone.png +0 -0
  106. package/generators/app/templates/app2021/resources/marketing.json +0 -19
  107. package/generators/app/templates/app2021/resources/splash.png +0 -0
  108. package/generators/app/templates/app2021/src/app/app-routing.module.ts +0 -25
  109. package/generators/app/templates/app2021/src/app/app.component.html +0 -3
  110. package/generators/app/templates/app2021/src/app/app.component.scss +0 -0
  111. package/generators/app/templates/app2021/src/app/app.component.spec.ts +0 -50
  112. package/generators/app/templates/app2021/src/app/app.component.ts +0 -28
  113. package/generators/app/templates/app2021/src/app/app.module.ts +0 -24
  114. package/generators/app/templates/app2021/src/app/content/content-routing.module.ts +0 -16
  115. package/generators/app/templates/app2021/src/app/content/content.module.ts +0 -20
  116. package/generators/app/templates/app2021/src/app/content/content.page.html +0 -31
  117. package/generators/app/templates/app2021/src/app/content/content.page.scss +0 -0
  118. package/generators/app/templates/app2021/src/app/content/content.page.ts +0 -26
  119. package/generators/app/templates/app2021/src/app/explore-container/explore-container.component.html +0 -4
  120. package/generators/app/templates/app2021/src/app/explore-container/explore-container.component.scss +0 -4
  121. package/generators/app/templates/app2021/src/app/explore-container/explore-container.component.spec.ts +0 -24
  122. package/generators/app/templates/app2021/src/app/explore-container/explore-container.component.ts +0 -16
  123. package/generators/app/templates/app2021/src/app/explore-container/explore-container.module.ts +0 -14
  124. package/generators/app/templates/app2021/src/app/my/my-routing.module.ts +0 -36
  125. package/generators/app/templates/app2021/src/app/my/my.module.ts +0 -19
  126. package/generators/app/templates/app2021/src/app/my/my.page.html +0 -15
  127. package/generators/app/templates/app2021/src/app/my/my.page.scss +0 -1
  128. package/generators/app/templates/app2021/src/app/my/my.page.spec.ts +0 -26
  129. package/generators/app/templates/app2021/src/app/my/my.page.ts +0 -25
  130. package/generators/app/templates/app2021/src/app/profile/profile-routing.module.ts +0 -16
  131. package/generators/app/templates/app2021/src/app/profile/profile.module.ts +0 -20
  132. package/generators/app/templates/app2021/src/app/profile/profile.page.html +0 -49
  133. package/generators/app/templates/app2021/src/app/profile/profile.page.scss +0 -0
  134. package/generators/app/templates/app2021/src/app/profile/profile.page.spec.ts +0 -25
  135. package/generators/app/templates/app2021/src/app/profile/profile.page.ts +0 -44
  136. package/generators/app/templates/app2021/src/app/shared/const.ts +0 -3
  137. package/generators/app/templates/app2021/src/app/signin/signin-routing.module.ts +0 -16
  138. package/generators/app/templates/app2021/src/app/signin/signin.module.ts +0 -18
  139. package/generators/app/templates/app2021/src/app/signin/signin.page.html +0 -53
  140. package/generators/app/templates/app2021/src/app/signin/signin.page.scss +0 -36
  141. package/generators/app/templates/app2021/src/app/signin/signin.page.ts +0 -69
  142. package/generators/app/templates/app2021/src/assets/icon/favicon.png +0 -0
  143. package/generators/app/templates/app2021/src/assets/shapes.svg +0 -1
  144. package/generators/app/templates/app2021/src/environments/environment.prod.ts +0 -3
  145. package/generators/app/templates/app2021/src/environments/environment.ts +0 -16
  146. package/generators/app/templates/app2021/src/global.scss +0 -26
  147. package/generators/app/templates/app2021/src/index.html +0 -26
  148. package/generators/app/templates/app2021/src/main.ts +0 -12
  149. package/generators/app/templates/app2021/src/polyfills.ts +0 -67
  150. package/generators/app/templates/app2021/src/test.ts +0 -20
  151. package/generators/app/templates/app2021/src/theme/variables.scss +0 -232
  152. package/generators/app/templates/app2021/src/zone-flags.ts +0 -5
  153. package/generators/app/templates/app2021/tests/protractor.conf.js +0 -36
  154. package/generators/app/templates/app2021/tests/src/app.e2e-spec.ts +0 -14
  155. package/generators/app/templates/app2021/tests/src/app.po.ts +0 -11
  156. package/generators/app/templates/app2021/tests/tsconfig.json +0 -13
  157. package/generators/app/templates/app2021/tsconfig.app.json +0 -18
  158. package/generators/app/templates/app2021/tsconfig.json +0 -23
  159. package/generators/app/templates/app2021/tsconfig.spec.json +0 -18
  160. package/generators/app/templates/app2021/tslint.json +0 -149
  161. package/generators/app/templates/app2021/web.js +0 -21
@@ -0,0 +1,916 @@
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
+
423
+ @media (max-width: 760px) {
424
+ main {
425
+ padding: 28px 18px 56px;
426
+ }
427
+ .topbar {
428
+ padding: 0 18px;
429
+ }
430
+ .workspace,
431
+ .privacy-grid {
432
+ grid-template-columns: 1fr;
433
+ }
434
+ .card {
435
+ padding: 20px;
436
+ }
437
+ .fidj-brand {
438
+ font-size: 0;
439
+ gap: 0;
440
+ }
441
+ .roles {
442
+ display: inline-block;
443
+ margin: 8px 0 0;
444
+ }
445
+ .page-heading {
446
+ align-items: flex-start;
447
+ }
448
+ }
449
+
450
+ /* The sign-in entry: ink panel carrying the app's identity, paper panel
451
+ * carrying the form. It stacks below 860px, ink first. It is full-bleed, so
452
+ * the shell's own header, padding and footer step aside while it is shown. */
453
+ body.signin-view .topbar,
454
+ body.signin-view main > footer {
455
+ display: none;
456
+ }
457
+ body.signin-view main {
458
+ max-width: none;
459
+ margin: 0;
460
+ padding: 0;
461
+ }
462
+ /* The sign-in entry: ink panel carrying the app's identity, paper panel
463
+ * carrying the form. It stacks below 860px, ink first. */
464
+ .signin-shell {
465
+ display: flex;
466
+ flex-wrap: wrap;
467
+ align-items: stretch;
468
+ min-height: 100vh;
469
+ width: 100%;
470
+ background: var(--fidj-paper);
471
+ }
472
+ .signin-form [role="alert"],
473
+ .signin-form [role="status"] {
474
+ margin: 0 0 20px;
475
+ }
476
+ .signin-intro {
477
+ flex: 1.35 1 520px;
478
+ background: var(--fidj-ink);
479
+ color: var(--fidj-on-ink);
480
+ padding: 56px clamp(32px, 5vw, 80px) 44px;
481
+ display: flex;
482
+ flex-direction: column;
483
+ gap: 52px;
484
+ justify-content: space-between;
485
+ }
486
+ .signin-masthead {
487
+ display: flex;
488
+ align-items: center;
489
+ gap: 12px;
490
+ }
491
+ /* The app's own mark, beside its name. An app that supplied none borrows the
492
+ * Fidj mark, which keeps the corner from being blank without pretending the
493
+ * app is Fidj — the trust line below always names the provider explicitly. */
494
+ .signin-masthead .app-mark {
495
+ height: 22px;
496
+ width: auto;
497
+ max-width: 88px;
498
+ object-fit: contain;
499
+ display: block;
500
+ flex: none;
501
+ }
502
+ .signin-masthead strong {
503
+ font-size: 17px;
504
+ font-weight: 600;
505
+ letter-spacing: 0.02em;
506
+ }
507
+ .signin-identity {
508
+ display: flex;
509
+ flex-direction: column;
510
+ gap: 28px;
511
+ max-width: 620px;
512
+ }
513
+ /* An app that supplies no highlights would leave the panel hollow under
514
+ * space-between; centre its identity in the space instead. */
515
+ .signin-intro.is-plain .signin-identity {
516
+ margin-block: auto;
517
+ }
518
+ .signin-intro h1 {
519
+ margin: 0;
520
+ font-size: clamp(40px, 5.2vw, 68px);
521
+ line-height: 1.03;
522
+ letter-spacing: -0.015em;
523
+ }
524
+ .signin-description {
525
+ margin: 0;
526
+ font-size: 17px;
527
+ line-height: 1.6;
528
+ color: var(--fidj-on-ink-muted);
529
+ max-width: 52ch;
530
+ }
531
+ /* One hairline grid: the 1px gap is the parent background showing through. */
532
+ .signin-highlights {
533
+ display: grid;
534
+ grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
535
+ gap: 1px;
536
+ background: var(--fidj-ink-raised);
537
+ border: 1px solid var(--fidj-ink-raised);
538
+ }
539
+ .signin-highlights article {
540
+ background: var(--fidj-ink);
541
+ padding: 22px 20px 24px;
542
+ display: flex;
543
+ flex-direction: column;
544
+ gap: 9px;
545
+ }
546
+ .signin-highlights .eyebrow {
547
+ color: var(--fidj-accent);
548
+ letter-spacing: 0.12em;
549
+ }
550
+ .signin-highlights h2 {
551
+ margin: 0;
552
+ font-size: 15px;
553
+ }
554
+ .signin-highlights p {
555
+ margin: 0;
556
+ font-size: 13.5px;
557
+ line-height: 1.55;
558
+ color: var(--fidj-on-ink-faint);
559
+ }
560
+ .signin-trust {
561
+ display: flex;
562
+ flex-direction: column;
563
+ gap: 12px;
564
+ border-top: 1px solid var(--fidj-line-soft);
565
+ padding-top: 20px;
566
+ }
567
+ .signin-trust-head {
568
+ display: flex;
569
+ align-items: center;
570
+ gap: 10px;
571
+ }
572
+ .signin-trust .signin-logo {
573
+ width: 18px;
574
+ height: 18px;
575
+ flex: none;
576
+ }
577
+ .signin-trust strong {
578
+ font-size: 13px;
579
+ color: var(--fidj-text);
580
+ }
581
+ .signin-trust p:not(.signin-trust-head) {
582
+ display: flex;
583
+ align-items: baseline;
584
+ gap: 10px;
585
+ margin: 0;
586
+ font-size: 13px;
587
+ line-height: 1.55;
588
+ color: var(--fidj-text-muted);
589
+ }
590
+ .signin-trust p:not(.signin-trust-head)::before {
591
+ content: "";
592
+ width: 5px;
593
+ height: 5px;
594
+ border-radius: 50%;
595
+ background: var(--fidj-accent);
596
+ flex: none;
597
+ transform: translateY(-2px);
598
+ }
599
+
600
+ .signin-form {
601
+ flex: 1 1 420px;
602
+ background: var(--fidj-paper);
603
+ padding: 56px clamp(28px, 4vw, 64px) 44px;
604
+ display: flex;
605
+ flex-direction: column;
606
+ gap: 28px;
607
+ }
608
+ .signin-form > * {
609
+ max-width: 400px;
610
+ width: 100%;
611
+ margin-inline: auto;
612
+ }
613
+ .signin-form h2 {
614
+ font-family: var(--fidj-font-display);
615
+ font-weight: 400;
616
+ font-size: 34px;
617
+ line-height: 1.1;
618
+ letter-spacing: -0.01em;
619
+ margin: 0 0 20px;
620
+ }
621
+ .signin-form > p {
622
+ margin: 0;
623
+ font-size: 14px;
624
+ }
625
+ .signin-form input {
626
+ min-height: 48px;
627
+ }
628
+ .signin-form form > button {
629
+ min-height: 48px;
630
+ width: 100%;
631
+ margin-top: 12px;
632
+ }
633
+ .signin-form .secondary {
634
+ background: transparent;
635
+ margin-top: 8px;
636
+ font-weight: 500;
637
+ }
638
+ /* The label row carries its own escape hatch, as the mockup does: the reset
639
+ * link sits with the field it is about, not adrift under the form. */
640
+ .field-head {
641
+ display: flex;
642
+ align-items: center;
643
+ justify-content: space-between;
644
+ gap: 12px;
645
+ margin: 18px 0 7px;
646
+ }
647
+ .field-head label {
648
+ margin: 0;
649
+ }
650
+ .field-head a {
651
+ font-size: 12px;
652
+ color: var(--fidj-text-faint);
653
+ text-decoration: underline;
654
+ text-underline-offset: 3px;
655
+ }
656
+ .password-field {
657
+ position: relative;
658
+ display: block;
659
+ }
660
+ .password-field input {
661
+ padding-right: 68px;
662
+ }
663
+ .password-field button {
664
+ position: absolute;
665
+ right: 5px;
666
+ top: 50%;
667
+ transform: translateY(-50%);
668
+ border: 0;
669
+ background: none;
670
+ font-family: var(--fidj-font-mono);
671
+ font-size: 11px;
672
+ letter-spacing: 0.06em;
673
+ text-transform: uppercase;
674
+ color: var(--fidj-text-faint);
675
+ padding: 8px;
676
+ }
677
+ .password-field button:hover:not(:disabled) {
678
+ color: var(--fidj-text);
679
+ }
680
+ .signin-divider {
681
+ display: flex;
682
+ align-items: center;
683
+ gap: 12px;
684
+ font-family: var(--fidj-font-mono);
685
+ font-size: 10.5px;
686
+ letter-spacing: 0.1em;
687
+ text-transform: uppercase;
688
+ color: var(--fidj-text-faint);
689
+ margin: 0;
690
+ }
691
+ .signin-divider::before,
692
+ .signin-divider::after {
693
+ content: "";
694
+ height: 1px;
695
+ flex: 1;
696
+ background: var(--fidj-line);
697
+ }
698
+ .anonymous-entry {
699
+ display: flex;
700
+ justify-content: space-between;
701
+ align-items: center;
702
+ width: 100%;
703
+ min-height: 46px;
704
+ }
705
+ .signin-form .signin-footnote {
706
+ font-size: 12px;
707
+ text-align: center;
708
+ margin: 0;
709
+ }
710
+ .signin-badges {
711
+ margin-top: auto;
712
+ padding-top: 24px;
713
+ display: flex;
714
+ flex-wrap: wrap;
715
+ gap: 8px;
716
+ }
717
+ .signin-badges span {
718
+ font-family: var(--fidj-font-mono);
719
+ font-size: 10.5px;
720
+ letter-spacing: 0.06em;
721
+ text-transform: uppercase;
722
+ color: var(--fidj-text-faint);
723
+ border: 1px solid var(--fidj-line);
724
+ padding: 5px 9px;
725
+ }
726
+
727
+ @media (max-width: 860px) {
728
+ .signin-intro {
729
+ gap: 32px;
730
+ padding: 36px 24px 32px;
731
+ }
732
+ .signin-form {
733
+ padding: 36px 24px 32px;
734
+ }
735
+ .signin-description {
736
+ font-size: 15px;
737
+ }
738
+ }
739
+
740
+ .public-content {
741
+ text-align: center;
742
+ margin: 2rem 0;
743
+ }
744
+ .public-content img {
745
+ display: inline-block;
746
+ width: min(100%, 520px);
747
+ height: auto;
748
+ }
749
+ .public-content h1 {
750
+ font-size: clamp(2rem, 5vw, 3.5rem);
751
+ }
752
+ .content-account {
753
+ max-width: 680px;
754
+ margin: 2rem auto;
755
+ }
756
+ .content-account button {
757
+ margin: 0.4rem 0.4rem 0.4rem 0;
758
+ }
759
+ .content-account input:not([type="checkbox"]) {
760
+ width: 100%;
761
+ }
762
+ .content-nav {
763
+ display: flex;
764
+ align-items: center;
765
+ gap: 10px;
766
+ }
767
+ .content-nav #exit {
768
+ margin-left: auto;
769
+ }
770
+ .signin-logo {
771
+ width: 22px;
772
+ height: 22px;
773
+ }
774
+
775
+ button:focus-visible,
776
+ a:focus-visible,
777
+ input:focus-visible,
778
+ summary:focus-visible {
779
+ outline: 2px solid var(--fidj-ink);
780
+ outline-offset: 3px;
781
+ }
782
+
783
+ /* The personal site layout mleweb builds from --content. Same system, wider
784
+ * measure: the supplied HTML is developer-authored and styled, not sanitised. */
785
+ .site-nav {
786
+ border: 0;
787
+ margin: 0;
788
+ padding: 0;
789
+ align-items: center;
790
+ gap: 24px;
791
+ font-size: 13px;
792
+ }
793
+ .workspace-link {
794
+ border: 1px solid var(--fidj-line-strong);
795
+ border-radius: var(--fidj-radius);
796
+ padding: 9px 14px;
797
+ }
798
+ .personal-hero {
799
+ display: grid;
800
+ grid-template-columns: 1.1fr 1fr;
801
+ gap: 36px;
802
+ align-items: center;
803
+ min-height: 590px;
804
+ }
805
+ .mario-scene {
806
+ text-align: center;
807
+ }
808
+ .mario-scene img {
809
+ width: 100%;
810
+ max-width: 570px;
811
+ height: auto;
812
+ object-fit: contain;
813
+ image-rendering: pixelated;
814
+ }
815
+ .personal-intro h1 {
816
+ font-size: clamp(44px, 6vw, 66px);
817
+ line-height: 1.05;
818
+ max-width: 480px;
819
+ }
820
+ .personal-tagline {
821
+ font-size: 19px;
822
+ color: var(--fidj-text-muted);
823
+ }
824
+ .personal-intro > p {
825
+ max-width: 440px;
826
+ }
827
+ .site-links {
828
+ display: flex;
829
+ align-items: center;
830
+ gap: 24px;
831
+ margin: 28px 0;
832
+ }
833
+ .site-primary {
834
+ display: inline-block;
835
+ padding: 13px 19px;
836
+ border-radius: var(--fidj-radius);
837
+ background: var(--fidj-ink);
838
+ color: var(--fidj-paper);
839
+ font-weight: 600;
840
+ font-size: 14px;
841
+ }
842
+ .site-primary:hover {
843
+ background: var(--fidj-ink-raised);
844
+ color: var(--fidj-paper);
845
+ }
846
+ .personal-contact {
847
+ font-size: 13px;
848
+ line-height: 2;
849
+ }
850
+ .resume-section {
851
+ scroll-margin-top: 30px;
852
+ display: grid;
853
+ grid-template-columns: 0.7fr 1.3fr;
854
+ gap: 70px;
855
+ border-top: 1px solid var(--fidj-line-soft);
856
+ padding: 60px 0;
857
+ }
858
+ .resume-intro h2 {
859
+ font-family: var(--fidj-font-display);
860
+ font-weight: 400;
861
+ font-size: 34px;
862
+ }
863
+ .resume-timeline article {
864
+ padding: 0 0 26px 24px;
865
+ border-left: 1px solid var(--fidj-line);
866
+ }
867
+ .resume-timeline h3 {
868
+ margin: 4px 0 8px;
869
+ }
870
+ .resume-timeline h3 span {
871
+ font-weight: 400;
872
+ }
873
+ .resume-period {
874
+ font-family: var(--fidj-font-mono);
875
+ font-size: 11px;
876
+ letter-spacing: 0.08em;
877
+ text-transform: uppercase;
878
+ margin: 0;
879
+ color: var(--fidj-text-faint);
880
+ }
881
+ .resume-timeline article > p:last-child {
882
+ margin-bottom: 0;
883
+ }
884
+ .personal-footer {
885
+ display: flex;
886
+ justify-content: space-between;
887
+ align-items: center;
888
+ gap: 25px;
889
+ }
890
+ .personal-footer p {
891
+ margin-bottom: 0;
892
+ }
893
+
894
+ @media (max-width: 760px) {
895
+ .personal-hero,
896
+ .resume-section {
897
+ grid-template-columns: 1fr;
898
+ gap: 28px;
899
+ min-height: 0;
900
+ }
901
+ .resume-section {
902
+ padding: 36px 0;
903
+ }
904
+ .personal-footer,
905
+ .site-links {
906
+ flex-wrap: wrap;
907
+ gap: 16px;
908
+ }
909
+ }
910
+
911
+ .signin-agreement { margin-block: 1rem; }
912
+ .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); }
913
+ .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); }
914
+ .signin-agreement button { margin-block: 0.5rem; padding: 0; border: 0; background: transparent; text-decoration: underline; }
915
+ #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; }
916
+ #agreement-text { white-space: pre-wrap; overflow-wrap: anywhere; }