@jjlmoya/utils-babies 1.4.0 → 1.5.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.
@@ -1,18 +1,29 @@
1
1
  ---
2
- import './style.css';
3
- import type { PregnancyCalculatorUI } from './index';
4
- interface Props { ui: PregnancyCalculatorUI; }
2
+ import type { PregnancyCalculatorUI } from "./index";
3
+ interface Props {
4
+ ui: PregnancyCalculatorUI;
5
+ }
5
6
  const { ui } = Astro.props;
6
7
  ---
7
- <div id="pregnancy-calculator-root" class="pregnancy-calculator" data-ui={JSON.stringify(ui)}>
8
8
 
9
+ <div
10
+ id="pregnancy-calculator-root"
11
+ class="pregnancy-calculator"
12
+ data-ui={JSON.stringify(ui)}
13
+ >
9
14
  <div class="pregnancy-calculator-header">
10
15
  <div class="pregnancy-calculator-method-group">
11
- <button class="pregnancy-calculator-method-btn" data-method="fur">{ui.btnFUR}</button>
12
- <button class="pregnancy-calculator-method-btn" data-method="conception">{ui.btnConception}</button>
16
+ <button class="pregnancy-calculator-method-btn" data-method="fur"
17
+ >{ui.btnFUR}</button
18
+ >
19
+ <button class="pregnancy-calculator-method-btn" data-method="conception"
20
+ >{ui.btnConception}</button
21
+ >
13
22
  </div>
14
23
  <label class="pregnancy-calculator-partner-wrap">
15
- <span class="pregnancy-calculator-partner-label">{ui.labelPartnerMode}</span>
24
+ <span class="pregnancy-calculator-partner-label"
25
+ >{ui.labelPartnerMode}</span
26
+ >
16
27
  <div class="pregnancy-calculator-toggle-track">
17
28
  <div class="pregnancy-calculator-toggle-thumb"></div>
18
29
  </div>
@@ -20,20 +31,33 @@ const { ui } = Astro.props;
20
31
  </div>
21
32
 
22
33
  <div class="pregnancy-calculator-main">
23
-
24
34
  <div class="pregnancy-calculator-left">
25
35
  <div class="pregnancy-calculator-dp-wrap">
26
- <span class="pregnancy-calculator-dp-label" id="pc-dp-label">{ui.labelFUR}</span>
36
+ <span class="pregnancy-calculator-dp-label" id="pc-dp-label"
37
+ >{ui.labelFUR}</span
38
+ >
27
39
  <div class="pregnancy-calculator-dp-selects">
28
- <select id="pc-dp-day" class="pregnancy-calculator-dp-select" aria-label="Día">
40
+ <select
41
+ id="pc-dp-day"
42
+ class="pregnancy-calculator-dp-select"
43
+ aria-label="Día"
44
+ >
29
45
  <option value="">Día</option>
30
46
  </select>
31
47
  <span class="pregnancy-calculator-dp-sep">/</span>
32
- <select id="pc-dp-month" class="pregnancy-calculator-dp-select" aria-label="Mes">
48
+ <select
49
+ id="pc-dp-month"
50
+ class="pregnancy-calculator-dp-select"
51
+ aria-label="Mes"
52
+ >
33
53
  <option value="">Mes</option>
34
54
  </select>
35
55
  <span class="pregnancy-calculator-dp-sep">/</span>
36
- <select id="pc-dp-year" class="pregnancy-calculator-dp-select" aria-label="Año">
56
+ <select
57
+ id="pc-dp-year"
58
+ class="pregnancy-calculator-dp-select"
59
+ aria-label="Año"
60
+ >
37
61
  <option value="">Año</option>
38
62
  </select>
39
63
  </div>
@@ -41,7 +65,9 @@ const { ui } = Astro.props;
41
65
 
42
66
  <div class="pregnancy-calculator-cs-wrap" id="pc-cs-wrap">
43
67
  <div class="pregnancy-calculator-cs-header">
44
- <span class="pregnancy-calculator-cs-label">{ui.labelCycleLength}</span>
68
+ <span class="pregnancy-calculator-cs-label"
69
+ >{ui.labelCycleLength}</span
70
+ >
45
71
  <span class="pregnancy-calculator-cs-value-wrap">
46
72
  <span id="pc-cs-value">28</span>
47
73
  <span class="pregnancy-calculator-cs-unit">{ui.unitDays}</span>
@@ -66,47 +92,79 @@ const { ui } = Astro.props;
66
92
  <div class="pregnancy-calculator-stats-row">
67
93
  <div class="pregnancy-calculator-stat-chip">
68
94
  <span class="pregnancy-calculator-stat-key">{ui.labelWeeks}</span>
69
- <span class="pregnancy-calculator-stat-value pregnancy-calculator-accent" id="pc-sd-weeks">—</span>
95
+ <span
96
+ class="pregnancy-calculator-stat-value pregnancy-calculator-accent"
97
+ id="pc-sd-weeks">—</span
98
+ >
70
99
  </div>
71
100
  <div class="pregnancy-calculator-stat-chip">
72
- <span class="pregnancy-calculator-stat-key">{ui.labelTrimester}</span>
73
- <span class="pregnancy-calculator-stat-value" id="pc-sd-tri">—</span>
101
+ <span class="pregnancy-calculator-stat-key"
102
+ >{ui.labelTrimester}</span
103
+ >
104
+ <span class="pregnancy-calculator-stat-value" id="pc-sd-tri">—</span
105
+ >
74
106
  </div>
75
107
  </div>
76
108
  <div class="pregnancy-calculator-edd-box">
77
109
  <div class="pregnancy-calculator-edd-label">{ui.labelEDD}</div>
78
- <div class="pregnancy-calculator-edd-date" id="pc-sd-edd">{ui.eddPlaceholder}</div>
110
+ <div class="pregnancy-calculator-edd-date" id="pc-sd-edd">
111
+ {ui.eddPlaceholder}
112
+ </div>
79
113
  <div class="pregnancy-calculator-edd-note">{ui.eddNote}</div>
80
114
  </div>
81
- <button class="pregnancy-calculator-btn-cal" id="pc-sd-btn-cal" disabled>{ui.btnCalendar}</button>
115
+ <button class="pregnancy-calculator-btn-cal" id="pc-sd-btn-cal" disabled
116
+ >{ui.btnCalendar}</button
117
+ >
82
118
  </div>
83
119
  </div>
84
120
 
85
121
  <div class="pregnancy-calculator-center">
86
122
  <div class="pregnancy-calculator-mp-empty" id="pc-mp-empty">
87
123
  <div class="pregnancy-calculator-mp-empty-dot"></div>
88
- <div class="pregnancy-calculator-mp-empty-title">{ui.labelStartHere}</div>
124
+ <div class="pregnancy-calculator-mp-empty-title">
125
+ {ui.labelStartHere}
126
+ </div>
89
127
  <p class="pregnancy-calculator-mp-empty-body">{ui.labelStartBody}</p>
90
128
  </div>
91
129
 
92
- <div class="pregnancy-calculator-mp-egg" id="pc-mp-egg" style="display:none">
130
+ <div
131
+ class="pregnancy-calculator-mp-egg"
132
+ id="pc-mp-egg"
133
+ style="display:none"
134
+ >
93
135
  <div class="pregnancy-calculator-egg-dot" id="pc-egg-dot"></div>
94
136
  <div class="pregnancy-calculator-egg-title" id="pc-egg-title"></div>
95
137
  <p class="pregnancy-calculator-egg-body" id="pc-egg-body"></p>
96
138
  </div>
97
139
 
98
- <div class="pregnancy-calculator-mp-results" id="pc-mp-results" style="display:none">
140
+ <div
141
+ class="pregnancy-calculator-mp-results"
142
+ id="pc-mp-results"
143
+ style="display:none"
144
+ >
99
145
  <div class="pregnancy-calculator-mp-top-row">
100
- <span class="pregnancy-calculator-mp-badge" id="pc-mp-badge">Semana —</span>
146
+ <span class="pregnancy-calculator-mp-badge" id="pc-mp-badge"
147
+ >Semana —</span
148
+ >
101
149
  <div class="pregnancy-calculator-analogy-tabs">
102
- <button class="pregnancy-calculator-at-btn" data-cat="fruits">{ui.labelFruits}</button>
103
- <button class="pregnancy-calculator-at-btn" data-cat="geek">{ui.labelGeek}</button>
104
- <button class="pregnancy-calculator-at-btn" data-cat="sweets">{ui.labelSweets}</button>
150
+ <button class="pregnancy-calculator-at-btn" data-cat="fruits"
151
+ >{ui.labelFruits}</button
152
+ >
153
+ <button class="pregnancy-calculator-at-btn" data-cat="geek"
154
+ >{ui.labelGeek}</button
155
+ >
156
+ <button class="pregnancy-calculator-at-btn" data-cat="sweets"
157
+ >{ui.labelSweets}</button
158
+ >
105
159
  </div>
106
160
  </div>
107
161
  <div class="pregnancy-calculator-size-card">
108
- <span class="pregnancy-calculator-size-name" id="pc-mp-analogy">—</span>
109
- <span class="pregnancy-calculator-size-measure" id="pc-mp-size">—</span>
162
+ <span class="pregnancy-calculator-size-name" id="pc-mp-analogy"
163
+ >—</span
164
+ >
165
+ <span class="pregnancy-calculator-size-measure" id="pc-mp-size"
166
+ >—</span
167
+ >
110
168
  </div>
111
169
  <div class="pregnancy-calculator-info-stack">
112
170
  <div class="pregnancy-calculator-info-block">
@@ -114,17 +172,23 @@ const { ui } = Astro.props;
114
172
  <p class="pregnancy-calculator-info-text" id="pc-mp-bio"></p>
115
173
  </div>
116
174
  <div class="pregnancy-calculator-info-block">
117
- <div class="pregnancy-calculator-info-key" id="pc-mp-mom-key">{ui.labelMomKey}</div>
175
+ <div class="pregnancy-calculator-info-key" id="pc-mp-mom-key">
176
+ {ui.labelMomKey}
177
+ </div>
118
178
  <p class="pregnancy-calculator-info-text" id="pc-mp-mom"></p>
119
179
  </div>
120
180
  </div>
121
181
  <div class="pregnancy-calculator-wonder-line" id="pc-mp-wonder"></div>
122
182
  <div class="pregnancy-calculator-semaphore">
123
183
  <div class="pregnancy-calculator-sema pregnancy-calculator-sema-safe">
124
- <div class="pregnancy-calculator-sema-title">{ui.labelNormalMolestias}</div>
184
+ <div class="pregnancy-calculator-sema-title">
185
+ {ui.labelNormalMolestias}
186
+ </div>
125
187
  <ul class="pregnancy-calculator-sema-list" id="pc-mp-safe"></ul>
126
188
  </div>
127
- <div class="pregnancy-calculator-sema pregnancy-calculator-sema-alert">
189
+ <div
190
+ class="pregnancy-calculator-sema pregnancy-calculator-sema-alert"
191
+ >
128
192
  <div class="pregnancy-calculator-sema-title">{ui.labelAlert}</div>
129
193
  <ul class="pregnancy-calculator-sema-list" id="pc-mp-alert"></ul>
130
194
  </div>
@@ -138,66 +202,84 @@ const { ui } = Astro.props;
138
202
  <div class="pregnancy-calculator-tl-scroll" id="pc-tl-scroll"></div>
139
203
  </div>
140
204
  </div>
141
-
142
205
  </div>
143
206
  </div>
144
207
 
145
208
  <script>
146
- import { getState, setState, subscribe } from './store';
147
- import { getMilestone, timelineLabels } from './milestones';
148
- import type { PCState } from './store';
149
- import type { CalcResult } from './calculator';
209
+ import { getState, setState, subscribe } from "./store";
210
+ import { getMilestone, timelineLabels } from "./milestones";
211
+ import type { PCState } from "./store";
212
+ import type { CalcResult } from "./calculator";
150
213
 
151
- const root = document.getElementById('pregnancy-calculator-root') as HTMLElement;
214
+ const root = document.getElementById(
215
+ "pregnancy-calculator-root",
216
+ ) as HTMLElement;
152
217
  const ui = JSON.parse(root.dataset.ui as string) as Record<string, string>;
153
218
 
154
- const dpLabel = root.querySelector('#pc-dp-label') as HTMLElement;
155
- const dpDay = root.querySelector('#pc-dp-day') as HTMLSelectElement;
156
- const dpMonth = root.querySelector('#pc-dp-month') as HTMLSelectElement;
157
- const dpYear = root.querySelector('#pc-dp-year') as HTMLSelectElement;
158
- const csWrap = root.querySelector('#pc-cs-wrap') as HTMLElement;
159
- const csSlider = root.querySelector('#pc-cs-slider') as HTMLInputElement;
160
- const csValue = root.querySelector('#pc-cs-value') as HTMLElement;
161
- const sdWeeks = root.querySelector('#pc-sd-weeks') as HTMLElement;
162
- const sdTri = root.querySelector('#pc-sd-tri') as HTMLElement;
163
- const sdEdd = root.querySelector('#pc-sd-edd') as HTMLElement;
164
- const sdBtnCal = root.querySelector('#pc-sd-btn-cal') as HTMLButtonElement;
165
- const mpEmpty = root.querySelector('#pc-mp-empty') as HTMLElement;
166
- const mpEgg = root.querySelector('#pc-mp-egg') as HTMLElement;
167
- const eggDot = root.querySelector('#pc-egg-dot') as HTMLElement;
168
- const eggTitle = root.querySelector('#pc-egg-title') as HTMLElement;
169
- const eggBody = root.querySelector('#pc-egg-body') as HTMLElement;
170
- const mpResults = root.querySelector('#pc-mp-results') as HTMLElement;
171
- const mpBadge = root.querySelector('#pc-mp-badge') as HTMLElement;
172
- const mpAnalogy = root.querySelector('#pc-mp-analogy') as HTMLElement;
173
- const mpSize = root.querySelector('#pc-mp-size') as HTMLElement;
174
- const mpBio = root.querySelector('#pc-mp-bio') as HTMLElement;
175
- const mpMomKey = root.querySelector('#pc-mp-mom-key') as HTMLElement;
176
- const mpMom = root.querySelector('#pc-mp-mom') as HTMLElement;
177
- const mpWonder = root.querySelector('#pc-mp-wonder') as HTMLElement;
178
- const mpSafe = root.querySelector('#pc-mp-safe') as HTMLElement;
179
- const mpAlert = root.querySelector('#pc-mp-alert') as HTMLElement;
180
- const tlScroll = root.querySelector('#pc-tl-scroll') as HTMLElement;
181
-
182
- const MONTHS_ES = ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'];
183
- const fmtEdd = new Intl.DateTimeFormat('es-ES', { day: 'numeric', month: 'long', year: 'numeric' });
219
+ const dpLabel = root.querySelector("#pc-dp-label") as HTMLElement;
220
+ const dpDay = root.querySelector("#pc-dp-day") as HTMLSelectElement;
221
+ const dpMonth = root.querySelector("#pc-dp-month") as HTMLSelectElement;
222
+ const dpYear = root.querySelector("#pc-dp-year") as HTMLSelectElement;
223
+ const csWrap = root.querySelector("#pc-cs-wrap") as HTMLElement;
224
+ const csSlider = root.querySelector("#pc-cs-slider") as HTMLInputElement;
225
+ const csValue = root.querySelector("#pc-cs-value") as HTMLElement;
226
+ const sdWeeks = root.querySelector("#pc-sd-weeks") as HTMLElement;
227
+ const sdTri = root.querySelector("#pc-sd-tri") as HTMLElement;
228
+ const sdEdd = root.querySelector("#pc-sd-edd") as HTMLElement;
229
+ const sdBtnCal = root.querySelector("#pc-sd-btn-cal") as HTMLButtonElement;
230
+ const mpEmpty = root.querySelector("#pc-mp-empty") as HTMLElement;
231
+ const mpEgg = root.querySelector("#pc-mp-egg") as HTMLElement;
232
+ const eggDot = root.querySelector("#pc-egg-dot") as HTMLElement;
233
+ const eggTitle = root.querySelector("#pc-egg-title") as HTMLElement;
234
+ const eggBody = root.querySelector("#pc-egg-body") as HTMLElement;
235
+ const mpResults = root.querySelector("#pc-mp-results") as HTMLElement;
236
+ const mpBadge = root.querySelector("#pc-mp-badge") as HTMLElement;
237
+ const mpAnalogy = root.querySelector("#pc-mp-analogy") as HTMLElement;
238
+ const mpSize = root.querySelector("#pc-mp-size") as HTMLElement;
239
+ const mpBio = root.querySelector("#pc-mp-bio") as HTMLElement;
240
+ const mpMomKey = root.querySelector("#pc-mp-mom-key") as HTMLElement;
241
+ const mpMom = root.querySelector("#pc-mp-mom") as HTMLElement;
242
+ const mpWonder = root.querySelector("#pc-mp-wonder") as HTMLElement;
243
+ const mpSafe = root.querySelector("#pc-mp-safe") as HTMLElement;
244
+ const mpAlert = root.querySelector("#pc-mp-alert") as HTMLElement;
245
+ const tlScroll = root.querySelector("#pc-tl-scroll") as HTMLElement;
246
+
247
+ const MONTHS_ES = [
248
+ "Ene",
249
+ "Feb",
250
+ "Mar",
251
+ "Abr",
252
+ "May",
253
+ "Jun",
254
+ "Jul",
255
+ "Ago",
256
+ "Sep",
257
+ "Oct",
258
+ "Nov",
259
+ "Dic",
260
+ ];
261
+ const fmtEdd = new Intl.DateTimeFormat("es-ES", {
262
+ day: "numeric",
263
+ month: "long",
264
+ year: "numeric",
265
+ });
184
266
 
185
267
  function buildDateDropdowns(): void {
186
268
  for (let d = 1; d <= 31; d++) {
187
- const o = document.createElement('option');
269
+ const o = document.createElement("option");
188
270
  o.value = String(d);
189
- o.textContent = String(d).padStart(2, '0');
271
+ o.textContent = String(d).padStart(2, "0");
190
272
  dpDay.appendChild(o);
191
273
  }
192
274
  MONTHS_ES.forEach((m, i) => {
193
- const o = document.createElement('option');
275
+ const o = document.createElement("option");
194
276
  o.value = String(i + 1);
195
277
  o.textContent = m;
196
278
  dpMonth.appendChild(o);
197
279
  });
198
280
  const now = new Date();
199
281
  for (let y = now.getFullYear(); y >= now.getFullYear() - 1; y--) {
200
- const o = document.createElement('option');
282
+ const o = document.createElement("option");
201
283
  o.value = String(y);
202
284
  o.textContent = String(y);
203
285
  dpYear.appendChild(o);
@@ -207,25 +289,26 @@ const { ui } = Astro.props;
207
289
  function buildTimeline(): void {
208
290
  const frag = document.createDocumentFragment();
209
291
  for (let w = 4; w <= 40; w++) {
210
- const row = document.createElement('div');
211
- row.className = 'pregnancy-calculator-tl-row pregnancy-calculator-tl-row-future';
292
+ const row = document.createElement("div");
293
+ row.className =
294
+ "pregnancy-calculator-tl-row pregnancy-calculator-tl-row-future";
212
295
  row.dataset.week = String(w);
213
- const lineCol = document.createElement('div');
214
- lineCol.className = 'pregnancy-calculator-tl-line-col';
215
- const dot = document.createElement('div');
216
- dot.className = 'pregnancy-calculator-tl-dot';
217
- const line = document.createElement('div');
218
- line.className = 'pregnancy-calculator-tl-line';
296
+ const lineCol = document.createElement("div");
297
+ lineCol.className = "pregnancy-calculator-tl-line-col";
298
+ const dot = document.createElement("div");
299
+ dot.className = "pregnancy-calculator-tl-dot";
300
+ const line = document.createElement("div");
301
+ line.className = "pregnancy-calculator-tl-line";
219
302
  lineCol.appendChild(dot);
220
303
  lineCol.appendChild(line);
221
- const info = document.createElement('div');
222
- info.className = 'pregnancy-calculator-tl-info';
223
- const num = document.createElement('span');
224
- num.className = 'pregnancy-calculator-tl-num';
225
- num.textContent = `${ui['labelSem'] ?? 'Sem'} ${w}`;
226
- const label = document.createElement('span');
227
- label.className = 'pregnancy-calculator-tl-label';
228
- label.textContent = timelineLabels[w] ?? '';
304
+ const info = document.createElement("div");
305
+ info.className = "pregnancy-calculator-tl-info";
306
+ const num = document.createElement("span");
307
+ num.className = "pregnancy-calculator-tl-num";
308
+ num.textContent = `${ui["labelSem"] ?? "Sem"} ${w}`;
309
+ const label = document.createElement("span");
310
+ label.className = "pregnancy-calculator-tl-label";
311
+ label.textContent = timelineLabels[w] ?? "";
229
312
  info.appendChild(num);
230
313
  info.appendChild(label);
231
314
  row.appendChild(lineCol);
@@ -236,9 +319,9 @@ const { ui } = Astro.props;
236
319
  }
237
320
 
238
321
  function getDateString(d: string, m: string, y: string): string {
239
- if (!d || !m || !y) return '';
240
- const mm = m.padStart(2, '0');
241
- const dd = d.padStart(2, '0');
322
+ if (!d || !m || !y) return "";
323
+ const mm = m.padStart(2, "0");
324
+ const dd = d.padStart(2, "0");
242
325
  return `${y}-${mm}-${dd}`;
243
326
  }
244
327
 
@@ -249,84 +332,94 @@ const { ui } = Astro.props;
249
332
  updateMethodUI(s.method);
250
333
  updatePartnerUI(s.partner);
251
334
  updateAnalogyTabs(s.analogyCat);
252
- csWrap.style.display = s.method === 'fur' ? '' : 'none';
335
+ csWrap.style.display = s.method === "fur" ? "" : "none";
253
336
  if (s.date) {
254
- const parts = s.date.split('-');
337
+ const parts = s.date.split("-");
255
338
  if (parts.length === 3) {
256
- dpYear.value = parts[0] ?? '';
257
- dpMonth.value = String(parseInt(parts[1] ?? '0', 10));
258
- dpDay.value = String(parseInt(parts[2] ?? '0', 10));
339
+ dpYear.value = parts[0] ?? "";
340
+ dpMonth.value = String(parseInt(parts[1] ?? "0", 10));
341
+ dpDay.value = String(parseInt(parts[2] ?? "0", 10));
259
342
  }
260
343
  }
261
344
  }
262
345
 
263
346
  function updateMethodUI(method: string): void {
264
- root.querySelectorAll('.pregnancy-calculator-method-btn').forEach((btn) => {
347
+ root.querySelectorAll(".pregnancy-calculator-method-btn").forEach((btn) => {
265
348
  const el = btn as HTMLElement;
266
- el.classList.toggle('pregnancy-calculator-method-btn-active', el.dataset.method === method);
349
+ el.classList.toggle(
350
+ "pregnancy-calculator-method-btn-active",
351
+ el.dataset.method === method,
352
+ );
267
353
  });
268
- dpLabel.textContent = (method === 'fur' ? ui['labelFUR'] : ui['labelConception']) ?? null;
269
- csWrap.style.display = method === 'fur' ? '' : 'none';
354
+ dpLabel.textContent =
355
+ (method === "fur" ? ui["labelFUR"] : ui["labelConception"]) ?? null;
356
+ csWrap.style.display = method === "fur" ? "" : "none";
270
357
  }
271
358
 
272
359
  function updatePartnerUI(partner: boolean): void {
273
- const track = root.querySelector('.pregnancy-calculator-toggle-track') as HTMLElement;
274
- track.classList.toggle('pregnancy-calculator-toggle-track-on', partner);
275
- mpMomKey.textContent = (partner ? ui['labelPartnerKey'] : ui['labelMomKey']) ?? null;
360
+ const track = root.querySelector(
361
+ ".pregnancy-calculator-toggle-track",
362
+ ) as HTMLElement;
363
+ track.classList.toggle("pregnancy-calculator-toggle-track-on", partner);
364
+ mpMomKey.textContent =
365
+ (partner ? ui["labelPartnerKey"] : ui["labelMomKey"]) ?? null;
276
366
  }
277
367
 
278
368
  function updateAnalogyTabs(cat: string): void {
279
- root.querySelectorAll('.pregnancy-calculator-at-btn').forEach((btn) => {
369
+ root.querySelectorAll(".pregnancy-calculator-at-btn").forEach((btn) => {
280
370
  const el = btn as HTMLElement;
281
- el.classList.toggle('pregnancy-calculator-at-btn-active', el.dataset.cat === cat);
371
+ el.classList.toggle(
372
+ "pregnancy-calculator-at-btn-active",
373
+ el.dataset.cat === cat,
374
+ );
282
375
  });
283
376
  }
284
377
 
285
378
  function applyTrimester(tri: 1 | 2 | 3): void {
286
379
  root.classList.remove(
287
- 'pregnancy-calculator-t1',
288
- 'pregnancy-calculator-t2',
289
- 'pregnancy-calculator-t3'
380
+ "pregnancy-calculator-t1",
381
+ "pregnancy-calculator-t2",
382
+ "pregnancy-calculator-t3",
290
383
  );
291
384
  root.classList.add(`pregnancy-calculator-t${tri}`);
292
385
  }
293
386
 
294
- function showEasterEgg(reason: 'future' | 'too-old'): void {
387
+ function showEasterEgg(reason: "future" | "too-old"): void {
295
388
  eggDot.dataset.reason = reason;
296
- if (reason === 'future') {
297
- eggTitle.textContent = ui['eggFutureTitle'] ?? '';
298
- eggBody.textContent = ui['eggFutureBody'] ?? '';
389
+ if (reason === "future") {
390
+ eggTitle.textContent = ui["eggFutureTitle"] ?? "";
391
+ eggBody.textContent = ui["eggFutureBody"] ?? "";
299
392
  } else {
300
- eggTitle.textContent = ui['eggTooOldTitle'] ?? '';
301
- eggBody.textContent = ui['eggTooOldBody'] ?? '';
393
+ eggTitle.textContent = ui["eggTooOldTitle"] ?? "";
394
+ eggBody.textContent = ui["eggTooOldBody"] ?? "";
302
395
  }
303
- mpEmpty.style.display = 'none';
304
- mpResults.style.display = 'none';
305
- mpEgg.style.display = '';
396
+ mpEmpty.style.display = "none";
397
+ mpResults.style.display = "none";
398
+ mpEgg.style.display = "";
306
399
  }
307
400
 
308
401
  function renderStats(result: CalcResult): void {
309
402
  if (!result.valid) {
310
- sdWeeks.textContent = '';
311
- sdTri.textContent = '';
312
- sdEdd.textContent = ui['eddPlaceholder'] ?? null;
403
+ sdWeeks.textContent = "";
404
+ sdTri.textContent = "";
405
+ sdEdd.textContent = ui["eddPlaceholder"] ?? null;
313
406
  sdBtnCal.disabled = true;
314
407
  return;
315
408
  }
316
- const wFmt = (ui['weeksFormat'] ?? '{w}s {d}d')
317
- .replace('{w}', String(result.weeks))
318
- .replace('{d}', String(result.days));
409
+ const wFmt = (ui["weeksFormat"] ?? "{w}s {d}d")
410
+ .replace("{w}", String(result.weeks))
411
+ .replace("{d}", String(result.days));
319
412
  sdWeeks.textContent = wFmt;
320
- sdTri.textContent = `${result.trimester}${ui['trimesterSuffix'] ?? ''}`;
413
+ sdTri.textContent = `${result.trimester}${ui["trimesterSuffix"] ?? ""}`;
321
414
  sdEdd.textContent = fmtEdd.format(result.edd);
322
415
  sdBtnCal.disabled = false;
323
416
  applyTrimester(result.trimester);
324
417
  }
325
418
 
326
419
  function buildList(ul: HTMLElement, items: string[]): void {
327
- ul.innerHTML = '';
420
+ ul.innerHTML = "";
328
421
  items.forEach((item) => {
329
- const li = document.createElement('li');
422
+ const li = document.createElement("li");
330
423
  li.textContent = item;
331
424
  ul.appendChild(li);
332
425
  });
@@ -334,8 +427,9 @@ const { ui } = Astro.props;
334
427
 
335
428
  function renderMilestone(weeks: number, cat: string, partner: boolean): void {
336
429
  const ms = getMilestone(weeks);
337
- mpBadge.textContent = `${ui['labelWeekBadge'] ?? 'Semana'} ${weeks}`;
338
- mpAnalogy.textContent = ms.analogies[cat as 'fruits' | 'geek' | 'sweets'] ?? ms.analogies.fruits;
430
+ mpBadge.textContent = `${ui["labelWeekBadge"] ?? "Semana"} ${weeks}`;
431
+ mpAnalogy.textContent =
432
+ ms.analogies[cat as "fruits" | "geek" | "sweets"] ?? ms.analogies.fruits;
339
433
  mpSize.textContent = ms.size;
340
434
  mpBio.textContent = ms.biolook;
341
435
  mpMom.textContent = partner ? ms.partner : ms.mom;
@@ -345,25 +439,27 @@ const { ui } = Astro.props;
345
439
  }
346
440
 
347
441
  function renderTimeline(weeks: number): void {
348
- tlScroll.querySelectorAll('.pregnancy-calculator-tl-row').forEach((row) => {
442
+ tlScroll.querySelectorAll(".pregnancy-calculator-tl-row").forEach((row) => {
349
443
  const el = row as HTMLElement;
350
- const w = parseInt(el.dataset.week ?? '0', 10);
444
+ const w = parseInt(el.dataset.week ?? "0", 10);
351
445
  el.classList.remove(
352
- 'pregnancy-calculator-tl-row-past',
353
- 'pregnancy-calculator-tl-row-current',
354
- 'pregnancy-calculator-tl-row-future'
446
+ "pregnancy-calculator-tl-row-past",
447
+ "pregnancy-calculator-tl-row-current",
448
+ "pregnancy-calculator-tl-row-future",
355
449
  );
356
450
  if (w < weeks) {
357
- el.classList.add('pregnancy-calculator-tl-row-past');
451
+ el.classList.add("pregnancy-calculator-tl-row-past");
358
452
  } else if (w === weeks) {
359
- el.classList.add('pregnancy-calculator-tl-row-current');
453
+ el.classList.add("pregnancy-calculator-tl-row-current");
360
454
  } else {
361
- el.classList.add('pregnancy-calculator-tl-row-future');
455
+ el.classList.add("pregnancy-calculator-tl-row-future");
362
456
  }
363
457
  });
364
- const currentRow = tlScroll.querySelector('.pregnancy-calculator-tl-row-current') as HTMLElement | null;
458
+ const currentRow = tlScroll.querySelector(
459
+ ".pregnancy-calculator-tl-row-current",
460
+ ) as HTMLElement | null;
365
461
  if (currentRow) {
366
- currentRow.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
462
+ currentRow.scrollIntoView({ block: "nearest", behavior: "smooth" });
367
463
  }
368
464
  }
369
465
 
@@ -372,9 +468,9 @@ const { ui } = Astro.props;
372
468
  updatePartnerUI(s.partner);
373
469
  updateAnalogyTabs(s.analogyCat);
374
470
  if (!s.result) {
375
- mpEmpty.style.display = '';
376
- mpEgg.style.display = 'none';
377
- mpResults.style.display = 'none';
471
+ mpEmpty.style.display = "";
472
+ mpEgg.style.display = "none";
473
+ mpResults.style.display = "none";
378
474
  return;
379
475
  }
380
476
  if (!s.result.valid && s.result.outOfRange) {
@@ -383,19 +479,19 @@ const { ui } = Astro.props;
383
479
  return;
384
480
  }
385
481
  if (!s.result.valid) {
386
- mpEmpty.style.display = '';
387
- mpEgg.style.display = 'none';
388
- mpResults.style.display = 'none';
482
+ mpEmpty.style.display = "";
483
+ mpEgg.style.display = "none";
484
+ mpResults.style.display = "none";
389
485
  renderStats(s.result);
390
486
  return;
391
487
  }
392
488
  renderStats(s.result);
393
489
  renderMilestone(s.result.weeks, s.analogyCat, s.partner);
394
490
  renderTimeline(s.result.weeks);
395
- mpEmpty.style.display = 'none';
396
- mpEgg.style.display = 'none';
397
- mpResults.style.display = '';
398
- mpResults.classList.add('pregnancy-calculator-mp-enter');
491
+ mpEmpty.style.display = "none";
492
+ mpEgg.style.display = "none";
493
+ mpResults.style.display = "";
494
+ mpResults.classList.add("pregnancy-calculator-mp-enter");
399
495
  }
400
496
 
401
497
  function onDateChange(): void {
@@ -404,28 +500,28 @@ const { ui } = Astro.props;
404
500
  }
405
501
 
406
502
  function downloadICS(edd: Date): void {
407
- const pad = (n: number) => String(n).padStart(2, '0');
503
+ const pad = (n: number) => String(n).padStart(2, "0");
408
504
  const y = edd.getFullYear();
409
505
  const m = pad(edd.getMonth() + 1);
410
506
  const d = pad(edd.getDate());
411
507
  const stamp = `${y}${m}${d}T000000Z`;
412
508
  const lines = [
413
- 'BEGIN:VCALENDAR',
414
- 'VERSION:2.0',
415
- 'BEGIN:VEVENT',
509
+ "BEGIN:VCALENDAR",
510
+ "VERSION:2.0",
511
+ "BEGIN:VEVENT",
416
512
  `DTSTART;VALUE=DATE:${y}${m}${d}`,
417
513
  `DTEND;VALUE=DATE:${y}${m}${d}`,
418
514
  `DTSTAMP:${stamp}`,
419
- 'SUMMARY:Fecha Probable de Parto',
420
- 'DESCRIPTION:Fecha estimada de parto calculada por jjlmoya',
421
- 'END:VEVENT',
422
- 'END:VCALENDAR',
515
+ "SUMMARY:Fecha Probable de Parto",
516
+ "DESCRIPTION:Fecha estimada de parto calculada por jjlmoya",
517
+ "END:VEVENT",
518
+ "END:VCALENDAR",
423
519
  ];
424
- const blob = new Blob([lines.join('\r\n')], { type: 'text/calendar' });
520
+ const blob = new Blob([lines.join("\r\n")], { type: "text/calendar" });
425
521
  const url = URL.createObjectURL(blob);
426
- const a = document.createElement('a');
522
+ const a = document.createElement("a");
427
523
  a.href = url;
428
- a.download = 'fecha-parto.ics';
524
+ a.download = "fecha-parto.ics";
429
525
  a.click();
430
526
  URL.revokeObjectURL(url);
431
527
  }
@@ -437,38 +533,1084 @@ const { ui } = Astro.props;
437
533
  const initialState = getState();
438
534
  if (initialState.result) onStateChange(initialState);
439
535
 
440
- dpDay.addEventListener('change', onDateChange);
441
- dpMonth.addEventListener('change', onDateChange);
442
- dpYear.addEventListener('change', onDateChange);
536
+ dpDay.addEventListener("change", onDateChange);
537
+ dpMonth.addEventListener("change", onDateChange);
538
+ dpYear.addEventListener("change", onDateChange);
443
539
 
444
- csSlider.addEventListener('input', () => {
540
+ csSlider.addEventListener("input", () => {
445
541
  const v = Number(csSlider.value);
446
542
  csValue.textContent = String(v);
447
543
  setState({ cycle: v });
448
544
  });
449
545
 
450
- root.querySelectorAll('.pregnancy-calculator-method-btn').forEach((btn) => {
451
- btn.addEventListener('click', () => {
452
- const method = (btn as HTMLElement).dataset.method as 'fur' | 'conception';
546
+ root.querySelectorAll(".pregnancy-calculator-method-btn").forEach((btn) => {
547
+ btn.addEventListener("click", () => {
548
+ const method = (btn as HTMLElement).dataset.method as
549
+ | "fur"
550
+ | "conception";
453
551
  setState({ method });
454
552
  });
455
553
  });
456
554
 
457
- root.querySelector('.pregnancy-calculator-partner-wrap')?.addEventListener('click', () => {
458
- setState({ partner: !getState().partner });
459
- });
555
+ root
556
+ .querySelector(".pregnancy-calculator-partner-wrap")
557
+ ?.addEventListener("click", () => {
558
+ setState({ partner: !getState().partner });
559
+ });
460
560
 
461
- root.querySelectorAll('.pregnancy-calculator-at-btn').forEach((btn) => {
462
- btn.addEventListener('click', () => {
463
- const cat = (btn as HTMLElement).dataset.cat as 'fruits' | 'geek' | 'sweets';
561
+ root.querySelectorAll(".pregnancy-calculator-at-btn").forEach((btn) => {
562
+ btn.addEventListener("click", () => {
563
+ const cat = (btn as HTMLElement).dataset.cat as
564
+ | "fruits"
565
+ | "geek"
566
+ | "sweets";
464
567
  setState({ analogyCat: cat });
465
568
  });
466
569
  });
467
570
 
468
- sdBtnCal.addEventListener('click', () => {
571
+ sdBtnCal.addEventListener("click", () => {
469
572
  const s = getState();
470
573
  if (s.result?.valid) downloadICS(s.result.edd);
471
574
  });
472
575
 
473
576
  subscribe(onStateChange);
474
577
  </script>
578
+
579
+ <style>
580
+ .pregnancy-calculator {
581
+ --pc-tri-primary: #86efac;
582
+ --pc-tri-accent: #22c55e;
583
+ --pc-tri-glow: rgba(134, 239, 172, 0.18);
584
+ --pc-tri-text: #14532d;
585
+ --pc-tri-bg: #f0fdf4;
586
+ --pc-tri-badge: #dcfce7;
587
+ --pc-bg: #fff;
588
+ --pc-bg-muted: #f8fafc;
589
+ --pc-bg-dark: #1a2332;
590
+ --pc-text: #1e293b;
591
+ --pc-text-muted: #475569;
592
+ --pc-text-dim: #94a3b8;
593
+ --pc-border: #edf2f7;
594
+ --pc-border-inner: rgba(0, 0, 0, 0.04);
595
+ --pc-shadow: rgba(0, 0, 0, 0.07);
596
+ --pc-safe-bg: #f0fdf4;
597
+ --pc-safe-title: #16a34a;
598
+ --pc-alert-bg: #fff7ed;
599
+ --pc-alert-title: #ea580c;
600
+
601
+ position: relative;
602
+ width: 100%;
603
+ color: var(--pc-text);
604
+ background: var(--pc-bg);
605
+ border-radius: 32px;
606
+ overflow: hidden;
607
+ box-shadow:
608
+ 0 0 0 1px rgba(0, 0, 0, 0.05),
609
+ 0 8px 32px rgba(0, 0, 0, 0.07),
610
+ 0 32px 64px rgba(0, 0, 0, 0.04);
611
+ transition: box-shadow 0.5s;
612
+ }
613
+
614
+ .pregnancy-calculator::before {
615
+ content: "";
616
+ position: absolute;
617
+ inset: 0 0 auto;
618
+ height: 3px;
619
+ background: linear-gradient(
620
+ 90deg,
621
+ var(--pc-tri-primary),
622
+ var(--pc-tri-accent)
623
+ );
624
+ transition: background 0.6s ease;
625
+ z-index: 1;
626
+ }
627
+
628
+ .pregnancy-calculator.pregnancy-calculator-t1 {
629
+ --pc-tri-primary: #86efac;
630
+ --pc-tri-accent: #22c55e;
631
+ --pc-tri-glow: rgba(134, 239, 172, 0.18);
632
+ --pc-tri-text: #14532d;
633
+ --pc-tri-bg: #f0fdf4;
634
+ --pc-tri-badge: #dcfce7;
635
+ }
636
+
637
+ .pregnancy-calculator.pregnancy-calculator-t2 {
638
+ --pc-tri-primary: #fcd34d;
639
+ --pc-tri-accent: #f59e0b;
640
+ --pc-tri-glow: rgba(252, 211, 77, 0.2);
641
+ --pc-tri-text: #78350f;
642
+ --pc-tri-bg: #fffbeb;
643
+ --pc-tri-badge: #fef3c7;
644
+ }
645
+
646
+ .pregnancy-calculator.pregnancy-calculator-t3 {
647
+ --pc-tri-primary: #d8b4fe;
648
+ --pc-tri-accent: #a855f7;
649
+ --pc-tri-glow: rgba(216, 180, 254, 0.2);
650
+ --pc-tri-text: #4c1d95;
651
+ --pc-tri-bg: #faf5ff;
652
+ --pc-tri-badge: #ede9fe;
653
+ }
654
+
655
+ :global(.theme-dark) .pregnancy-calculator {
656
+ --pc-bg: #111827;
657
+ --pc-bg-muted: #0f1923;
658
+ --pc-bg-dark: #0f1923;
659
+ --pc-text: #f1f5f9;
660
+ --pc-text-muted: #94a3b8;
661
+ --pc-text-dim: #64748b;
662
+ --pc-border: rgba(255, 255, 255, 0.04);
663
+ --pc-border-inner: rgba(255, 255, 255, 0.04);
664
+ --pc-shadow: rgba(0, 0, 0, 0.4);
665
+ --pc-safe-bg: rgba(16, 185, 129, 0.08);
666
+ --pc-safe-title: #16a34a;
667
+ --pc-alert-bg: rgba(249, 115, 22, 0.08);
668
+ --pc-alert-title: #ea580c;
669
+
670
+ background: #111827;
671
+ box-shadow:
672
+ 0 0 0 1px rgba(255, 255, 255, 0.06),
673
+ 0 8px 32px rgba(0, 0, 0, 0.4);
674
+ }
675
+
676
+ .pregnancy-calculator-header {
677
+ display: flex;
678
+ align-items: center;
679
+ justify-content: space-between;
680
+ padding: 24px 32px 20px;
681
+ border-bottom: 1px solid var(--pc-border);
682
+ gap: 16px;
683
+ flex-wrap: wrap;
684
+ }
685
+
686
+ .pregnancy-calculator-method-group {
687
+ display: flex;
688
+ gap: 0;
689
+ background: #f1f5f9;
690
+ padding: 4px;
691
+ border-radius: 16px;
692
+ }
693
+
694
+ :global(.theme-dark) .pregnancy-calculator-method-group {
695
+ background: rgba(255, 255, 255, 0.06);
696
+ }
697
+
698
+ .pregnancy-calculator-method-btn {
699
+ padding: 9px 20px;
700
+ border-radius: 12px;
701
+ border: none;
702
+ background: transparent;
703
+ color: var(--pc-text-muted);
704
+ font-size: 0.78rem;
705
+ font-weight: 800;
706
+ cursor: pointer;
707
+ transition:
708
+ background 0.2s,
709
+ color 0.2s,
710
+ box-shadow 0.2s;
711
+ text-transform: uppercase;
712
+ letter-spacing: 0.04em;
713
+ white-space: nowrap;
714
+ }
715
+
716
+ .pregnancy-calculator-method-btn-active {
717
+ background: var(--pc-bg);
718
+ color: var(--pc-tri-accent);
719
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.07);
720
+ }
721
+
722
+ .pregnancy-calculator-partner-wrap {
723
+ display: flex;
724
+ align-items: center;
725
+ gap: 0.5rem;
726
+ cursor: pointer;
727
+ user-select: none;
728
+ }
729
+
730
+ .pregnancy-calculator-partner-label {
731
+ font-size: 0.8125rem;
732
+ color: var(--pc-text-muted);
733
+ }
734
+
735
+ .pregnancy-calculator-toggle-track {
736
+ width: 2.5rem;
737
+ height: 1.375rem;
738
+ border-radius: 0.6875rem;
739
+ background: var(--pc-border);
740
+ position: relative;
741
+ transition: background 0.2s;
742
+ border: 1px solid var(--pc-border-inner);
743
+ }
744
+
745
+ .pregnancy-calculator-toggle-track-on {
746
+ background: var(--pc-tri-accent);
747
+ }
748
+
749
+ .pregnancy-calculator-toggle-thumb {
750
+ position: absolute;
751
+ top: 2px;
752
+ left: 2px;
753
+ width: 1rem;
754
+ height: 1rem;
755
+ border-radius: 50%;
756
+ background: var(--pc-bg);
757
+ box-shadow: 0 1px 3px var(--pc-shadow);
758
+ transition: transform 0.2s;
759
+ }
760
+
761
+ .pregnancy-calculator-toggle-track-on .pregnancy-calculator-toggle-thumb {
762
+ transform: translateX(1.125rem);
763
+ }
764
+
765
+ .pregnancy-calculator-main {
766
+ display: grid;
767
+ grid-template-columns: 300px 1fr 220px;
768
+ min-height: 32rem;
769
+ }
770
+
771
+ .pregnancy-calculator-left {
772
+ padding: 28px 24px 36px;
773
+ border-right: 1px solid var(--pc-border);
774
+ display: flex;
775
+ flex-direction: column;
776
+ gap: 20px;
777
+ background: #f8fafc;
778
+ }
779
+
780
+ :global(.theme-dark) .pregnancy-calculator-left {
781
+ background: #0f1923;
782
+ border-right-color: rgba(255, 255, 255, 0.04);
783
+ }
784
+
785
+ .pregnancy-calculator-center {
786
+ padding: 28px 28px 36px;
787
+ border-right: 1px solid var(--pc-border);
788
+ overflow-y: auto;
789
+ background: #fff;
790
+ }
791
+
792
+ :global(.theme-dark) .pregnancy-calculator-center {
793
+ background: #111827;
794
+ }
795
+
796
+ .pregnancy-calculator-right {
797
+ position: relative;
798
+ overflow: hidden;
799
+ }
800
+
801
+ .pregnancy-calculator-tl-inner {
802
+ position: absolute;
803
+ inset: 0;
804
+ display: flex;
805
+ flex-direction: column;
806
+ background: var(--pc-bg-muted);
807
+ overflow: hidden;
808
+ }
809
+
810
+ :global(.theme-dark) .pregnancy-calculator-tl-inner {
811
+ background: #0f1923;
812
+ }
813
+
814
+ .pregnancy-calculator-dp-wrap {
815
+ display: flex;
816
+ flex-direction: column;
817
+ gap: 0.5rem;
818
+ }
819
+
820
+ .pregnancy-calculator-dp-label {
821
+ font-size: 0.8125rem;
822
+ font-weight: 600;
823
+ color: var(--pc-text-muted);
824
+ text-transform: uppercase;
825
+ letter-spacing: 0.04em;
826
+ }
827
+
828
+ .pregnancy-calculator-dp-selects {
829
+ display: flex;
830
+ align-items: center;
831
+ background: #fff;
832
+ border-radius: 18px;
833
+ padding: 6px 10px;
834
+ gap: 4px;
835
+ box-shadow:
836
+ 0 2px 12px rgba(0, 0, 0, 0.06),
837
+ 0 0 0 1px rgba(0, 0, 0, 0.04);
838
+ transition: box-shadow 0.2s;
839
+ }
840
+
841
+ .pregnancy-calculator-dp-selects:focus-within {
842
+ box-shadow:
843
+ 0 4px 20px var(--pc-tri-glow),
844
+ 0 0 0 2px var(--pc-tri-primary);
845
+ }
846
+
847
+ :global(.theme-dark) .pregnancy-calculator-dp-selects {
848
+ background: #1a2332;
849
+ box-shadow:
850
+ 0 2px 12px rgba(0, 0, 0, 0.2),
851
+ 0 0 0 1px rgba(255, 255, 255, 0.06);
852
+ }
853
+
854
+ .pregnancy-calculator-dp-select {
855
+ flex: 1;
856
+ padding: 8px 4px;
857
+ border: none;
858
+ background: transparent;
859
+ color: var(--pc-text);
860
+ font-size: 0.95rem;
861
+ font-weight: 700;
862
+ cursor: pointer;
863
+ appearance: none;
864
+ outline: none;
865
+ text-align: center;
866
+ min-width: 0;
867
+ }
868
+
869
+ .pregnancy-calculator-dp-sep {
870
+ color: #cbd5e1;
871
+ font-size: 1rem;
872
+ font-weight: 300;
873
+ flex-shrink: 0;
874
+ padding: 0 2px;
875
+ }
876
+
877
+ .pregnancy-calculator-cs-wrap {
878
+ background: #fff;
879
+ border-radius: 18px;
880
+ padding: 20px;
881
+ box-shadow:
882
+ 0 2px 12px rgba(0, 0, 0, 0.06),
883
+ 0 0 0 1px rgba(0, 0, 0, 0.04);
884
+ display: flex;
885
+ flex-direction: column;
886
+ gap: 0;
887
+ transition: opacity 0.3s;
888
+ }
889
+
890
+ :global(.theme-dark) .pregnancy-calculator-cs-wrap {
891
+ background: #1a2332;
892
+ box-shadow:
893
+ 0 2px 12px rgba(0, 0, 0, 0.2),
894
+ 0 0 0 1px rgba(255, 255, 255, 0.06);
895
+ }
896
+
897
+ .pregnancy-calculator-cs-header {
898
+ display: flex;
899
+ align-items: baseline;
900
+ justify-content: space-between;
901
+ margin-bottom: 16px;
902
+ }
903
+
904
+ .pregnancy-calculator-cs-label {
905
+ font-size: 0.7rem;
906
+ font-weight: 800;
907
+ color: var(--pc-text-muted);
908
+ text-transform: uppercase;
909
+ letter-spacing: 0.14em;
910
+ }
911
+
912
+ .pregnancy-calculator-cs-value-wrap {
913
+ display: flex;
914
+ align-items: baseline;
915
+ gap: 3px;
916
+ }
917
+
918
+ #pc-cs-value {
919
+ font-size: 2rem;
920
+ font-weight: 900;
921
+ letter-spacing: -0.04em;
922
+ color: var(--pc-tri-accent);
923
+ transition: color 0.5s;
924
+ }
925
+
926
+ .pregnancy-calculator-cs-unit {
927
+ font-size: 0.8rem;
928
+ font-weight: 600;
929
+ color: var(--pc-text-dim);
930
+ }
931
+
932
+ .pregnancy-calculator-cs-slider {
933
+ width: 100%;
934
+ height: 4px;
935
+ border-radius: 2px;
936
+ background: linear-gradient(90deg, var(--pc-tri-primary) 0%, #e2e8f0 0%);
937
+ appearance: none;
938
+ cursor: pointer;
939
+ outline: none;
940
+ transition: background 0.4s;
941
+ }
942
+
943
+ .pregnancy-calculator-cs-slider::-webkit-slider-thumb {
944
+ appearance: none;
945
+ width: 20px;
946
+ height: 20px;
947
+ border-radius: 50%;
948
+ background: #fff;
949
+ border: 3px solid var(--pc-tri-accent);
950
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
951
+ cursor: pointer;
952
+ transition:
953
+ transform 0.2s,
954
+ border-color 0.5s;
955
+ }
956
+
957
+ .pregnancy-calculator-cs-slider::-webkit-slider-thumb:hover {
958
+ transform: scale(1.2);
959
+ }
960
+
961
+ .pregnancy-calculator-cs-extremes {
962
+ display: flex;
963
+ justify-content: space-between;
964
+ margin-top: 8px;
965
+ font-size: 0.65rem;
966
+ font-weight: 700;
967
+ color: #cbd5e1;
968
+ }
969
+
970
+ .pregnancy-calculator-sd-wrap {
971
+ display: flex;
972
+ flex-direction: column;
973
+ gap: 0.875rem;
974
+ }
975
+
976
+ .pregnancy-calculator-stats-row {
977
+ display: flex;
978
+ gap: 0.625rem;
979
+ }
980
+
981
+ .pregnancy-calculator-stat-chip {
982
+ flex: 1;
983
+ background: #f8fafc;
984
+ border-radius: 16px;
985
+ padding: 16px 18px;
986
+ display: flex;
987
+ flex-direction: column;
988
+ gap: 4px;
989
+ }
990
+
991
+ :global(.theme-dark) .pregnancy-calculator-stat-chip {
992
+ background: #1e2936;
993
+ }
994
+
995
+ .pregnancy-calculator-stat-key {
996
+ font-size: 0.65rem;
997
+ font-weight: 800;
998
+ text-transform: uppercase;
999
+ letter-spacing: 0.12em;
1000
+ color: #94a3b8;
1001
+ }
1002
+
1003
+ .pregnancy-calculator-stat-value {
1004
+ font-size: 1.5rem;
1005
+ font-weight: 900;
1006
+ color: var(--pc-text);
1007
+ line-height: 1;
1008
+ letter-spacing: -0.02em;
1009
+ transition: color 0.5s;
1010
+ }
1011
+
1012
+ .pregnancy-calculator-accent {
1013
+ color: var(--pc-tri-accent);
1014
+ }
1015
+
1016
+ .pregnancy-calculator-edd-box {
1017
+ border-radius: 18px;
1018
+ padding: 20px;
1019
+ background: var(--pc-tri-bg);
1020
+ text-align: center;
1021
+ display: flex;
1022
+ flex-direction: column;
1023
+ gap: 0;
1024
+ transition: background 0.5s;
1025
+ }
1026
+
1027
+ :global(.theme-dark) .pregnancy-calculator-edd-box {
1028
+ background: rgba(255, 255, 255, 0.04);
1029
+ }
1030
+
1031
+ .pregnancy-calculator-edd-label {
1032
+ font-size: 0.65rem;
1033
+ font-weight: 800;
1034
+ text-transform: uppercase;
1035
+ letter-spacing: 0.14em;
1036
+ color: #94a3b8;
1037
+ margin-bottom: 6px;
1038
+ }
1039
+
1040
+ .pregnancy-calculator-edd-date {
1041
+ font-size: 1.15rem;
1042
+ font-weight: 900;
1043
+ color: var(--pc-tri-text);
1044
+ letter-spacing: -0.02em;
1045
+ transition: color 0.5s;
1046
+ }
1047
+
1048
+ :global(.theme-dark) .pregnancy-calculator-edd-date {
1049
+ color: var(--pc-tri-primary);
1050
+ }
1051
+
1052
+ .pregnancy-calculator-edd-note {
1053
+ font-size: 0.72rem;
1054
+ color: #94a3b8;
1055
+ margin-top: 5px;
1056
+ font-style: italic;
1057
+ }
1058
+
1059
+ .pregnancy-calculator-btn-cal {
1060
+ width: 100%;
1061
+ padding: 15px;
1062
+ border-radius: 16px;
1063
+ border: none;
1064
+ background: var(--pc-tri-accent);
1065
+ color: #fff;
1066
+ font-size: 0.82rem;
1067
+ font-weight: 800;
1068
+ cursor: pointer;
1069
+ letter-spacing: 0.06em;
1070
+ text-transform: uppercase;
1071
+ transition: all 0.25s;
1072
+ box-shadow: 0 4px 16px var(--pc-tri-glow);
1073
+ }
1074
+
1075
+ .pregnancy-calculator-btn-cal:hover:not(:disabled) {
1076
+ transform: translateY(-2px);
1077
+ box-shadow: 0 8px 24px var(--pc-tri-glow);
1078
+ }
1079
+
1080
+ .pregnancy-calculator-btn-cal:disabled {
1081
+ background: #e2e8f0;
1082
+ color: #94a3b8;
1083
+ box-shadow: none;
1084
+ cursor: default;
1085
+ }
1086
+
1087
+ :global(.theme-dark) .pregnancy-calculator-btn-cal:disabled {
1088
+ background: #1e2936;
1089
+ }
1090
+
1091
+ .pregnancy-calculator-mp-empty {
1092
+ display: flex;
1093
+ flex-direction: column;
1094
+ align-items: center;
1095
+ justify-content: center;
1096
+ height: 100%;
1097
+ min-height: 18rem;
1098
+ gap: 0.75rem;
1099
+ text-align: center;
1100
+ }
1101
+
1102
+ .pregnancy-calculator-mp-empty-dot {
1103
+ width: 3rem;
1104
+ height: 3rem;
1105
+ border-radius: 50%;
1106
+ background: var(--pc-tri-bg);
1107
+ border: 2px solid var(--pc-tri-primary);
1108
+ box-shadow: 0 0 0 6px var(--pc-tri-glow);
1109
+ }
1110
+
1111
+ .pregnancy-calculator-mp-empty-title {
1112
+ font-size: 1.125rem;
1113
+ font-weight: 700;
1114
+ color: var(--pc-text);
1115
+ }
1116
+
1117
+ .pregnancy-calculator-mp-empty-body {
1118
+ font-size: 0.875rem;
1119
+ color: var(--pc-text-muted);
1120
+ max-width: 22ch;
1121
+ line-height: 1.5;
1122
+ margin: 0;
1123
+ }
1124
+
1125
+ @keyframes pc-fade-in {
1126
+ from {
1127
+ opacity: 0;
1128
+ transform: translateY(6px);
1129
+ }
1130
+ to {
1131
+ opacity: 1;
1132
+ transform: translateY(0);
1133
+ }
1134
+ }
1135
+
1136
+ .pregnancy-calculator-mp-results {
1137
+ display: flex;
1138
+ flex-direction: column;
1139
+ gap: 1rem;
1140
+ }
1141
+
1142
+ .pregnancy-calculator-mp-enter {
1143
+ animation: pc-fade-in 0.25s ease-out;
1144
+ }
1145
+
1146
+ .pregnancy-calculator-mp-top-row {
1147
+ display: flex;
1148
+ align-items: center;
1149
+ justify-content: space-between;
1150
+ gap: 0.75rem;
1151
+ flex-wrap: wrap;
1152
+ }
1153
+
1154
+ .pregnancy-calculator-mp-badge {
1155
+ display: inline-flex;
1156
+ align-items: center;
1157
+ padding: 0.375rem 0.875rem;
1158
+ border-radius: 2rem;
1159
+ background: var(--pc-tri-badge);
1160
+ color: var(--pc-tri-text);
1161
+ font-size: 0.875rem;
1162
+ font-weight: 700;
1163
+ border: 1px solid var(--pc-tri-primary);
1164
+ }
1165
+
1166
+ .pregnancy-calculator-analogy-tabs {
1167
+ display: flex;
1168
+ gap: 0.25rem;
1169
+ background: var(--pc-bg-muted);
1170
+ padding: 0.25rem;
1171
+ border-radius: 0.5rem;
1172
+ border: 1px solid var(--pc-border);
1173
+ }
1174
+
1175
+ .pregnancy-calculator-at-btn {
1176
+ padding: 0.25rem 0.625rem;
1177
+ border-radius: 0.375rem;
1178
+ border: none;
1179
+ background: transparent;
1180
+ color: var(--pc-text-muted);
1181
+ font-size: 0.75rem;
1182
+ font-weight: 500;
1183
+ cursor: pointer;
1184
+ transition:
1185
+ background 0.15s,
1186
+ color 0.15s;
1187
+ }
1188
+
1189
+ .pregnancy-calculator-at-btn-active {
1190
+ background: var(--pc-bg);
1191
+ color: var(--pc-tri-accent);
1192
+ box-shadow: 0 1px 3px var(--pc-shadow);
1193
+ }
1194
+
1195
+ .pregnancy-calculator-size-card {
1196
+ display: flex;
1197
+ align-items: baseline;
1198
+ justify-content: space-between;
1199
+ background: #f8fafc;
1200
+ border-radius: 20px;
1201
+ padding: 24px 28px;
1202
+ gap: 12px;
1203
+ }
1204
+
1205
+ :global(.theme-dark) .pregnancy-calculator-size-card {
1206
+ background: #1a2332;
1207
+ }
1208
+
1209
+ .pregnancy-calculator-size-name {
1210
+ font-size: 1.6rem;
1211
+ font-weight: 300;
1212
+ font-style: italic;
1213
+ color: var(--pc-text);
1214
+ letter-spacing: -0.01em;
1215
+ }
1216
+
1217
+ :global(.theme-dark) .pregnancy-calculator-size-name {
1218
+ color: #f1f5f9;
1219
+ }
1220
+
1221
+ .pregnancy-calculator-size-measure {
1222
+ font-size: 0.8rem;
1223
+ font-weight: 700;
1224
+ color: #94a3b8;
1225
+ text-transform: uppercase;
1226
+ letter-spacing: 0.08em;
1227
+ white-space: nowrap;
1228
+ }
1229
+
1230
+ .pregnancy-calculator-info-stack {
1231
+ display: flex;
1232
+ flex-direction: column;
1233
+ gap: 0.75rem;
1234
+ }
1235
+
1236
+ .pregnancy-calculator-info-block {
1237
+ background: #fff;
1238
+ border-radius: 16px;
1239
+ padding: 18px 20px;
1240
+ box-shadow: 0 1px 6px rgba(0, 0, 0, 0.04);
1241
+ display: flex;
1242
+ flex-direction: column;
1243
+ }
1244
+
1245
+ :global(.theme-dark) .pregnancy-calculator-info-block {
1246
+ background: #1a2332;
1247
+ box-shadow: 0 1px 6px rgba(0, 0, 0, 0.15);
1248
+ }
1249
+
1250
+ .pregnancy-calculator-info-key {
1251
+ font-size: 0.65rem;
1252
+ font-weight: 900;
1253
+ text-transform: uppercase;
1254
+ letter-spacing: 0.14em;
1255
+ color: var(--pc-tri-accent);
1256
+ margin-bottom: 7px;
1257
+ transition: color 0.5s;
1258
+ }
1259
+
1260
+ .pregnancy-calculator-info-text {
1261
+ font-size: 0.92rem;
1262
+ color: var(--pc-text-muted);
1263
+ line-height: 1.75;
1264
+ margin: 0;
1265
+ font-weight: 500;
1266
+ }
1267
+
1268
+ .pregnancy-calculator-wonder-line {
1269
+ font-size: 0.85rem;
1270
+ font-style: italic;
1271
+ font-weight: 600;
1272
+ color: var(--pc-tri-text);
1273
+ padding: 12px 16px;
1274
+ border-left: 3px solid var(--pc-tri-primary);
1275
+ background: var(--pc-tri-bg);
1276
+ border-radius: 0 12px 12px 0;
1277
+ line-height: 1.6;
1278
+ transition:
1279
+ background 0.5s,
1280
+ color 0.5s,
1281
+ border-color 0.5s;
1282
+ }
1283
+
1284
+ .pregnancy-calculator-semaphore {
1285
+ display: grid;
1286
+ grid-template-columns: 1fr 1fr;
1287
+ gap: 0.75rem;
1288
+ }
1289
+
1290
+ .pregnancy-calculator-sema {
1291
+ border-radius: 0.625rem;
1292
+ padding: 0.75rem;
1293
+ display: flex;
1294
+ flex-direction: column;
1295
+ gap: 0.5rem;
1296
+ }
1297
+
1298
+ .pregnancy-calculator-sema-safe {
1299
+ background: var(--pc-safe-bg);
1300
+ border: 1px solid rgba(22, 163, 74, 0.2);
1301
+ }
1302
+
1303
+ .pregnancy-calculator-sema-alert {
1304
+ background: var(--pc-alert-bg);
1305
+ border: 1px solid rgba(234, 88, 12, 0.2);
1306
+ }
1307
+
1308
+ .pregnancy-calculator-sema-title {
1309
+ font-size: 0.6875rem;
1310
+ font-weight: 700;
1311
+ text-transform: uppercase;
1312
+ letter-spacing: 0.04em;
1313
+ }
1314
+
1315
+ .pregnancy-calculator-sema-safe .pregnancy-calculator-sema-title {
1316
+ color: var(--pc-safe-title);
1317
+ }
1318
+
1319
+ .pregnancy-calculator-sema-alert .pregnancy-calculator-sema-title {
1320
+ color: var(--pc-alert-title);
1321
+ }
1322
+
1323
+ .pregnancy-calculator-sema-list {
1324
+ list-style: none;
1325
+ margin: 0;
1326
+ padding: 0;
1327
+ display: flex;
1328
+ flex-direction: column;
1329
+ gap: 0.25rem;
1330
+ }
1331
+
1332
+ .pregnancy-calculator-sema-list li {
1333
+ font-size: 0.75rem;
1334
+ color: var(--pc-text-muted);
1335
+ padding-left: 1rem;
1336
+ position: relative;
1337
+ line-height: 1.4;
1338
+ }
1339
+
1340
+ .pregnancy-calculator-sema-safe .pregnancy-calculator-sema-list li::before {
1341
+ content: "v";
1342
+ position: absolute;
1343
+ left: 0;
1344
+ color: #22c55e;
1345
+ font-weight: 900;
1346
+ font-size: 0.7rem;
1347
+ }
1348
+
1349
+ .pregnancy-calculator-sema-alert .pregnancy-calculator-sema-list li::before {
1350
+ content: "!";
1351
+ position: absolute;
1352
+ left: 0;
1353
+ color: #f97316;
1354
+ font-weight: 900;
1355
+ font-size: 0.7rem;
1356
+ }
1357
+
1358
+ .pregnancy-calculator-mp-egg {
1359
+ display: flex;
1360
+ flex-direction: column;
1361
+ align-items: center;
1362
+ justify-content: center;
1363
+ height: 100%;
1364
+ min-height: 18rem;
1365
+ gap: 14px;
1366
+ padding: 48px 32px;
1367
+ text-align: center;
1368
+ animation: pc-fade-in 0.4s ease-out;
1369
+ }
1370
+
1371
+ .pregnancy-calculator-egg-dot {
1372
+ width: 48px;
1373
+ height: 48px;
1374
+ border-radius: 50%;
1375
+ border: 2px dashed #f87171;
1376
+ background: #fef2f2;
1377
+ animation: pc-egg-spin 6s linear infinite;
1378
+ }
1379
+
1380
+ .pregnancy-calculator-egg-dot[data-reason="too-old"] {
1381
+ border-color: #fb923c;
1382
+ background: #fff7ed;
1383
+ }
1384
+
1385
+ @keyframes pc-egg-spin {
1386
+ from {
1387
+ transform: rotate(0deg);
1388
+ }
1389
+ to {
1390
+ transform: rotate(360deg);
1391
+ }
1392
+ }
1393
+
1394
+ .pregnancy-calculator-egg-title {
1395
+ font-size: 1.2rem;
1396
+ font-weight: 800;
1397
+ color: var(--pc-text);
1398
+ letter-spacing: -0.02em;
1399
+ }
1400
+
1401
+ .pregnancy-calculator-egg-body {
1402
+ font-size: 0.92rem;
1403
+ color: var(--pc-text-muted);
1404
+ max-width: 300px;
1405
+ line-height: 1.7;
1406
+ font-style: italic;
1407
+ margin: 0;
1408
+ }
1409
+
1410
+ .pregnancy-calculator-tl-header {
1411
+ padding: 18px 18px 12px;
1412
+ font-size: 0.65rem;
1413
+ font-weight: 900;
1414
+ text-transform: uppercase;
1415
+ letter-spacing: 0.15em;
1416
+ color: #94a3b8;
1417
+ border-bottom: 1px solid var(--pc-border);
1418
+ flex-shrink: 0;
1419
+ }
1420
+
1421
+ .pregnancy-calculator-tl-scroll {
1422
+ flex: 1;
1423
+ min-height: 0;
1424
+ overflow-y: auto;
1425
+ padding: 12px 14px 20px;
1426
+ scrollbar-width: thin;
1427
+ scrollbar-color: #e2e8f0 transparent;
1428
+ }
1429
+
1430
+ .pregnancy-calculator-tl-scroll::-webkit-scrollbar {
1431
+ width: 3px;
1432
+ }
1433
+
1434
+ .pregnancy-calculator-tl-scroll::-webkit-scrollbar-thumb {
1435
+ background: #e2e8f0;
1436
+ border-radius: 2px;
1437
+ }
1438
+
1439
+ .pregnancy-calculator-tl-row {
1440
+ display: flex;
1441
+ align-items: flex-start;
1442
+ gap: 0.5rem;
1443
+ padding: 0.25rem 0.75rem;
1444
+ cursor: default;
1445
+ transition: background 0.1s;
1446
+ }
1447
+
1448
+ .pregnancy-calculator-tl-row-current {
1449
+ background: var(--pc-tri-bg);
1450
+ }
1451
+
1452
+ .pregnancy-calculator-tl-line-col {
1453
+ display: flex;
1454
+ flex-direction: column;
1455
+ align-items: center;
1456
+ flex-shrink: 0;
1457
+ width: 1rem;
1458
+ padding-top: 0.2rem;
1459
+ }
1460
+
1461
+ .pregnancy-calculator-tl-dot {
1462
+ width: 0.5rem;
1463
+ height: 0.5rem;
1464
+ border-radius: 50%;
1465
+ background: var(--pc-border);
1466
+ flex-shrink: 0;
1467
+ transition: background 0.15s;
1468
+ }
1469
+
1470
+ .pregnancy-calculator-tl-row-past .pregnancy-calculator-tl-dot {
1471
+ background: var(--pc-tri-accent);
1472
+ }
1473
+
1474
+ .pregnancy-calculator-tl-row-current .pregnancy-calculator-tl-dot {
1475
+ background: var(--pc-tri-accent);
1476
+ box-shadow: 0 0 0 3px var(--pc-tri-glow);
1477
+ width: 0.625rem;
1478
+ height: 0.625rem;
1479
+ }
1480
+
1481
+ .pregnancy-calculator-tl-line {
1482
+ width: 2px;
1483
+ flex: 1;
1484
+ min-height: 1.25rem;
1485
+ background: var(--pc-border);
1486
+ margin-top: 2px;
1487
+ }
1488
+
1489
+ .pregnancy-calculator-tl-row-past .pregnancy-calculator-tl-line {
1490
+ background: var(--pc-tri-primary);
1491
+ }
1492
+
1493
+ .pregnancy-calculator-tl-info {
1494
+ display: flex;
1495
+ align-items: baseline;
1496
+ gap: 0.375rem;
1497
+ min-width: 0;
1498
+ }
1499
+
1500
+ .pregnancy-calculator-tl-num {
1501
+ font-size: 0.75rem;
1502
+ font-weight: 700;
1503
+ color: var(--pc-text-dim);
1504
+ flex-shrink: 0;
1505
+ }
1506
+
1507
+ .pregnancy-calculator-tl-row-past .pregnancy-calculator-tl-num {
1508
+ color: var(--pc-tri-accent);
1509
+ }
1510
+
1511
+ .pregnancy-calculator-tl-row-current .pregnancy-calculator-tl-num {
1512
+ color: var(--pc-tri-accent);
1513
+ font-size: 0.875rem;
1514
+ }
1515
+
1516
+ .pregnancy-calculator-tl-label {
1517
+ font-size: 0.6875rem;
1518
+ color: var(--pc-text-dim);
1519
+ white-space: nowrap;
1520
+ overflow: hidden;
1521
+ text-overflow: ellipsis;
1522
+ }
1523
+
1524
+ .pregnancy-calculator-tl-row-current .pregnancy-calculator-tl-label {
1525
+ color: var(--pc-tri-text);
1526
+ font-weight: 600;
1527
+ font-size: 0.75rem;
1528
+ }
1529
+
1530
+ @media (max-width: 900px) {
1531
+ .pregnancy-calculator-main {
1532
+ grid-template-columns: 1fr;
1533
+ }
1534
+
1535
+ .pregnancy-calculator-center {
1536
+ border-right: none;
1537
+ border-top: 1px solid var(--pc-border);
1538
+ }
1539
+
1540
+ .pregnancy-calculator-right {
1541
+ border-top: 1px solid var(--pc-border);
1542
+ height: 16rem;
1543
+ }
1544
+
1545
+ .pregnancy-calculator-tl-inner {
1546
+ position: static;
1547
+ height: 100%;
1548
+ }
1549
+
1550
+ .pregnancy-calculator-tl-scroll {
1551
+ display: flex;
1552
+ flex-direction: row;
1553
+ overflow-x: auto;
1554
+ overflow-y: hidden;
1555
+ padding: 0.5rem;
1556
+ gap: 0.25rem;
1557
+ }
1558
+
1559
+ .pregnancy-calculator-tl-row {
1560
+ flex-direction: column;
1561
+ align-items: center;
1562
+ padding: 0.5rem 0.375rem;
1563
+ min-width: 3rem;
1564
+ }
1565
+
1566
+ .pregnancy-calculator-tl-line-col {
1567
+ flex-direction: row;
1568
+ width: auto;
1569
+ padding-top: 0;
1570
+ }
1571
+
1572
+ .pregnancy-calculator-tl-line {
1573
+ width: 1.25rem;
1574
+ height: 2px;
1575
+ min-height: 0;
1576
+ margin-top: 0;
1577
+ margin-left: 2px;
1578
+ }
1579
+
1580
+ .pregnancy-calculator-tl-info {
1581
+ flex-direction: column;
1582
+ align-items: center;
1583
+ gap: 0.125rem;
1584
+ }
1585
+
1586
+ .pregnancy-calculator-tl-label {
1587
+ display: none;
1588
+ }
1589
+
1590
+ .pregnancy-calculator-semaphore {
1591
+ grid-template-columns: 1fr;
1592
+ }
1593
+
1594
+ .pregnancy-calculator-left {
1595
+ border-right: none;
1596
+ border-bottom: 1px solid var(--pc-border);
1597
+ }
1598
+ }
1599
+
1600
+ @media (max-width: 600px) {
1601
+ .pregnancy-calculator-header {
1602
+ flex-direction: column;
1603
+ align-items: flex-start;
1604
+ }
1605
+
1606
+ .pregnancy-calculator-method-group {
1607
+ width: 100%;
1608
+ justify-content: stretch;
1609
+ }
1610
+
1611
+ .pregnancy-calculator-method-btn {
1612
+ flex: 1;
1613
+ text-align: center;
1614
+ }
1615
+ }
1616
+ </style>