arthrod commited on
Commit
5bdaffe
Β·
verified Β·
1 Parent(s): 9a353a7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +807 -397
app.py CHANGED
@@ -1,469 +1,879 @@
1
- import marimo
2
-
3
- __generated_with = "0.9.2"
4
- app = marimo.App()
5
-
6
-
7
- @app.cell
8
- def __():
9
- import marimo as mo
10
-
11
- mo.md("# Welcome to marimo! πŸŒŠπŸƒ")
12
- return (mo,)
13
 
14
 
15
- @app.cell
16
- def __(mo):
17
- slider = mo.ui.slider(1, 22)
18
- return (slider,)
19
-
20
-
21
- @app.cell
22
- def __(mo, slider):
23
- mo.md(
24
- f"""
25
- marimo is a **reactive** Python notebook.
26
-
27
- This means that unlike traditional notebooks, marimo notebooks **run
28
- automatically** when you modify them or
29
- interact with UI elements, like this slider: {slider}.
30
-
31
- {"##" + "πŸƒ" * slider.value}
32
- """
33
- )
34
- return
35
 
36
-
37
- @app.cell(hide_code=True)
38
- def __(mo):
39
- mo.accordion(
40
- {
41
- "Tip: disabling automatic execution": mo.md(
42
- rf"""
43
- marimo lets you disable automatic execution: just go into the
44
- notebook settings and set
45
-
46
- "Runtime > On Cell Change" to "lazy".
47
-
48
- When the runtime is lazy, after running a cell, marimo marks its
49
- descendants as stale instead of automatically running them. The
50
- lazy runtime puts you in control over when cells are run, while
51
- still giving guarantees about the notebook state.
52
- """
53
- )
54
- }
55
- )
56
- return
57
 
58
 
59
  @app.cell(hide_code=True)
60
- def __(mo):
61
- mo.md(
62
- """
63
- Tip: This is a tutorial notebook. You can create your own notebooks
64
- by entering `marimo edit` at the command line.
65
- """
66
- ).callout()
67
  return
68
 
69
 
70
  @app.cell(hide_code=True)
71
- def __(mo):
72
- mo.md(
73
- """
74
- ## 1. Reactive execution
75
-
76
- A marimo notebook is made up of small blocks of Python code called
77
- cells.
78
-
79
- marimo reads your cells and models the dependencies among them: whenever
80
- a cell that defines a global variable is run, marimo
81
- **automatically runs** all cells that reference that variable.
82
-
83
- Reactivity keeps your program state and outputs in sync with your code,
84
- making for a dynamic programming environment that prevents bugs before they
85
- happen.
86
- """
87
- )
88
- return
89
 
90
 
91
  @app.cell(hide_code=True)
92
- def __(changed, mo):
93
- (
94
- mo.md(
95
- f"""
96
- **✨ Nice!** The value of `changed` is now {changed}.
97
-
98
- When you updated the value of the variable `changed`, marimo
99
- **reacted** by running this cell automatically, because this cell
100
- references the global variable `changed`.
101
-
102
- Reactivity ensures that your notebook state is always
103
- consistent, which is crucial for doing good science; it's also what
104
- enables marimo notebooks to double as tools and apps.
105
- """
106
- )
107
- if changed
108
- else mo.md(
109
- """
110
- **🌊 See it in action.** In the next cell, change the value of the
111
- variable `changed` to `True`, then click the run button.
112
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  )
114
- )
115
- return
 
116
 
 
 
117
 
118
- @app.cell
119
- def __():
120
- changed = False
121
- return (changed,)
122
 
123
 
124
  @app.cell(hide_code=True)
125
- def __(mo):
126
- mo.accordion(
127
- {
128
- "Tip: execution order": (
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  """
130
- The order of cells on the page has no bearing on
131
- the order in which cells are executed: marimo knows that a cell
132
- reading a variable must run after the cell that defines it. This
133
- frees you to organize your code in the way that makes the most
134
- sense for you.
135
- """
136
- )
137
- }
138
- )
139
- return
140
 
 
 
141
 
142
- @app.cell(hide_code=True)
143
- def __(mo):
144
- mo.md(
145
- """
146
- **Global names must be unique.** To enable reactivity, marimo imposes a
147
- constraint on how names appear in cells: no two cells may define the same
148
- variable.
149
- """
150
- )
151
- return
152
 
153
 
154
  @app.cell(hide_code=True)
155
- def __(mo):
156
- mo.accordion(
157
- {
158
- "Tip: encapsulation": (
159
- """
160
- By encapsulating logic in functions, classes, or Python modules,
161
- you can minimize the number of global variables in your notebook.
162
- """
163
- )
164
- }
165
- )
166
- return
167
-
168
 
169
- @app.cell(hide_code=True)
170
- def __(mo):
171
- mo.accordion(
172
- {
173
- "Tip: private variables": (
174
- """
175
- Variables prefixed with an underscore are "private" to a cell, so
176
- they can be defined by multiple cells.
177
- """
178
- )
179
- }
180
- )
181
  return
182
 
183
 
184
  @app.cell(hide_code=True)
185
- def __(mo):
186
- mo.md(
187
- """
188
- ## 2. UI elements
189
-
190
- Cells can output interactive UI elements. Interacting with a UI
191
- element **automatically triggers notebook execution**: when
192
- you interact with a UI element, its value is sent back to Python, and
193
- every cell that references that element is re-run.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
 
195
- marimo provides a library of UI elements to choose from under
196
- `marimo.ui`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  """
198
- )
199
- return
200
-
201
-
202
- @app.cell
203
- def __(mo):
204
- mo.md("""**🌊 Some UI elements.** Try interacting with the below elements.""")
205
- return
206
-
207
-
208
- @app.cell
209
- def __(mo):
210
- icon = mo.ui.dropdown(["πŸƒ", "🌊", "✨"], value="πŸƒ")
211
- return (icon,)
212
-
213
-
214
- @app.cell
215
- def __(icon, mo):
216
- repetitions = mo.ui.slider(1, 16, label=f"number of {icon.value}: ")
217
- return (repetitions,)
218
-
219
-
220
- @app.cell
221
- def __(icon, repetitions):
222
- icon, repetitions
223
- return
224
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
226
- @app.cell
227
- def __(icon, mo, repetitions):
228
- mo.md("# " + icon.value * repetitions.value)
229
- return
 
 
 
230
 
231
 
232
  @app.cell(hide_code=True)
233
- def __(mo):
234
- mo.md(
235
- """
236
- ## 3. marimo is just Python
237
 
238
- marimo cells parse Python (and only Python), and marimo notebooks are
239
- stored as pure Python files β€” outputs are _not_ included. There's no
240
- magical syntax.
 
 
 
 
 
241
 
242
- The Python files generated by marimo are:
243
 
244
- - easily versioned with git, yielding minimal diffs
245
- - legible for both humans and machines
246
- - formattable using your tool of choice,
247
- - usable as Python scripts, with UI elements taking their default
248
- values, and
249
- - importable by other modules (more on that in the future).
250
- """
251
- )
252
- return
253
 
254
 
255
  @app.cell(hide_code=True)
256
- def __(mo):
257
- mo.md(
258
- """
259
- ## 4. Running notebooks as apps
260
-
261
- marimo notebooks can double as apps. Click the app window icon in the
262
- bottom-right to see this notebook in "app view."
263
-
264
- Serve a notebook as an app with `marimo run` at the command-line.
265
- Of course, you can use marimo just to level-up your
266
- notebooking, without ever making apps.
267
- """
268
- )
269
- return
270
 
271
 
272
  @app.cell(hide_code=True)
273
- def __(mo):
274
- mo.md(
275
- """
276
- ## 5. The `marimo` command-line tool
277
-
278
- **Creating and editing notebooks.** Use
279
-
280
- ```
281
- marimo edit
282
- ```
283
-
284
- in a terminal to start the marimo notebook server. From here
285
- you can create a new notebook or edit existing ones.
286
-
287
-
288
- **Running as apps.** Use
289
-
290
- ```
291
- marimo run notebook.py
292
- ```
 
 
 
 
 
 
 
293
 
294
- to start a webserver that serves your notebook as an app in read-only mode,
295
- with code cells hidden.
296
 
297
- **Convert a Jupyter notebook.** Convert a Jupyter notebook to a marimo
298
- notebook using `marimo convert`:
299
-
300
- ```
301
- marimo convert your_notebook.ipynb > your_app.py
302
- ```
303
 
304
- **Tutorials.** marimo comes packaged with tutorials:
305
 
306
- - `dataflow`: more on marimo's automatic execution
307
- - `ui`: how to use UI elements
308
- - `markdown`: how to write markdown, with interpolated values and
309
- LaTeX
310
- - `plots`: how plotting works in marimo
311
- - `sql`: how to use SQL
312
- - `layout`: layout elements in marimo
313
- - `fileformat`: how marimo's file format works
314
- - `markdown-format`: for using `.md` files in marimo
315
- - `for-jupyter-users`: if you are coming from Jupyter
 
 
 
 
 
 
 
 
316
 
317
- Start a tutorial with `marimo tutorial`; for example,
318
 
319
- ```
320
- marimo tutorial dataflow
321
- ```
322
 
323
- In addition to tutorials, we have examples in our
324
- [our GitHub repo](https://www.github.com/marimo-team/marimo/tree/main/examples).
325
- """
326
- )
327
- return
328
 
329
 
330
  @app.cell(hide_code=True)
331
- def __(mo):
332
- mo.md(
333
- """
334
- ## 6. The marimo editor
335
 
336
- Here are some tips to help you get started with the marimo editor.
337
- """
338
- )
339
- return
340
 
341
 
342
- @app.cell
343
- def __(mo, tips):
344
- mo.accordion(tips)
345
- return
 
 
 
 
 
 
 
 
 
 
 
 
 
346
 
347
 
348
  @app.cell(hide_code=True)
349
- def __(mo):
350
- mo.md("""## Finally, a fun fact""")
351
- return
 
352
 
353
 
354
  @app.cell(hide_code=True)
355
- def __(mo):
356
- mo.md(
357
- """
358
- The name "marimo" is a reference to a type of algae that, under
359
- the right conditions, clumps together to form a small sphere
360
- called a "marimo moss ball". Made of just strands of algae, these
361
- beloved assemblages are greater than the sum of their parts.
362
- """
363
- )
 
 
 
364
  return
365
 
366
 
367
  @app.cell(hide_code=True)
368
- def __():
369
- tips = {
370
- "Saving": (
371
- """
372
- **Saving**
373
-
374
- - _Name_ your app using the box at the top of the screen, or
375
- with `Ctrl/Cmd+s`. You can also create a named app at the
376
- command line, e.g., `marimo edit app_name.py`.
377
-
378
- - _Save_ by clicking the save icon on the bottom right, or by
379
- inputting `Ctrl/Cmd+s`. By default marimo is configured
380
- to autosave.
381
- """
382
- ),
383
- "Running": (
384
- """
385
- 1. _Run a cell_ by clicking the play ( β–· ) button on the top
386
- right of a cell, or by inputting `Ctrl/Cmd+Enter`.
387
-
388
- 2. _Run a stale cell_ by clicking the yellow run button on the
389
- right of the cell, or by inputting `Ctrl/Cmd+Enter`. A cell is
390
- stale when its code has been modified but not run.
391
-
392
- 3. _Run all stale cells_ by clicking the play ( β–· ) button on
393
- the bottom right of the screen, or input `Ctrl/Cmd+Shift+r`.
394
- """
395
- ),
396
- "Console Output": (
397
- """
398
- Console output (e.g., `print()` statements) is shown below a
399
- cell.
400
- """
401
- ),
402
- "Creating, Moving, and Deleting Cells": (
403
- """
404
- 1. _Create_ a new cell above or below a given one by clicking
405
- the plus button to the left of the cell, which appears on
406
- mouse hover.
407
-
408
- 2. _Move_ a cell up or down by dragging on the handle to the
409
- right of the cell, which appears on mouse hover.
410
-
411
- 3. _Delete_ a cell by clicking the trash bin icon. Bring it
412
- back by clicking the undo button on the bottom right of the
413
- screen, or with `Ctrl/Cmd+Shift+z`.
414
- """
415
- ),
416
- "Disabling Automatic Execution": (
417
- """
418
- Via the notebook settings (gear icon) or footer panel, you
419
- can disable automatic execution. This is helpful when
420
- working with expensive notebooks or notebooks that have
421
- side-effects like database transactions.
422
- """
423
- ),
424
- "Disabling Cells": (
425
- """
426
- You can disable a cell via the cell context menu.
427
- marimo will never run a disabled cell or any cells that depend on it.
428
- This can help prevent accidental execution of expensive computations
429
- when editing a notebook.
430
- """
431
- ),
432
- "Code Folding": (
433
- """
434
- You can collapse or fold the code in a cell by clicking the arrow
435
- icons in the line number column to the left, or by using keyboard
436
- shortcuts.
437
-
438
- Use the command palette (`Ctrl/Cmd+k`) or a keyboard shortcut to
439
- quickly fold or unfold all cells.
440
- """
441
- ),
442
- "Code Formatting": (
443
- """
444
- If you have [ruff](https://github.com/astral-sh/ruff) installed,
445
- you can format a cell with the keyboard shortcut `Ctrl/Cmd+b`.
446
- """
447
- ),
448
- "Command Palette": (
449
- """
450
- Use `Ctrl/Cmd+k` to open the command palette.
451
- """
452
- ),
453
- "Keyboard Shortcuts": (
454
- """
455
- Open the notebook menu (top-right) or input `Ctrl/Cmd+Shift+h` to
456
- view a list of all keyboard shortcuts.
457
- """
458
- ),
459
- "Configuration": (
460
- """
461
- Configure the editor by clicking the gears icon near the top-right
462
- of the screen.
463
- """
464
- ),
465
- }
466
- return (tips,)
467
 
468
 
469
  if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
 
3
+ import marimo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
+ __generated_with = "0.12.8"
6
+ app = marimo.App(
7
+ width="medium",
8
+ layout_file="layouts/welcome-elaine.slides.json",
9
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
 
12
  @app.cell(hide_code=True)
13
+ def _(mo):
14
+ mo.md("""# Seja bem-vinda, Elaine!""")
 
 
 
 
 
15
  return
16
 
17
 
18
  @app.cell(hide_code=True)
19
+ def _():
20
+ import marimo as mo
21
+ return (mo,)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
 
24
  @app.cell(hide_code=True)
25
+ def _(mo):
26
+ # Create an accordion component with the personal message inside
27
+
28
+ def create_accordion_message():
29
+ # Create the accordion component
30
+ accordion = mo.accordion(
31
+ {
32
+ "A Letter for Elaine ": f"""
33
+ <div style="background-color: #fff8e1; border-radius: 8px; padding: 20px; border: 1px solid #ffecb3;
34
+ font-family: 'Garamond', monospace; position: relative; margin: 10px 0;">
35
+
36
+ <p style="font-style: italic; line-height: 1.6;">
37
+ Dear Elaine,
38
+ <br/><br/>
39
+ I'm looking forward to the day you will be reading this letter to me in person.
40
+ I'm sure we will be wrong about many things, but not about the fact that you are
41
+ an adorable smart girl.
42
+ <br/><br/>
43
+ I prepared this page on April 10-11, in 2025. I love your parents very much
44
+ and I hope you inherit (no pressure!) a lot from them.
45
+ <br/><br/>
46
+ With love,<br/>
47
+ Uncle Arthur
48
+ </p>
49
+
50
+ <div style="text-align: right; margin-top: 10px;">
51
+ <svg width="30" height="30" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
52
+ <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
53
+ fill="#ff8f00" opacity="0.7"/>
54
+ </svg>
55
+ </div>
56
+ </div>
57
+ """
58
+ },
59
  )
60
+
61
+ # Return the accordion component
62
+ return accordion
63
 
64
+ # Create the accordion component
65
+ letter_accordion = create_accordion_message()
66
 
67
+ return (letter_accordion,)
 
 
 
68
 
69
 
70
  @app.cell(hide_code=True)
71
+ def _(mo):
72
+ # Create a letter for the parents inside an accordion
73
+
74
+ def create_parents_letter_accordion():
75
+ # Create the accordion with the letter inside
76
+ accordion = mo.accordion(
77
+ {
78
+ "A Letter for Brandon & Lindsay ": f"""
79
+ <div style="background-color: #e3f2fd; border-radius: 8px; padding: 25px; border: 1px solid #bbdefb;
80
+ font-family: 'Georgia', serif; position: relative;
81
+ margin: 10px 0;">
82
+
83
+ <p style="line-height: 1.6; font-size: 1.05em;">
84
+ Hey,
85
+ <br/><br/>
86
+ I prepared this as a gift to Elaine and, of course, to you. This is a list of advice on how to raise a child from 0 to 10.
87
+ Of course I know nothing about this and used deep research, which usually provides solid information.
88
+ <br/><br/>
89
+ Besides a cursory review, I haven't verified the quality of the results. They look solid and logical.
90
+ They are, however, presented as hopeful goals rather than guarantees - aspirations for what we want to happen
91
+ in a child's development. In any case, in the face of the unknown and absence of tested knowledge,
92
+ logic is all we have.
93
+ <br/><br/>
94
+ With love,<br/>
95
+ Arthur
96
+ </p>
97
+
98
+ <div style="text-align: right; margin-top: 10px;">
99
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
100
+ <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"
101
+ fill="#1976d2" opacity="0.8"/>
102
+ </svg>
103
+ </div>
104
+ </div>
105
  """
106
+ },
107
+ )
108
+
109
+ # Return the accordion component
110
+ return accordion
 
 
 
 
 
111
 
112
+ # Create and display the parents letter accordion
113
+ parents_letter_accordion = create_parents_letter_accordion()
114
 
115
+ return (parents_letter_accordion,)
 
 
 
 
 
 
 
 
 
116
 
117
 
118
  @app.cell(hide_code=True)
119
+ def _(letter_accordion, mo, parents_letter_accordion):
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
+ # Display the accordion with a headline
122
+ mo.output.replace(mo.vstack([
123
+ parents_letter_accordion,
124
+ letter_accordion,
125
+ ]))
 
 
 
 
 
 
 
126
  return
127
 
128
 
129
  @app.cell(hide_code=True)
130
+ def _():
131
+ # Emojis for the advice tabs (ensure at least 5)
132
+ advice_emojis = ["⭐", "🧸", "🎈", "πŸ–οΈ", "πŸ’‘"]
133
+
134
+ # Corresponding styles for each advice tab content
135
+ # Each item is a dict: {'border': 'border-color', 'bg': 'background-color'}
136
+ advice_styles = [
137
+ {'border': '#4285f4', 'bg': '#e8f0fe'}, # Blue
138
+ {'border': '#34a853', 'bg': '#e6f4ea'}, # Green
139
+ {'border': '#fbbc05', 'bg': '#fff8e1'}, # Yellow
140
+ {'border': '#ea4335', 'bg': '#fce8e6'}, # Red
141
+ {'border': '#9c27b0', 'bg': '#f3e5f5'} # Purple
142
+ ]
143
+
144
+ year_value_map = {
145
+ 0: "Elaine is here! 🌱",
146
+ 1: "My first year! πŸŽ‚",
147
+ 2: "Toddler Times Two! πŸ‘£",
148
+ 3: "Happy three! ✨",
149
+ 4: "Fabulous Four! πŸš€",
150
+ 5: "A full hand of years! πŸ–οΈ",
151
+ 6: "Super Six! 🦸",
152
+ 7: "Lucky Seven! πŸ€",
153
+ 8: "I'm 8! I'm not a child!",
154
+ 9: "Nearly Double Digits! πŸŽ‰",
155
+ 10: "Two full hands! πŸ™Œ"
156
+ }
157
 
158
+ # Dictionary to store SVG content for each year
159
+ flower_svgs = {
160
+ 0: """
161
+ <!-- Replace with your Year 0 SVG code -->
162
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
163
+ <!-- Background -->
164
+ <rect width="400" height="300" fill="#e8f4f8"/>
165
+
166
+ <!-- Ground -->
167
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
168
+
169
+ <!-- Snow patches -->
170
+ <path d="M50,245 Q100,240 150,245 Q200,250 250,245 Q300,240 350,245 L350,250 L50,250 Z" fill="#f5f5f5" opacity="0.7"/>
171
+
172
+ <!-- Wet soil crack -->
173
+ <path d="M190,245 C193,240 190,235 195,230 C200,225 198,220 200,215" stroke="#3e2723" stroke-width="2" fill="none"/>
174
+ <path d="M192,243 C195,238 192,233 197,228 C202,223 200,218 202,213" stroke="#3e2723" stroke-width="1.5" fill="none"/>
175
+
176
+ <!-- Wet area around crack -->
177
+ <ellipse cx="195" cy="240" rx="15" ry="5" fill="#5d4037" opacity="0.6"/>
178
+
179
+ <!-- Water droplets -->
180
+ <circle cx="197" cy="232" r="1.5" fill="#bbdefb"/>
181
+ <circle cx="193" cy="237" r="1" fill="#bbdefb"/>
182
+ <circle cx="199" cy="228" r="1" fill="#bbdefb"/>
183
+
184
+ <!-- Tiny green sprout hint -->
185
+ <path d="M200,245 C200,242 199,238 200,235" stroke="#81c784" stroke-width="0.8" fill="none"/>
186
+
187
+ <!-- Melting snow particles -->
188
+ <circle cx="180" cy="245" r="2" fill="white" opacity="0.8"/>
189
+ <circle cx="210" cy="246" r="1.5" fill="white" opacity="0.7"/>
190
+ <circle cx="175" cy="248" r="1" fill="white" opacity="0.6"/>
191
+ <circle cx="215" cy="247" r="1" fill="white" opacity="0.5"/>
192
+ </svg>
193
+ """,
194
+
195
+ 1: """
196
+ <!-- Replace with your Year 1 SVG code -->
197
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
198
+ <!-- Background -->
199
+ <rect width="400" height="300" fill="#e8f4f8"/>
200
+
201
+ <!-- Ground -->
202
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
203
+
204
+ <!-- Tiny sprout -->
205
+ <path d="M200,250 C199,240 201,235 200,225" stroke="#66bb6a" stroke-width="2" fill="none"/>
206
+
207
+ <!-- First two tiny leaves -->
208
+ <path d="M200,235 C195,233 190,235 195,238 C200,241 205,238 200,235" fill="#81c784" stroke="#66bb6a" stroke-width="0.8"/>
209
+ <path d="M200,235 C205,233 210,235 205,238 C200,241 195,238 200,235" fill="#81c784" stroke="#66bb6a" stroke-width="0.8"/>
210
+
211
+ <!-- Moist soil around sprout -->
212
+ <ellipse cx="200" cy="250" rx="20" ry="5" fill="#5d4037" opacity="0.5"/>
213
+
214
+ <!-- The diminishing crack -->
215
+ <path d="M195,250 C197,245 196,240 198,238" stroke="#3e2723" stroke-width="1" fill="none" opacity="0.7"/>
216
+
217
+ <!-- Dew drops -->
218
+ <circle cx="201" cy="232" r="1" fill="#bbdefb" opacity="0.9"/>
219
+ <circle cx="199" cy="237" r="0.8" fill="#bbdefb" opacity="0.8"/>
220
+ <circle cx="203" cy="235" r="0.6" fill="#bbdefb" opacity="0.7"/>
221
+
222
+ <!-- Small root hint -->
223
+ <path d="M200,250 C198,255 202,260 199,265" stroke="#8d6e63" stroke-width="0.8" fill="none" opacity="0.5"/>
224
+ <path d="M200,250 C202,255 198,260 201,265" stroke="#8d6e63" stroke-width="0.8" fill="none" opacity="0.5"/>
225
+ </svg>
226
+ """,
227
+
228
+ # Add more years (2-10) with the corresponding SVG code
229
+ # The pattern continues for years 2-10
230
+ # Example for year 2:
231
+ 2: """
232
+ <!-- Replace with your Year 2 SVG code -->
233
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
234
+ <!-- Background -->
235
+ <rect width="400" height="300" fill="#e8f4f8"/>
236
+
237
+ <!-- Ground -->
238
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
239
+
240
+ <!-- Small stem -->
241
+ <path d="M200,250 C198,240 202,230 200,220" stroke="#66bb6a" stroke-width="2.5" fill="none"/>
242
+
243
+ <!-- First pair of true leaves -->
244
+ <path d="M200,230 C190,228 180,230 185,235 C190,240 198,238 200,230" fill="#7cb342" stroke="#66bb6a" stroke-width="1"/>
245
+ <path d="M200,230 C210,228 220,230 215,235 C210,240 202,238 200,230" fill="#7cb342" stroke="#66bb6a" stroke-width="1"/>
246
+
247
+ <!-- Second smaller pair of leaves forming -->
248
+ <path d="M200,220 C196,218 192,219 195,222 C198,225 202,222 200,220" fill="#81c784" stroke="#66bb6a" stroke-width="0.8"/>
249
+ <path d="M200,220 C204,218 208,219 205,222 C202,225 198,222 200,220" fill="#81c784" stroke="#66bb6a" stroke-width="0.8"/>
250
+
251
+ <!-- Moist soil -->
252
+ <ellipse cx="200" cy="250" rx="25" ry="5" fill="#5d4037" opacity="0.4"/>
253
+
254
+ <!-- Root system hints -->
255
+ <path d="M200,250 C195,260 190,265 185,270" stroke="#8d6e63" stroke-width="1" fill="none" opacity="0.4"/>
256
+ <path d="M200,250 C205,260 210,265 215,270" stroke="#8d6e63" stroke-width="1" fill="none" opacity="0.4"/>
257
+ </svg>
258
+ """,
259
+ 3: """
260
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
261
+ <!-- Background -->
262
+ <rect width="400" height="300" fill="#e8f4f8"/>
263
+
264
+ <!-- Ground -->
265
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
266
+
267
+ <!-- Growing stem -->
268
+ <path d="M200,250 C197,235 203,225 198,210 C195,195 202,185 200,175" stroke="#4caf50" stroke-width="3" fill="none"/>
269
+
270
+ <!-- First set of mature leaves -->
271
+ <path d="M198,230 C183,225 173,230 178,238 C183,246 193,240 198,230" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
272
+ <path d="M202,230 C217,225 227,230 222,238 C217,246 207,240 202,230" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
273
+
274
+ <!-- Second set of leaves -->
275
+ <path d="M195,210 C180,205 170,210 175,218 C180,226 190,220 195,210" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
276
+ <path d="M205,210 C220,205 230,210 225,218 C220,226 210,220 205,210" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
277
+
278
+ <!-- Third new set of leaves forming -->
279
+ <path d="M197,190 C190,186 182,188 187,194 C192,200 197,195 197,190" fill="#81c784" stroke="#4caf50" stroke-width="0.8"/>
280
+ <path d="M203,190 C210,186 218,188 213,194 C208,200 203,195 203,190" fill="#81c784" stroke="#4caf50" stroke-width="0.8"/>
281
+
282
+ <!-- Tiny bud beginning at top -->
283
+ <circle cx="200" cy="175" r="3" fill="#f8bbd0" stroke="#ec407a" stroke-width="0.8"/>
284
+
285
+ <!-- Dew drops -->
286
+ <circle cx="183" cy="234" r="1.2" fill="#bbdefb" opacity="0.7"/>
287
+ <circle cx="217" cy="234" r="1" fill="#bbdefb" opacity="0.6"/>
288
+ <circle cx="180" cy="214" r="1.2" fill="#bbdefb" opacity="0.7"/>
289
+ <circle cx="220" cy="214" r="1" fill="#bbdefb" opacity="0.6"/>
290
+ <circle cx="200" cy="175" r="0.8" fill="#bbdefb" opacity="0.9"/>
291
+ </svg>
292
+ """,
293
+ 4: """
294
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
295
+ <!-- Background -->
296
+ <rect width="400" height="300" fill="#e8f4f8"/>
297
+
298
+ <!-- Ground -->
299
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
300
+
301
+ <!-- Taller stem with slight curves -->
302
+ <path d="M200,250 C197,230 203,220 198,200 C195,180 203,160 200,140" stroke="#4caf50" stroke-width="3.5" fill="none"/>
303
+
304
+ <!-- Multiple leaf pairs down the stem -->
305
+ <path d="M198,230 C183,225 173,230 178,238 C183,246 193,240 198,230" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
306
+ <path d="M202,230 C217,225 227,230 222,238 C217,246 207,240 202,230" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
307
+
308
+ <path d="M195,210 C180,205 170,210 175,218 C180,226 190,220 195,210" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
309
+ <path d="M205,210 C220,205 230,210 225,218 C220,226 210,220 205,210" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
310
+
311
+ <path d="M197,190 C182,185 172,190 177,198 C182,206 192,200 197,190" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
312
+ <path d="M203,190 C218,185 228,190 223,198 C218,206 208,200 203,190" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
313
+
314
+ <path d="M195,170 C180,165 175,170 180,178 C185,186 190,180 195,170" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
315
+ <path d="M205,170 C220,165 225,170 220,178 C215,186 210,180 205,170" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
316
+
317
+ <!-- Developing bud -->
318
+ <ellipse cx="200" cy="140" rx="8" ry="12" fill="#f8bbd0" stroke="#ec407a" stroke-width="1"/>
319
+
320
+ <!-- Sepal formation beginning -->
321
+ <path d="M192,145 C188,140 186,135 190,138" fill="#81c784" stroke="#4caf50" stroke-width="0.8"/>
322
+ <path d="M208,145 C212,140 214,135 210,138" fill="#81c784" stroke="#4caf50" stroke-width="0.8"/>
323
+ <path d="M196,152 C194,158 192,163 196,160" fill="#81c784" stroke="#4caf50" stroke-width="0.8"/>
324
+ <path d="M204,152 C206,158 208,163 204,160" fill="#81c784" stroke="#4caf50" stroke-width="0.8"/>
325
+
326
+ <!-- Morning dew -->
327
+ <circle cx="193" cy="143" r="1" fill="#bbdefb" opacity="0.8"/>
328
+ <circle cx="207" cy="143" r="1" fill="#bbdefb" opacity="0.8"/>
329
+ <circle cx="200" cy="132" r="0.8" fill="#bbdefb" opacity="0.9"/>
330
+ </svg>
331
+ """,
332
+ 5: """
333
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
334
+ <!-- Background -->
335
+ <rect width="400" height="300" fill="#e8f4f8"/>
336
+
337
+ <!-- Ground -->
338
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
339
+
340
+ <!-- Stem -->
341
+ <path d="M200,250 C198,220 202,210 198,180 C195,150 205,130 200,100" stroke="#4caf50" stroke-width="4" fill="none"/>
342
+
343
+ <!-- Small leaf left -->
344
+ <path d="M198,220 C185,215 175,218 180,225 C185,232 195,228 198,220" fill="#81c784" stroke="#4caf50" stroke-width="1"/>
345
+
346
+ <!-- Small leaf right -->
347
+ <path d="M202,190 C215,185 225,188 220,195 C215,202 205,198 202,190" fill="#81c784" stroke="#4caf50" stroke-width="1"/>
348
+
349
+ <!-- Medium leaf left -->
350
+ <path d="M195,160 C175,155 165,160 175,170 C185,180 190,175 195,160" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
351
+
352
+ <!-- Closed flower bud -->
353
+ <ellipse cx="200" cy="100" rx="15" ry="25" fill="#f8bbd0" stroke="#ec407a" stroke-width="1.5"/>
354
+
355
+ <!-- Sepal elements -->
356
+ <path d="M185,110 C180,95 185,85 190,95" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
357
+ <path d="M215,110 C220,95 215,85 210,95" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
358
+ <path d="M195,125 C185,130 182,140 192,135" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
359
+ <path d="M205,125 C215,130 218,140 208,135" fill="#66bb6a" stroke="#4caf50" stroke-width="1"/>
360
+
361
+ <!-- Bud structure lines -->
362
+ <path d="M195,100 C197,90 203,90 205,100" stroke="#f48fb1" stroke-width="1" fill="none"/>
363
+ <path d="M190,100 C195,85 205,85 210,100" stroke="#f48fb1" stroke-width="0.8" fill="none" opacity="0.6"/>
364
+ <path d="M200,75 L200,100" stroke="#f48fb1" stroke-width="0.8" fill="none" opacity="0.6"/>
365
+
366
+ <!-- Dew drops -->
367
+ <circle cx="188" cy="108" r="1.5" fill="#bbdefb" opacity="0.8"/>
368
+ <circle cx="212" cy="107" r="1.3" fill="#bbdefb" opacity="0.7"/>
369
+ <circle cx="200" cy="78" r="1" fill="#bbdefb" opacity="0.9"/>
370
+ </svg>
371
+ """,
372
+ 6: """
373
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
374
+ <!-- Background -->
375
+ <rect width="400" height="300" fill="#e8f4f8"/>
376
+
377
+ <!-- Ground -->
378
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
379
+
380
+ <!-- Stem growth between year 5 and 6 -->
381
+ <path d="M200,250 C197,220 203,200 197,180 C194,160 206,140 200,100" stroke="#2e7d32" stroke-width="4" fill="none"/>
382
+
383
+ <!-- Multiple leaf pairs -->
384
+ <path d="M197,225 C177,220 167,225 172,235 C177,245 187,240 197,225" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
385
+ <path d="M203,225 C223,220 233,225 228,235 C223,245 213,240 203,225" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
386
+
387
+ <path d="M194,200 C174,195 164,200 169,210 C174,220 184,215 194,200" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
388
+ <path d="M206,200 C226,195 236,200 231,210 C226,220 216,215 206,200" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
389
+
390
+ <path d="M196,175 C176,170 166,175 171,185 C176,195 186,190 196,175" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
391
+ <path d="M204,175 C224,170 234,175 229,185 C224,195 214,190 204,175" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
392
+
393
+ <path d="M193,150 C173,145 163,150 168,160 C173,170 183,165 193,150" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
394
+ <path d="M207,150 C227,145 237,150 232,160 C227,170 217,165 207,150" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
395
+
396
+ <path d="M197,125 C177,120 167,125 172,135 C177,145 187,140 197,125" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
397
+ <path d="M203,125 C223,120 233,125 228,135 C223,145 213,140 203,125" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
398
+
399
+ <!-- Maturing bud - transitioning between year 5 and 6 -->
400
+ <ellipse cx="200" cy="100" rx="16" ry="28" fill="#f8bbd0" stroke="#ec407a" stroke-width="1.5"/>
401
+
402
+ <!-- Sepals slightly more developed than year 5 but not yet like year 6 -->
403
+ <path d="M184,110 C174,100 169,90 179,100" fill="#66bb6a" stroke="#388e3c" stroke-width="1.2"/>
404
+ <path d="M216,110 C226,100 231,90 221,100" fill="#66bb6a" stroke="#388e3c" stroke-width="1.2"/>
405
+ <path d="M184,90 C174,80 169,70 179,80" fill="#66bb6a" stroke="#388e3c" stroke-width="1.2"/>
406
+ <path d="M216,90 C226,80 231,70 221,80" fill="#66bb6a" stroke="#388e3c" stroke-width="1.2"/>
407
+ <path d="M192,128 C182,138 177,148 187,138" fill="#66bb6a" stroke="#388e3c" stroke-width="1.2"/>
408
+ <path d="M208,128 C218,138 223,148 213,138" fill="#66bb6a" stroke="#388e3c" stroke-width="1.2"/>
409
+
410
+ <!-- Beginning of color differentiation in the bud -->
411
+ <path d="M195,100 C198,90 202,90 205,100" stroke="#f48fb1" stroke-width="1.2" fill="none"/>
412
+ <path d="M190,100 C195,85 205,85 210,100" stroke="#f48fb1" stroke-width="1" fill="none" opacity="0.7"/>
413
+ <path d="M200,72 L200,100" stroke="#f48fb1" stroke-width="1" fill="none" opacity="0.7"/>
414
+
415
+ <!-- New feature: slight hints of petals starting to form inside -->
416
+ <path d="M197,85 C195,80 198,75 200,80" stroke="#f06292" stroke-width="0.8" fill="none" opacity="0.6"/>
417
+ <path d="M203,85 C205,80 202,75 200,80" stroke="#f06292" stroke-width="0.8" fill="none" opacity="0.6"/>
418
+
419
+ <!-- Morning dew -->
420
+ <circle cx="184" cy="104" r="1.5" fill="#bbdefb" opacity="0.8"/>
421
+ <circle cx="216" cy="104" r="1.3" fill="#bbdefb" opacity="0.7"/>
422
+ <circle cx="200" cy="74" r="1" fill="#bbdefb" opacity="0.9"/>
423
+
424
+ <!-- Subtle glow indicating coming transformation -->
425
+ <ellipse cx="200" cy="100" rx="22" ry="34" fill="white" opacity="0.15" filter="blur(5px)"/>
426
+ </svg>
427
+ """,
428
+ 7: """
429
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
430
+ <!-- Background -->
431
+ <rect width="400" height="300" fill="#e8f4f8"/>
432
+
433
+ <!-- Ground -->
434
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
435
+
436
+ <!-- Stronger stem -->
437
+ <path d="M200,250 C196,225 204,200 196,175 C192,150 208,125 200,95" stroke="#2e7d32" stroke-width="4.5" fill="none"/>
438
+
439
+ <!-- Multiple leaf pairs -->
440
+ <path d="M196,225 C176,220 166,225 171,235 C176,245 186,240 196,225" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
441
+ <path d="M204,225 C224,220 234,225 229,235 C224,245 214,240 204,225" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
442
+
443
+ <path d="M193,200 C173,195 163,200 168,210 C173,220 183,215 193,200" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
444
+ <path d="M207,200 C227,195 237,200 232,210 C227,220 217,215 207,200" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
445
+
446
+ <path d="M195,175 C175,170 165,175 170,185 C175,195 185,190 195,175" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
447
+ <path d="M205,175 C225,170 235,175 230,185 C225,195 215,190 205,175" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
448
+
449
+ <path d="M192,150 C172,145 162,150 167,160 C172,170 182,165 192,150" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
450
+ <path d="M208,150 C228,145 238,150 233,160 C228,170 218,165 208,150" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
451
+
452
+ <path d="M196,125 C176,120 166,125 171,135 C176,145 186,140 196,125" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
453
+ <path d="M204,125 C224,120 234,125 229,135 C224,145 214,140 204,125" fill="#388e3c" stroke="#2e7d32" stroke-width="1.2"/>
454
+
455
+ <!-- Maturing bud -->
456
+ <ellipse cx="200" cy="95" rx="18" ry="30" fill="#f8bbd0" stroke="#ec407a" stroke-width="1.5"/>
457
+
458
+ <!-- Fully formed sepals -->
459
+ <path d="M182,105 C172,95 167,85 177,95" fill="#66bb6a" stroke="#388e3c" stroke-width="1.2"/>
460
+ <path d="M218,105 C228,95 233,85 223,95" fill="#66bb6a" stroke="#388e3c" stroke-width="1.2"/>
461
+ <path d="M190,125 C180,135 175,145 185,135" fill="#66bb6a" stroke="#388e3c" stroke-width="1.2"/>
462
+ <path d="M210,125 C220,135 225,145 215,135" fill="#66bb6a" stroke="#388e3c" stroke-width="1.2"/>
463
+
464
+ <!-- Internal bud structure hints -->
465
+ <path d="M195,95 C200,85 200,75 205,95" stroke="#f48fb1" stroke-width="1" fill="none"/>
466
+ <path d="M190,95 C200,80 200,70 210,95" stroke="#f48fb1" stroke-width="0.8" fill="none" opacity="0.6"/>
467
+ <path d="M200,65 L200,95" stroke="#f48fb1" stroke-width="0.8" fill="none" opacity="0.6"/>
468
+
469
+ <!-- Morning dew -->
470
+ <circle cx="182" cy="100" r="1.5" fill="#bbdefb" opacity="0.8"/>
471
+ <circle cx="218" cy="100" r="1.3" fill="#bbdefb" opacity="0.7"/>
472
+ <circle cx="200" cy="68" r="1" fill="#bbdefb" opacity="0.9"/>
473
+ </svg>
474
+ """,
475
+ 8: """
476
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
477
+ <!-- Background -->
478
+ <rect width="400" height="300" fill="#e8f4f8"/>
479
+
480
+ <!-- Ground -->
481
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
482
+
483
+ <!-- Stronger stem with character -->
484
+ <path d="M200,250 C195,220 205,195 195,170 C190,145 205,120 198,95 C195,80 202,75 200,60" stroke="#2e7d32" stroke-width="5" fill="none"/>
485
+
486
+ <!-- Rich foliage - multiple leaf pairs -->
487
+ <path d="M196,225 C176,220 161,230 171,240 C181,250 186,240 196,225" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
488
+ <path d="M204,225 C224,220 239,230 229,240 C219,250 214,240 204,225" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
489
+
490
+ <path d="M193,195 C173,190 158,200 168,210 C178,220 183,210 193,195" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
491
+ <path d="M207,195 C227,190 242,200 232,210 C222,220 217,210 207,195" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
492
+
493
+ <path d="M190,165 C170,160 155,170 165,180 C175,190 180,180 190,165" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
494
+ <path d="M210,165 C230,160 245,170 235,180 C225,190 220,180 210,165" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
495
+
496
+ <path d="M193,135 C173,130 158,140 168,150 C178,160 183,150 193,135" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
497
+ <path d="M207,135 C227,130 242,140 232,150 C222,160 217,150 207,135" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
498
+
499
+ <path d="M195,105 C175,100 160,110 170,120 C180,130 185,120 195,105" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
500
+ <path d="M205,105 C225,100 240,110 230,120 C220,130 215,120 205,105" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
501
+
502
+ <!-- Mature bud with sepals beginning to part slightly -->
503
+ <ellipse cx="200" cy="60" rx="20" ry="32" fill="#f8bbd0" stroke="#ec407a" stroke-width="1.5"/>
504
+
505
+ <!-- Sepals starting to separate -->
506
+ <path d="M180,70 C165,60 155,65 165,75 C175,85 175,75 180,70" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
507
+ <path d="M220,70 C235,60 245,65 235,75 C225,85 225,75 220,70" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
508
+ <path d="M180,50 C165,40 155,45 165,55 C175,65 175,55 180,50" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
509
+ <path d="M220,50 C235,40 245,45 235,55 C225,65 225,55 220,50" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
510
+ <path d="M190,90 C175,100 165,105 175,95 C185,85 185,95 190,90" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
511
+ <path d="M210,90 C225,100 235,105 225,95 C215,85 215,95 210,90" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
512
+
513
+ <!-- Tiny glimpse of pink petals between sepals -->
514
+ <path d="M199,45 C195,40 198,35 201,40 C204,45 201,40 199,45" fill="#f06292" stroke="#ec407a" stroke-width="0.8"/>
515
+ <path d="M201,45 C205,40 202,35 199,40 C196,45 199,40 201,45" fill="#f06292" stroke="#ec407a" stroke-width="0.8"/>
516
+
517
+ <!-- Internal bud structure hints -->
518
+ <path d="M195,60 C200,50 200,40 205,60" stroke="#f48fb1" stroke-width="1" fill="none"/>
519
+ <path d="M190,60 C200,45 200,35 210,60" stroke="#f48fb1" stroke-width="0.8" fill="none" opacity="0.7"/>
520
+
521
+ <!-- Morning dew -->
522
+ <circle cx="175" cy="65" r="1.5" fill="#bbdefb" opacity="0.8"/>
523
+ <circle cx="225" cy="65" r="1.3" fill="#bbdefb" opacity="0.7"/>
524
+ <circle cx="198" cy="38" r="1" fill="#bbdefb" opacity="0.9"/>
525
+ <circle cx="202" cy="38" r="0.8" fill="#bbdefb" opacity="0.8"/>
526
+ </svg>
527
+ """,
528
+ 9: """
529
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
530
+ <!-- Background -->
531
+ <rect width="400" height="300" fill="#e8f4f8"/>
532
+
533
+ <!-- Ground -->
534
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
535
+
536
+ <!-- Strong mature stem -->
537
+ <path d="M200,250 C195,220 205,195 195,170 C190,145 205,120 198,95 C195,75 205,60 200,40" stroke="#2e7d32" stroke-width="5" fill="none"/>
538
+
539
+ <!-- Full foliage -->
540
+ <path d="M196,225 C170,218 155,230 170,245 C185,260 191,250 196,225" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
541
+ <path d="M204,225 C230,218 245,230 230,245 C215,260 209,250 204,225" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
542
+
543
+ <path d="M193,195 C167,188 152,200 167,215 C182,230 188,220 193,195" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
544
+ <path d="M207,195 C233,188 248,200 233,215 C218,230 212,220 207,195" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
545
+
546
+ <path d="M190,165 C164,158 149,170 164,185 C179,200 185,190 190,165" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
547
+ <path d="M210,165 C236,158 251,170 236,185 C221,200 215,190 210,165" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
548
+
549
+ <path d="M193,135 C167,128 152,140 167,155 C182,170 188,160 193,135" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
550
+ <path d="M207,135 C233,128 248,140 233,155 C218,170 212,160 207,135" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
551
+
552
+ <path d="M195,105 C169,98 154,110 169,125 C184,140 190,130 195,105" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
553
+ <path d="M205,105 C231,98 246,110 231,125 C216,140 210,130 205,105" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
554
+
555
+ <path d="M197,75 C171,68 161,80 176,90 C191,100 192,90 197,75" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
556
+ <path d="M203,75 C229,68 239,80 224,90 C209,100 208,90 203,75" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
557
+
558
+ <!-- Bud with sepals clearly opening -->
559
+ <ellipse cx="200" cy="40" rx="22" ry="30" fill="#f8bbd0" stroke="#ec407a" stroke-width="1.5"/>
560
+
561
+ <!-- Sepals distinctly pulled back -->
562
+ <path d="M178,50 C163,40 153,45 163,55 C173,65 173,60 178,50" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
563
+ <path d="M222,50 C237,40 247,45 237,55 C227,65 227,60 222,50" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
564
+ <path d="M178,35 C163,25 153,30 163,40 C173,50 173,45 178,35" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
565
+ <path d="M222,35 C237,25 247,30 237,40 C227,50 227,45 222,35" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
566
+ <path d="M185,65 C170,75 160,80 170,70 C180,60 180,55 185,65" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
567
+ <path d="M215,65 C230,75 240,80 230,70 C220,60 220,55 215,65" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
568
+
569
+ <!-- Pink petals visible but still tightly closed -->
570
+ <path d="M200,40 C195,30 190,20 195,15 C200,10 205,15 200,40" fill="#f06292" stroke="#ec407a" stroke-width="1"/>
571
+ <path d="M200,40 C205,30 210,20 205,15 C200,10 195,15 200,40" fill="#f06292" stroke="#ec407a" stroke-width="1"/>
572
+ <path d="M200,40 C190,35 180,25 185,20 C190,15 200,20 200,40" fill="#f06292" stroke="#ec407a" stroke-width="1"/>
573
+ <path d="M200,40 C210,35 220,25 215,20 C210,15 200,20 200,40" fill="#f06292" stroke="#ec407a" stroke-width="1"/>
574
+
575
+ <!-- Flower center starting to form -->
576
+ <circle cx="200" cy="40" r="5" fill="#f8bbd0"/>
577
+
578
+ <!-- Morning dew -->
579
+ <circle cx="170" cy="45" r="1.5" fill="#bbdefb" opacity="0.8"/>
580
+ <circle cx="230" cy="45" r="1.3" fill="#bbdefb" opacity="0.7"/>
581
+ <circle cx="195" cy="15" r="1" fill="#bbdefb" opacity="0.9"/>
582
+ <circle cx="205" cy="15" r="0.8" fill="#bbdefb" opacity="0.8"/>
583
+ </svg>
584
+ """,
585
+
586
+ # Continue with years 3-10...
587
+ # For brevity, I'll add placeholders for years 3-9 and include year 10
588
+
589
+ 10: """
590
+ <!-- Replace with your Year 10 SVG code -->
591
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
592
+ <!-- Background -->
593
+ <rect width="400" height="300" fill="#e8f4f8"/>
594
+
595
+ <!-- Ground -->
596
+ <path d="M0,250 L400,250 L400,300 L0,300 Z" fill="#6d4c41"/>
597
+
598
+ <!-- Strong stem -->
599
+ <path d="M200,250 C197,230 203,210 197,190 C192,170 208,150 203,130 C198,110 202,90 200,70" stroke="#2e7d32" stroke-width="5" fill="none"/>
600
+
601
+ <!-- Leaves -->
602
+ <path d="M197,220 C175,215 160,225 175,235 C190,245 195,235 197,220" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
603
+ <path d="M203,190 C225,180 235,195 220,205 C205,215 200,200 203,190" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
604
+ <path d="M192,160 C170,155 155,170 170,180 C185,190 188,175 192,160" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
605
+ <path d="M208,130 C230,125 240,140 225,150 C210,160 205,145 208,130" fill="#388e3c" stroke="#2e7d32" stroke-width="1.5"/>
606
+
607
+ <!-- Flower just beginning to open -->
608
+ <!-- Sepals -->
609
+ <path d="M185,80 C175,70 165,80 175,90 C185,100 185,90 185,80" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
610
+ <path d="M215,80 C225,70 235,80 225,90 C215,100 215,90 215,80" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
611
+ <path d="M185,60 C175,50 165,60 175,70 C185,80 185,70 185,60" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
612
+ <path d="M215,60 C225,50 235,60 225,70 C215,80 215,70 215,60" fill="#66bb6a" stroke="#388e3c" stroke-width="1.5"/>
613
+
614
+ <!-- Petals just starting to open -->
615
+ <path d="M200,70 C185,60 175,45 185,35 C195,25 205,35 200,70" fill="#f8bbd0" stroke="#ec407a" stroke-width="1"/>
616
+ <path d="M200,70 C215,60 225,45 215,35 C205,25 195,35 200,70" fill="#f8bbd0" stroke="#ec407a" stroke-width="1"/>
617
+ <path d="M200,70 C195,55 180,40 190,30 C200,20 210,30 200,70" fill="#f8bbd0" stroke="#ec407a" stroke-width="1"/>
618
+ <path d="M200,70 C205,55 220,40 210,30 C200,20 190,30 200,70" fill="#f8bbd0" stroke="#ec407a" stroke-width="1"/>
619
+ <path d="M200,70 C190,55 175,50 180,35 C185,20 200,25 200,70" fill="#f8bbd0" stroke="#ec407a" stroke-width="1"/>
620
+ <path d="M200,70 C210,55 225,50 220,35 C215,20 200,25 200,70" fill="#f8bbd0" stroke="#ec407a" stroke-width="1"/>
621
+
622
+ <!-- Flower center -->
623
+ <circle cx="200" cy="70" r="10" fill="#ffeb3b"/>
624
+ <circle cx="200" cy="70" r="7" fill="#ffc107"/>
625
+ </svg>
626
  """
627
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
628
 
629
+ # Dictionary to store advice for each year
630
+ parenting_advice = {
631
+ 0: [
632
+ "Respond consistently to distress, but avoid hyper-attunement to every minor fuss; allow brief moments for infant self-discovery/soothing within a secure context.",
633
+ "Aim for one consistent primary caregiver, especially in the first 6 months, to provide a clear anchor for secure attachment, more so than a patchwork of caregivers.",
634
+ "Look beyond crying; recognize signs of overstimulation (gaze aversion, arching) and other non-verbal cues to provide more attuned care and prevent meltdowns.",
635
+ "During inconsolable crying, focus on providing a calm, steady, regulating presence (\"containment\") rather than solely on stopping the tears immediately.",
636
+ "Reserve firm \"No's\" for safety; use quick, engaging redirection for most non-dangerous exploration to respect developmental drives while maintaining boundaries."
637
+ ],
638
+
639
+ 1: [
640
+ "Proactively build tolerance for separation through games (peek-a-boo, hide-and-seek with talking) and short, planned practice separations, not just reacting to anxiety.",
641
+ "Never sneak out; use a brief, consistent ritual and leave confidently (even with tears) stating return time concretely. Lingering prolongs distress.",
642
+ "Go beyond responding; expand toddler's utterance into a full phrase, then extend the topic with new info or questions to accelerate language skills.",
643
+ "Frame participation in routines (dressing, cleanup) as helpful contributions, leveraging imitation drive to foster competence and cooperation, not just compliance.",
644
+ "View \"No!\" and boundary testing primarily as cognitive exploration (cause/effect, autonomy), not just defiance, allowing for more empathetic limit-setting."
645
+ ],
646
+
647
+ 2: [
648
+ "Use tantrums as teaching moments: systematically validate feelings, label emotions, connect, and set limits while problem-solving, turning conflict into connection.",
649
+ "Reframe tantrums not as manipulation, but as communication of overwhelm or testing control; respond calmly, acknowledge desire, hold limits, comfort after.",
650
+ "During meltdowns, focus first on helping the child calm down using your own calm presence before attempting to correct behavior or teach lessons.",
651
+ "If a break is needed, use a calm-down space with or near the child, focusing on regulation support, not punitive isolation which can increase shame/distress.",
652
+ "Go beyond basic labels; introduce nuanced feeling words in context and use a simple color-based Mood Meter to help toddlers categorize and express emotions."
653
+ ],
654
+
655
+ 3: [
656
+ "Strategically use imaginative play scenarios (with dolls, puppets) to practice challenging social skills like sharing, turn-taking, and conflict resolution.",
657
+ "Go beyond \"calm down\"; teach concrete methods like \"belly breathing,\" using a calm-down space/jar, or visual aids, and practice them during calm times.",
658
+ "Make transitions smoother by pairing verbal warnings (e.g., \"5 more minutes\") with a sensory cue like a visual timer, a specific song, or a gentle touch.",
659
+ "Actively teach emotion recognition using games with feeling face cards, discussing character expressions in books, and labeling emotions observed in others.",
660
+ "Emphasize effort over outcome in praise; when misbehavior occurs, focus on understanding impact and \"repairing\" harm (apology, kind deed) rather than solely on punishment."
661
+ ],
662
+
663
+ 4: [
664
+ "Allow small, safe failures and manageable risks; don't rescue from all challenges. Frame setbacks as learning opportunities to build coping skills and perseverance.",
665
+ "Go beyond encouragement; teach a concrete process (Stop/Calm, Say Problem, Think Solutions, Try, Reflect) for navigating conflicts and challenges.",
666
+ "To promote reflection and solutions instead of defensiveness, ask \"How can you fix this?\" or \"What could you do differently?\" instead of \"Why did you do that?\".",
667
+ "Frame chores and helpful behaviors not just as tasks, but as contributions that care for the family, pets, or shared spaces, linking responsibility to empathy.",
668
+ "Acknowledge anxiety (\"It's okay to feel scared\"), but gently coach facing fears in small steps rather than allowing complete avoidance, which reinforces anxiety."
669
+ ],
670
+
671
+ 5: [
672
+ "Deliberately resist correcting imperfect efforts on self-care tasks (crooked bed-making, misaligned buttons) to prioritize developing intrinsic motivation and competence over perfectionism, especially challenging for achievement-oriented parents.", "Invest in robust imaginative play that develops classroom-essential social-emotional skills (turn-taking, rule-following, negotiating roles) rather than primarily drilling academic readiness like letter recognition.", "Anchor abstract time words ('tomorrow,' 'later') to concrete sequential experiences ('after you sleep, wake up, and eat breakfast') to reduce confusion and anxiety about anticipated events.", "Recognize 'talking back' as often representing clumsy bids for autonomy; acknowledge the underlying need for independence while redirecting to appropriate expressions by offering legitimate choices.", "Transform storytime into proactive social-emotional training by posing questions that prompt problem-solving: 'What could the character have done instead?' to mentally rehearse strategies for navigating school social scenarios."
673
+
674
+ ],
675
+
676
+ 6: [
677
+ "Deliberately shift praise from outcomes or innate traits ('You're so smart!') to process and strategy ('You found a clever way to solve that problem'), which research shows builds resilience, challenge-seeking, and a growth mindset.", "Explicitly teach friendship initiation skills through role-play (joining groups, sharing materials/ideas, being a good listener) rather than assuming social competencies develop naturally without direct instruction.", "Frame household rules through the lens of fairness and logical consequences ('We clean toys so everyone has safe play space') rather than authority alone, leveraging six-year-olds' emerging sense of justice and cause-effect reasoning.", "Introduce 'feeling thermometers' (1-5 scales) to help children develop emotional granularity beyond basic labels, teaching that different intensity levels require different regulation strategies.", "Deliberately schedule periods of unstructured 'do nothing' time (distinct from screen time) where boredom becomes the catalyst for creativity, daydreaming, and developing internal resources, especially valuable for children with highly scheduled lives."
678
+ ],
679
+
680
+ 7: [
681
+ "Present hypothetical social dilemmas during calm moments ('What would you do if you saw someone sitting alone?') to actively cultivate perspective-taking skills that build on seven-year-olds' emerging empathy.", "When addressing lying, recognize it partially as evidence of cognitive development (Theory of Mind), respond calmly without high emotion, and focus conversations on trust and relationship rather than punishment.", "Replace ineffective reassurances about fears ('Don't worry') with validation plus collaborative coping strategies ('It's normal to feel nervous; let's create a plan together with specific steps to manage this situation').", "During disagreements, explicitly introduce the concept that two people can experience the same event differently and both perspectives can be valid, challenging their tendency toward single-factor thinking.", "Elevate reading practice beyond decoding to 'meaning detective' work by asking questions about character motivation, multiple word meanings, and contextual clues about emotions not explicitly stated in text."
682
+ ],
683
+
684
+ 8: [
685
+ "Proactively rehearse specific peer pressure resistance techniques through role-play (direct refusal, suggesting alternatives, having exit strategies) rather than simply warning about 'bad influences' or expecting good choices without practice.", "Reframe emotional outbursts as evidence of lagging skills (emotional regulation, impulse control) rather than pure misbehavior, responding with empathy for the feeling, clear boundaries on behavior, then explicitly teaching missing coping strategies.", "Support exploration of varying interests without excessive pressure for long-term commitment, recognizing that dabbling and shifting passions are fundamental to self-discovery rather than signs of problematic inconsistency.", "Leverage eight-year-olds' black-and-white thinking to establish clear family values ('In our family, we tell the truth even when it's difficult'), providing moral foundations that will guide more complex ethical reasoning later.", "Implement the 'complaint sandwich' technique when children express criticism rudely: validate the underlying feeling, set clear boundaries about respectful communication, then suggest alternative phrasing that addresses the same concern appropriately."
686
+ ],
687
+
688
+ 9: [
689
+ "Shift from solving your child's problems to collaborative brainstorming by asking guiding questions ('What solutions have you considered?' 'What else might work?') that position you as consultant rather than fixer, building resourcefulness and problem-solving confidence.", "Complement screen time limits with active 'digital citizenship' education covering online safety, respectful communication, privacy management, information evaluation, and understanding the permanence of digital footprints.", "Initiate factual, matter-of-fact conversations about puberty before significant physical changes occur, using age-appropriate books and language to normalize the process and establish yourself as a trusted information source.", "Consciously model healthy conflict resolution between parents using 'I feel' statements, focusing on needs not blame, and working toward solutions, providing your child a lived blueprint for managing her own complex social relationships.", "Frame household responsibilities as contributions to family functioning ('we all help our home run smoothly') rather than tying basic chores directly to allowance, which can inadvertently create a purely transactional view of family participation."
690
+ ],
691
+
692
+ 10: [
693
+ "Evolve from 'rules enforcer' to 'values consultant' by asking questions that help your preteen apply core family principles to complex situations ('How does our value of kindness apply to this friendship dilemma?'), developing internal moral reasoning.", "Move beyond content filtering to actively teaching media literacy skills by discussing who creates media messages and why, identifying stereotypes (particularly gender-based ones), distinguishing fact from opinion, and analyzing persuasion techniques.", "Establish simple but consistent one-on-one connection rituals (bedtime chats, weekly walks, shared hobbies) that signal ongoing availability despite busy schedules and your child's natural gravitational pull toward peer relationships.", "Nurture healthy skepticism by encouraging your child to respectfully question assumptions, look for supporting evidence, and think critically about information, framing this as valuable intellectual development rather than defiance.", "Deliberately shift body-related conversations away from appearance toward function and capability ('bodies are for doing, not just for looking'), emphasizing strength, energy, and health over weight, shape or conventional attractiveness."
694
+ ]
695
+ }
696
 
697
+ return (
698
+ advice_emojis,
699
+ advice_styles,
700
+ flower_svgs,
701
+ parenting_advice,
702
+ year_value_map,
703
+ )
704
 
705
 
706
  @app.cell(hide_code=True)
707
+ def _(year_value_map):
708
+ # Create tab labels for years
709
+ tab_labels = [f"Year {i}" for i in range(11)]
 
710
 
711
+ # Create the year tabs widget - Keys are labels, values don't matter here
712
+ # as the content is generated reactively in the next cell.
713
+ tabs_dict_years = {}
714
+ for i in range(11):
715
+ label = f"Year {i}"
716
+ # Get the custom value from the map, provide a fallback if needed
717
+ value = year_value_map.get(i, f"Value for Year {i}")
718
+ tabs_dict_years[label] = value
719
 
 
720
 
721
+ return (tabs_dict_years,)
 
 
 
 
 
 
 
 
722
 
723
 
724
  @app.cell(hide_code=True)
725
+ def _(mo, tabs_dict_years, year_value_map):
726
+ default_year_value = year_value_map[0]
727
+ year_tabs = mo.ui.tabs(tabs_dict_years, value=default_year_value)
728
+ return (year_tabs,)
 
 
 
 
 
 
 
 
 
 
729
 
730
 
731
  @app.cell(hide_code=True)
732
+ def _(advice_emojis, advice_styles, mo):
733
+ def create_advice_tabs_dictionary(advice_list):
734
+ """Creates the dictionary mapping advice tab emojis to styled content."""
735
+ _advice_tabs_dict = {}
736
+ if not advice_list:
737
+ _advice_tabs_dict["Info"] = mo.md("No specific advice available for this year.")
738
+ else:
739
+ for i, advice_text in enumerate(advice_list):
740
+ # Ensure we don't go out of bounds for emojis/styles
741
+ if i < len(advice_emojis) and i < len(advice_styles):
742
+ tab_key = advice_emojis[i] # Use emoji as the key/label
743
+ current_style = advice_styles[i] # Get the style dict for this tip
744
+
745
+ advice_content = mo.md(f"""
746
+ <div style="background-color: {current_style['bg']}; border-radius: 5px; padding: 15px; border-left: 5px solid {current_style['border']}; min-height: 50px; display: flex; align-items: center;">
747
+ <p style="margin: 0; font-size: 1em; color: #333;">{advice_text}</p>
748
+ </div>
749
+ """)
750
+ _advice_tabs_dict[tab_key] = advice_content
751
+ else:
752
+ # Fallback if there are more tips than emojis/styles (optional)
753
+ tab_key = f"Tip {i+1}"
754
+ advice_content = mo.md(f"<p>{advice_text}</p>") # Basic fallback
755
+ _advice_tabs_dict[tab_key] = advice_content
756
+
757
+ return _advice_tabs_dict
758
+ return (create_advice_tabs_dictionary,)
759
 
 
 
760
 
761
+ @app.cell(hide_code=True)
762
+ def _(year_tabs):
763
+ selected_year_str = year_tabs.value.split()[-1]
764
+ selected_year = int(selected_year_str)
765
+ return (selected_year,)
 
766
 
 
767
 
768
+ @app.cell(hide_code=True)
769
+ def _(flower_svgs, mo, selected_year):
770
+ # 1. Get the SVG for the selected year
771
+ svg_display = mo.Html(f"""
772
+ <div style="
773
+ display: flex;
774
+ justify-content: center; /* Center the content horizontally */
775
+ padding: 20px 10px; /* Add some vertical padding */
776
+ margin: 15px 0; /* Add margin above and below */
777
+ background-color: #f8f9fa; /* Light background color */
778
+ border-radius: 12px; /* Rounded corners */
779
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); /* Subtle shadow */
780
+ border: 1px solid #e9ecef; /* Light border */
781
+ ">
782
+ {flower_svgs.get(selected_year, "<!-- SVG not found -->")}
783
+ </div>
784
+ """)
785
+ return (svg_display,)
786
 
 
787
 
788
+ @app.cell(hide_code=True)
789
+ def _(parenting_advice, selected_year):
790
+ advice_list_for_year = parenting_advice.get(selected_year, [])
791
 
792
+ return (advice_list_for_year,)
 
 
 
 
793
 
794
 
795
  @app.cell(hide_code=True)
796
+ def _(advice_list_for_year, create_advice_tabs_dictionary):
797
+ advice_tabs_dict = create_advice_tabs_dictionary(advice_list_for_year)
 
 
798
 
799
+ return (advice_tabs_dict,)
 
 
 
800
 
801
 
802
+ @app.cell(hide_code=True)
803
+ def _(mo, year_tabs):
804
+ show_years = mo.Html(f"""
805
+ <div style="
806
+ display: flex;
807
+ justify-content: center; /* Center the tabs horizontally */
808
+ padding: 20px 10px; /* Add some vertical padding */
809
+ margin: 15px 0; /* Add margin above and below */
810
+ background-color: #f8f9fa; /* Light background color */
811
+ border-radius: 12px; /* Rounded corners */
812
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); /* Subtle shadow */
813
+ border: 1px solid #e9ecef; /* Light border */
814
+ ">
815
+ {year_tabs}
816
+ </div>
817
+ """)
818
+ return (show_years,)
819
 
820
 
821
  @app.cell(hide_code=True)
822
+ def _(advice_emojis, advice_list_for_year, advice_tabs_dict, mo):
823
+ default_advice_tab = advice_emojis[0] if advice_list_for_year else "Info"
824
+ individual_advice_tabs = mo.ui.tabs(advice_tabs_dict, value=default_advice_tab)
825
+ return (individual_advice_tabs,)
826
 
827
 
828
  @app.cell(hide_code=True)
829
+ def _(individual_advice_tabs, mo, show_years, svg_display):
830
+ mo.vstack([
831
+ mo.Html("""
832
+ <div style="text-align: center; font-family: Garamond, serif; font-weight: bold; font-size: 1.5em;">
833
+ A Letter to Elaine
834
+ </div>
835
+ """),
836
+ show_years,
837
+ svg_display,
838
+ mo.md("---"),
839
+ individual_advice_tabs
840
+ ])
841
  return
842
 
843
 
844
  @app.cell(hide_code=True)
845
+ def _(mo):
846
+
847
+ # Final capsule with source link
848
+ final_capsule = mo.Html(f"""
849
+ <div style="
850
+ background-color: #f0f0f0; /* Light grey background */
851
+ border-radius: 15px; /* Rounded corners */
852
+ padding: 15px 25px; /* Padding inside the capsule */
853
+ margin: 25px auto; /* Margin top/bottom and centered horizontally */
854
+ text-align: center; /* Center the text */
855
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Modern font */
856
+ font-size: 0.9em; /* Slightly smaller font size */
857
+ color: #555; /* Dark grey text color */
858
+ border: 1px solid #ddd; /* Light border */
859
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); /* Subtle shadow */
860
+ max-width: 800px; /* Limit the width */
861
+ ">
862
+ Compiled sources:
863
+ <a href="https://docs.google.com/document/d/1PhMmoAAGtcYAsHW2TUWxdZ4rL_P85iCES-UnU_ZOp4Q/edit?usp=sharing"
864
+ target="_blank"
865
+ rel="noopener noreferrer"
866
+ style="color: #007bff; text-decoration: none; font-weight: 500;"
867
+ onmouseover="this.style.textDecoration='underline'"
868
+ onmouseout="this.style.textDecoration='none'">
869
+ Google Docs Link
870
+ </a>
871
+ </div>
872
+ """)
873
+
874
+ # Display the final capsule
875
+ final_capsule
876
+ return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
877
 
878
 
879
  if __name__ == "__main__":