moracarta 2.1.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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +84 -0
  3. package/index.html +31 -0
  4. package/package.json +35 -0
  5. package/public/assets/images/corner.webp +0 -0
  6. package/public/assets/images/custom-text-demo1.png +0 -0
  7. package/public/assets/images/custom-text-demo2.png +0 -0
  8. package/public/assets/images/demo-animation.gif +0 -0
  9. package/public/assets/images/demo-main-page.png +0 -0
  10. package/public/assets/images/googleDocsTabs.webp +0 -0
  11. package/public/assets/images/setup-demo.png +0 -0
  12. package/public/robots.txt +2 -0
  13. package/src/commands/add.js +170 -0
  14. package/src/commands/cliConfig.js +68 -0
  15. package/src/commands/deploy.js +41 -0
  16. package/src/commands/remove.js +198 -0
  17. package/src/commands/setup.js +257 -0
  18. package/src/config/fonts.js +7 -0
  19. package/src/data/letters.example.js +28 -0
  20. package/src/data/lettersLoader.js +7 -0
  21. package/src/i18n/de.js +8 -0
  22. package/src/i18n/en.js +8 -0
  23. package/src/i18n/es.js +8 -0
  24. package/src/i18n/fr.js +8 -0
  25. package/src/i18n/it.js +8 -0
  26. package/src/i18n/ja.js +8 -0
  27. package/src/i18n/ko.js +8 -0
  28. package/src/i18n/nl.js +0 -0
  29. package/src/i18n/pr.js +0 -0
  30. package/src/i18n/pt-BR.js +8 -0
  31. package/src/i18n/ru.js +8 -0
  32. package/src/i18n/tl.js +0 -0
  33. package/src/i18n/zh.js +8 -0
  34. package/src/scripts/data.variable.js +24 -0
  35. package/src/scripts/i18n.js +67 -0
  36. package/src/scripts/letters.script.js +257 -0
  37. package/src/scripts/main.script.js +101 -0
  38. package/src/services/googleDocs.js +76 -0
  39. package/src/styles/letters.css +405 -0
  40. package/src/styles/main.css +338 -0
  41. package/src/views/letters.view.html +83 -0
  42. package/vite.config.mjs +16 -0
@@ -0,0 +1,405 @@
1
+ *, *::before, *::after {
2
+ box-sizing: border-box;
3
+ margin: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ :root {
8
+ --main-font: 'Cormorant Garamond', serif;
9
+ --paper: #fdf6e3;
10
+ --paper-dark: #f5e6c8;
11
+ --ink: #3b2f1e;
12
+ --ink-soft: #7a6248;
13
+ --ink-light: #a8906e;
14
+ --red: #8b2e2e;
15
+ }
16
+
17
+ body {
18
+ background-color: #2c1f0f;
19
+ background-image:
20
+ radial-gradient(ellipse at 20% 10%, #3d2a10 0%, transparent 50%),
21
+ radial-gradient(ellipse at 80% 90%, #1a0f05 0%, transparent 50%);
22
+ min-height: 100vh;
23
+ font-family: var(--main-font);
24
+ font-optical-sizing: auto;
25
+ color: var(--ink);
26
+ padding: 0 0 60px;
27
+ }
28
+
29
+ .back-link-wrap {
30
+ padding: 20px 20px 0;
31
+ max-width: 480px;
32
+ margin: 0 auto;
33
+ }
34
+
35
+ .back-link {
36
+ display: inline-flex;
37
+ align-items: center;
38
+ gap: 6px;
39
+ text-decoration: none;
40
+ color: #a08060;
41
+ font-size: 13px;
42
+ font-style: italic;
43
+ letter-spacing: 0.3px;
44
+ transition: color 0.2s;
45
+ }
46
+
47
+ .back-link:active {
48
+ color: var(--paper-dark);
49
+ }
50
+
51
+ .back-link-arrow {
52
+ font-size: 16px;
53
+ line-height: 1;
54
+ }
55
+
56
+ .envelope-animation-wrap {
57
+ display: flex;
58
+ align-items: flex-start;
59
+ justify-content: center;
60
+ padding: 22vh 20px 0;
61
+ min-height: calc(100vh - 52px);
62
+ }
63
+
64
+ .envelope-stage {
65
+ position: relative;
66
+ width: 100%;
67
+ max-width: 380px;
68
+ aspect-ratio: 1 / 0.5;
69
+ opacity: 0;
70
+ transition: opacity 0.15s ease;
71
+ }
72
+
73
+ .envelope-stage.ready {
74
+ opacity: 1;
75
+ }
76
+
77
+ .env-fundo {
78
+ position: absolute;
79
+ inset: 0;
80
+ background: #e8d5b0;
81
+ border-radius: 4px;
82
+ z-index: 1;
83
+ }
84
+
85
+ .env-papel {
86
+ position: absolute;
87
+ left: 11%;
88
+ right: 11%;
89
+ bottom: 14px;
90
+ height: 65%;
91
+ background: var(--paper);
92
+ border-radius: 2px 2px 0 0;
93
+ z-index: 2;
94
+ transform: translateY(0);
95
+ transition: transform 0.85s cubic-bezier(0.4, 0, 0.2, 1) 0.45s;
96
+ box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.12);
97
+ overflow: hidden;
98
+ }
99
+
100
+ .env-papel.leaving {
101
+ transform: translateY(-120%);
102
+ }
103
+
104
+ .paper-text {
105
+ padding: 16px 12px;
106
+ font-size: 13px;
107
+ line-height: 1.8;
108
+ color: #5a4632;
109
+ font-family: Georgia, 'Times New Roman', Times, serif;
110
+ text-align: center;
111
+ font-style: italic;
112
+ }
113
+
114
+ .env-corpo-svg {
115
+ position: absolute;
116
+ inset: 0;
117
+ z-index: 3;
118
+ pointer-events: none;
119
+ }
120
+
121
+ .env-corpo-svg svg {
122
+ width: 100%;
123
+ height: 100%;
124
+ }
125
+
126
+ .env-aba {
127
+ position: absolute;
128
+ top: 0;
129
+ left: 0;
130
+ right: 0;
131
+ height: 72%;
132
+ z-index: 4;
133
+ transform-origin: top center;
134
+ transition: transform 0.65s cubic-bezier(0.4, 0, 0.2, 1);
135
+ pointer-events: none;
136
+ overflow: visible;
137
+ }
138
+
139
+ .env-aba.open {
140
+ transform: rotateX(180deg);
141
+ }
142
+
143
+ .env-aba.behind {
144
+ z-index: 0;
145
+ }
146
+
147
+ .env-aba svg {
148
+ width: 100%;
149
+ height: 100%;
150
+ }
151
+
152
+ .env-lacre {
153
+ position: absolute;
154
+ z-index: 5;
155
+ width: 50px;
156
+ height: 50px;
157
+ background: var(--red);
158
+ border-radius: 50%;
159
+ display: flex;
160
+ align-items: center;
161
+ justify-content: center;
162
+ font-size: 18px;
163
+ color: #f5c6c6;
164
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4), inset 0 1px 3px rgba(255, 255, 255, 0.15);
165
+ left: 50%;
166
+ top: 74%;
167
+ transform: translate(-50%, -100%);
168
+ transition: opacity 0.3s ease 0.25s, transform 0.3s ease 0.25s;
169
+ }
170
+
171
+ .seal-heart {
172
+ display: inline-block;
173
+ line-height: 1;
174
+ transform: translate(-1px, 1px);
175
+ font-size: 18px;
176
+ will-change: transform;
177
+ }
178
+
179
+ .env-lacre.fading {
180
+ opacity: 0;
181
+ transform: translate(-50%, -120%) scale(0.5);
182
+ }
183
+
184
+ .letter-wrap {
185
+ max-width: 480px;
186
+ margin: 0 auto;
187
+ padding: 0 16px;
188
+ opacity: 0;
189
+ transform: translateY(20px);
190
+ transition: opacity 0.5s ease, transform 0.5s ease;
191
+ }
192
+
193
+ .letter-wrap.visible {
194
+ opacity: 1;
195
+ transform: translateY(0);
196
+ margin-top: 10px;
197
+ }
198
+
199
+ .letter {
200
+ background: var(--paper);
201
+ border-radius: 2px;
202
+ padding: 10px 28px 40px;
203
+ position: relative;
204
+ background-image: repeating-linear-gradient(
205
+ transparent,
206
+ transparent 27px,
207
+ rgba(168, 144, 110, 0.15) 28px
208
+ );
209
+ background-position: 0 36px;
210
+ overflow: hidden;
211
+ z-index: 0;
212
+ font-family: var(--main-font);
213
+ font-optical-sizing: auto;
214
+ letter-spacing: 0.01em;
215
+ }
216
+
217
+ .letter-corners {
218
+ position: absolute;
219
+ inset: 0;
220
+ pointer-events: none;
221
+ z-index: 0;
222
+ }
223
+
224
+ .letter-corner {
225
+ position: absolute;
226
+ width: 72px;
227
+ height: 72px;
228
+ background-image: url('/assets/images/corner.webp');
229
+ background-size: contain;
230
+ background-repeat: no-repeat;
231
+ opacity: 0.9;
232
+ filter: sepia(0.25) saturate(0.9) brightness(0.95) hue-rotate(-10deg);
233
+ }
234
+
235
+ .letter-corner-tl {
236
+ top: 12px;
237
+ left: 12px;
238
+ transform: rotate(0deg);
239
+ }
240
+
241
+ .letter-corner-tr {
242
+ top: 12px;
243
+ right: 12px;
244
+ transform: scaleX(-1);
245
+ }
246
+
247
+ .letter-corner-bl {
248
+ bottom: 12px;
249
+ left: 12px;
250
+ transform: scaleY(-1);
251
+ }
252
+
253
+ .letter-corner-br {
254
+ bottom: 12px;
255
+ right: 12px;
256
+ transform: scale(-1, -1);
257
+ }
258
+
259
+ .letter::after {
260
+ content: '';
261
+ position: absolute;
262
+ top: 0;
263
+ right: 0;
264
+ width: 0;
265
+ height: 0;
266
+ border-style: solid;
267
+ border-width: 0 28px 28px 0;
268
+ border-color: transparent #f5e6c8 transparent transparent;
269
+ filter: drop-shadow(-2px 2px 2px rgba(0, 0, 0, 0.1));
270
+ z-index: 1;
271
+ }
272
+
273
+ .letter-top {
274
+ text-align: center;
275
+ margin-bottom: 10px;
276
+ }
277
+
278
+ .letter-ornament {
279
+ color: var(--red);
280
+ font-size: 18px;
281
+ letter-spacing: 8px;
282
+ opacity: 0.7;
283
+ font-style: normal;
284
+ }
285
+
286
+ .letter-date {
287
+ font-size: 12px;
288
+ letter-spacing: 1px;
289
+ text-transform: uppercase;
290
+ color: var(--ink-light);
291
+ font-style: italic;
292
+ display: block;
293
+ margin-top: 8px;
294
+ }
295
+
296
+ .letter-title {
297
+ font-family: var(--main-font);
298
+ font-optical-sizing: auto;
299
+ font-weight: 500;
300
+ font-style: normal;
301
+ font-size: 26px;
302
+ letter-spacing: 0.08em;
303
+ color: var(--ink);
304
+ text-align: center;
305
+ line-height: 1.2;
306
+ margin-top: 10px;
307
+ }
308
+
309
+ .letter-divider {
310
+ width: 50px;
311
+ height: 1px;
312
+ background: linear-gradient(to right, transparent, var(--ink-light), transparent);
313
+ margin: 10px auto 14px;
314
+ opacity: 0.7;
315
+ }
316
+
317
+ .letter-body {
318
+ font-size: 16px;
319
+ line-height: 2;
320
+ color: var(--ink);
321
+ font-family: var(--main-font);
322
+ text-align: justify;
323
+ white-space: pre-wrap;
324
+ tab-size: 4;
325
+ font-style: italic;
326
+ }
327
+
328
+ .letter-body p {
329
+ margin-bottom: 1.2em;
330
+ }
331
+
332
+ .letter-body p:first-child {
333
+ text-indent: 0;
334
+ }
335
+
336
+ .letter-footer {
337
+ margin-top: 32px;
338
+ text-align: center;
339
+ padding-top: 20px;
340
+ border-top: 1px solid rgba(168, 144, 110, 0.25);
341
+ }
342
+
343
+ .letter-footer-ornament {
344
+ color: var(--red);
345
+ font-size: 20px;
346
+ opacity: 0.6;
347
+ font-style: normal;
348
+ }
349
+
350
+ .letter-nav {
351
+ max-width: 480px;
352
+ margin: 24px auto 0;
353
+ padding: 0 16px;
354
+ display: flex;
355
+ justify-content: space-between;
356
+ align-items: center;
357
+ opacity: 0;
358
+ transition: opacity 0.4s ease 0.3s;
359
+ }
360
+
361
+ .letter-nav.visible {
362
+ opacity: 1;
363
+ }
364
+
365
+ .nav-button {
366
+ text-decoration: none;
367
+ color: #a08060;
368
+ font-size: 13px;
369
+ font-style: italic;
370
+ display: flex;
371
+ align-items: center;
372
+ gap: 4px;
373
+ padding: 8px 4px;
374
+ }
375
+
376
+ .nav-button:active {
377
+ color: var(--paper-dark);
378
+ }
379
+
380
+ .nav-button.invisible {
381
+ visibility: hidden;
382
+ }
383
+
384
+ .nav-counter {
385
+ font-size: 12px;
386
+ color: #6b4c2a;
387
+ font-style: italic;
388
+ }
389
+
390
+ .error {
391
+ text-align: center;
392
+ padding: 60px 24px;
393
+ color: #a08060;
394
+ font-style: italic;
395
+ }
396
+
397
+ #canvas-hearts {
398
+ position: fixed;
399
+ inset: 0;
400
+ width: 100%;
401
+ height: 100%;
402
+ pointer-events: none;
403
+ z-index: 9999;
404
+ }
405
+
@@ -0,0 +1,338 @@
1
+ *, *::before, *::after {
2
+ box-sizing: border-box;
3
+ margin: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ :root {
8
+ --main-font: 'Cormorant Garamond', serif;
9
+ --paper: #fdf6e3;
10
+ --paper-dark: #f5e6c8;
11
+ --ink: #3b2f1e;
12
+ --ink-soft: #7a6248;
13
+ --ink-light: #a8906e;
14
+ --envelope-front: #e8d5b0;
15
+ --envelope-flap: #d4b896;
16
+ --envelope-shadow: #c4a07a;
17
+ --red: #8b2e2e;
18
+ --red-soft: #c04040;
19
+ }
20
+
21
+ body {
22
+ background-color: #2c1f0f;
23
+ background-image:
24
+ radial-gradient(ellipse at 20% 10%, #3d2a10 0%, transparent 50%),
25
+ radial-gradient(ellipse at 80% 90%, #1a0f05 0%, transparent 50%);
26
+ min-height: 100vh;
27
+ font-family: var(--main-font);
28
+ color: var(--ink);
29
+ padding: 0 0 60px;
30
+ }
31
+
32
+ .header {
33
+ text-align: center;
34
+ padding: 48px 24px 32px;
35
+ position: relative;
36
+ }
37
+
38
+ .header-ornament {
39
+ color: var(--red);
40
+ font-size: 28px;
41
+ letter-spacing: 12px;
42
+ margin-bottom: 16px;
43
+ opacity: 0.8;
44
+ }
45
+
46
+ .header h1 {
47
+ font-family: 'Playfair Display', Georgia, serif;
48
+ font-size: 28px;
49
+ font-weight: 400;
50
+ font-style: italic;
51
+ color: var(--paper-dark);
52
+ line-height: 1.3;
53
+ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
54
+ margin-bottom: 8px;
55
+ }
56
+
57
+ .header-line {
58
+ width: 80px;
59
+ height: 1px;
60
+ background: linear-gradient(to right, transparent, var(--red), transparent);
61
+ margin: 16px auto 0;
62
+ }
63
+
64
+ .header-sub {
65
+ max-width: 560px;
66
+ margin: 12px auto 0;
67
+ color: #a08060;
68
+ font-size: 14px;
69
+ line-height: 1.75;
70
+ letter-spacing: 0.35px;
71
+ text-align: center;
72
+ padding: 0 12px;
73
+ }
74
+
75
+ .love-note {
76
+ text-align: justify;
77
+ text-justify: inter-word;
78
+ -webkit-hyphens: auto;
79
+ -ms-hyphens: auto;
80
+ hyphens: auto;
81
+ font-style: italic;
82
+ font-family: 'Playfair Display', Georgia, serif;
83
+ font-size: 15px;
84
+ color: #d9b892;
85
+ line-height: 1.85;
86
+ padding: 12px 56px 8px 28px;
87
+ position: relative;
88
+ letter-spacing: 0.2px;
89
+ }
90
+
91
+ .love-note::before {
92
+ content: '“';
93
+ position: absolute;
94
+ left: 12px;
95
+ top: -10px;
96
+ font-family: 'Playfair Display', Georgia, serif;
97
+ font-size: 34px;
98
+ color: rgba(219, 174, 125, 0.95);
99
+ line-height: 1;
100
+ opacity: 0.95;
101
+ pointer-events: none;
102
+ }
103
+
104
+ .love-note::after {
105
+ content: '”';
106
+ position: absolute;
107
+ right: 18px;
108
+ bottom: 4px;
109
+ font-family: 'Playfair Display', Georgia, serif;
110
+ font-size: 28px;
111
+ color: rgba(219, 174, 125, 0.95);
112
+ line-height: 1;
113
+ opacity: 0.95;
114
+ pointer-events: none;
115
+ }
116
+
117
+ .letter-list {
118
+ padding: 8px 20px;
119
+ display: flex;
120
+ flex-direction: column;
121
+ gap: 20px;
122
+ max-width: 480px;
123
+ margin: 0 auto;
124
+ }
125
+
126
+ .envelope-link {
127
+ text-decoration: none;
128
+ display: block;
129
+ }
130
+
131
+ .envelope-wrap {
132
+ position: relative;
133
+ cursor: pointer;
134
+ transform: rotate(-0.5deg);
135
+ transition: transform 0.3s ease;
136
+ }
137
+
138
+ .envelope-wrap:nth-child(even) {
139
+ transform: rotate(0.5deg);
140
+ }
141
+
142
+ .envelope-wrap:active {
143
+ transform: scale(0.97) rotate(0deg);
144
+ }
145
+
146
+ .envelope-sombra {
147
+ position: absolute;
148
+ bottom: -6px;
149
+ left: 6px;
150
+ right: -6px;
151
+ height: 100%;
152
+ background: #1a0f05;
153
+ border-radius: 4px;
154
+ opacity: 0.4;
155
+ z-index: 0;
156
+ }
157
+
158
+ .envelope {
159
+ position: relative;
160
+ z-index: 1;
161
+ background: var(--envelope-front);
162
+ border-radius: 4px;
163
+ overflow: visible;
164
+ height: 30vh;
165
+ width: 100%;
166
+ }
167
+
168
+ .envelope::before {
169
+ content: '';
170
+ position: absolute;
171
+ bottom: 0;
172
+ left: 0;
173
+ right: 0;
174
+ height: 55%;
175
+ background:
176
+ linear-gradient(135deg, var(--envelope-shadow) 50%, transparent 50%),
177
+ linear-gradient(225deg, var(--envelope-shadow) 50%, transparent 50%);
178
+ background-size: 50% 100%;
179
+ background-position: left bottom, right bottom;
180
+ background-repeat: no-repeat;
181
+ }
182
+
183
+ .env-corpo-svg {
184
+ position: absolute;
185
+ inset: 0;
186
+ z-index: 1;
187
+ pointer-events: none;
188
+ }
189
+
190
+ .env-corpo-svg svg {
191
+ width: 100%;
192
+ height: 100%;
193
+ display: block;
194
+ }
195
+
196
+ .env-aba {
197
+ position: relative;
198
+ z-index: 4;
199
+ pointer-events: none;
200
+ overflow: visible;
201
+ height: 17vh;
202
+ width: 100%;
203
+ }
204
+
205
+ .env-aba svg {
206
+ width: 100%;
207
+ height: 100%;
208
+ display: block;
209
+ }
210
+
211
+ .env-lacre {
212
+ position: absolute;
213
+ z-index: 5;
214
+ width: 48px;
215
+ height: 48px;
216
+ background: var(--red);
217
+ border-radius: 50%;
218
+ display: flex;
219
+ align-items: center;
220
+ justify-content: center;
221
+ font-size: 16px;
222
+ color: #f5c6c6;
223
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4), inset 0 1px 3px rgba(255, 255, 255, 0.15);
224
+ left: 50%;
225
+ transform: translate(-50%, 0);
226
+ bottom: -24px;
227
+ }
228
+
229
+ .envelope-centro {
230
+ position: relative;
231
+ z-index: 2;
232
+ padding: 12px 16px 16px;
233
+ display: flex;
234
+ flex-direction: column;
235
+ gap: 2px;
236
+ }
237
+
238
+ .envelope-data {
239
+ font-size: 10px;
240
+ letter-spacing: 0.5px;
241
+ text-transform: uppercase;
242
+ color: var(--ink-soft);
243
+ font-family: 'Lora', serif;
244
+ font-style: italic;
245
+ }
246
+
247
+ .envelope-titulo {
248
+ font-family: 'Playfair Display', Georgia, serif;
249
+ font-size: 16px;
250
+ font-weight: 600;
251
+ color: var(--ink);
252
+ line-height: 1.2;
253
+ }
254
+
255
+ .envelope-hint {
256
+ font-size: 11px;
257
+ color: var(--ink-soft);
258
+ margin-top: 3px;
259
+ display: flex;
260
+ align-items: center;
261
+ gap: 4px;
262
+ }
263
+
264
+ .envelope-hint::before {
265
+ content: '✦';
266
+ font-size: 8px;
267
+ color: var(--red);
268
+ }
269
+
270
+ .envelope-canto {
271
+ position: absolute;
272
+ width: 20px;
273
+ height: 20px;
274
+ border-color: var(--envelope-shadow);
275
+ border-style: solid;
276
+ opacity: 0.5;
277
+ }
278
+
279
+ .envelope-canto.tl {
280
+ top: 6px;
281
+ left: 6px;
282
+ border-width: 1px 0 0 1px;
283
+ }
284
+
285
+ .envelope-canto.tr {
286
+ top: 6px;
287
+ right: 6px;
288
+ border-width: 1px 1px 0 0;
289
+ }
290
+
291
+ .envelope-canto.bl {
292
+ bottom: 6px;
293
+ left: 6px;
294
+ border-width: 0 0 1px 1px;
295
+ }
296
+
297
+ .envelope-canto.br {
298
+ bottom: 6px;
299
+ right: 6px;
300
+ border-width: 0 1px 1px 0;
301
+ }
302
+
303
+ @media (hover: hover) {
304
+ .envelope-wrap:hover {
305
+ transform: rotate(0deg) translateY(-3px);
306
+ }
307
+
308
+ .envelope-wrap:nth-child(even):hover {
309
+ transform: rotate(0deg) translateY(-3px);
310
+ }
311
+ }
312
+
313
+ .footer {
314
+ text-align: center;
315
+ margin-top: 40px;
316
+ padding: 0 20px;
317
+ max-width: 480px;
318
+ margin-left: auto;
319
+ margin-right: auto;
320
+ }
321
+
322
+ .footer-line {
323
+ width: 60px;
324
+ height: 1px;
325
+ background: linear-gradient(to right, transparent, #6b4c2a, transparent);
326
+ margin: 0 auto 16px;
327
+ }
328
+
329
+ .footer p {
330
+ font-size: 12px;
331
+ color: #6b4c2a;
332
+ font-style: italic;
333
+ letter-spacing: 0.5px;
334
+ line-height: 1.8;
335
+ text-align: justify;
336
+ }
337
+
338
+