mathiassandnes Claude Opus 4.5 commited on
Commit
2c64567
·
1 Parent(s): 1c3f26e

Clean up Strategy view - hide product header & exec summary

Browse files

- Hide Product Header and Executive Summary for Strategy view
- Strategy now has clean standalone layout without clutter
- Add liis-design.md skill for brand colors (to be updated)
- Other views retain the Executive Summary

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Files changed (2) hide show
  1. .claude/skills/liis-design.md +79 -0
  2. app.py +43 -46
.claude/skills/liis-design.md ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # LiiS Design System
2
+
3
+ Apply LiiS brand styling to the simulator.
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ /liis-design
9
+ ```
10
+
11
+ ## Brand Colors (to be updated)
12
+
13
+ ```python
14
+ # Primary colors
15
+ LIIS_PRIMARY = "#2ecc71" # TODO: Update with actual LiiS green
16
+ LIIS_SECONDARY = "#1a1a2e" # TODO: Update with actual dark
17
+ LIIS_ACCENT = "#f1c40f" # TODO: Update with actual accent
18
+ LIIS_BACKGROUND = "#0e0e1a" # TODO: Update with actual bg
19
+ LIIS_TEXT = "#ffffff" # TODO: Update with actual text
20
+ LIIS_MUTED = "#888888" # TODO: Update with actual muted
21
+
22
+ # Semantic colors
23
+ LIIS_SUCCESS = "#2ecc71"
24
+ LIIS_WARNING = "#f1c40f"
25
+ LIIS_ERROR = "#e74c3c"
26
+ ```
27
+
28
+ ## Typography (to be updated)
29
+
30
+ ```python
31
+ LIIS_FONT_FAMILY = "system-ui, -apple-system, sans-serif" # TODO: Update
32
+ LIIS_HEADING_WEIGHT = "600"
33
+ LIIS_BODY_WEIGHT = "400"
34
+ ```
35
+
36
+ ## Design Principles
37
+
38
+ 1. **Minimal & Clean** - Lots of whitespace, no clutter
39
+ 2. **Family-friendly** - Warm, accessible, trustworthy
40
+ 3. **Sustainability focus** - Green accents, circular imagery
41
+ 4. **Functional simplicity** - Clear hierarchy, obvious actions
42
+
43
+ ## CSS for Streamlit
44
+
45
+ ```css
46
+ /* Apply in st.markdown() with unsafe_allow_html=True */
47
+ .liis-card {
48
+ background: linear-gradient(135deg, #1a1a2e 0%, #252540 100%);
49
+ padding: 1.5rem;
50
+ border-radius: 12px;
51
+ border-left: 4px solid #2ecc71;
52
+ }
53
+
54
+ .liis-hero-metric {
55
+ font-size: 2.5rem;
56
+ font-weight: 600;
57
+ color: #2ecc71;
58
+ }
59
+
60
+ .liis-label {
61
+ color: #888;
62
+ font-size: 0.75rem;
63
+ text-transform: uppercase;
64
+ letter-spacing: 1px;
65
+ }
66
+ ```
67
+
68
+ ## Instructions
69
+
70
+ When applying LiiS design:
71
+ 1. Remove clutter - only essential information
72
+ 2. Use the brand colors defined above
73
+ 3. Keep charts minimal - no unnecessary gridlines
74
+ 4. Use st.metric() sparingly - prefer custom styled cards
75
+ 5. Maintain consistent spacing (1rem, 1.5rem, 2rem)
76
+
77
+ ## Update Colors
78
+
79
+ When brand colors are provided, update the hex values above and regenerate the CSS.
app.py CHANGED
@@ -243,58 +243,55 @@ else:
243
 
244
 
245
  # ============================================================
246
- # SHARED PRODUCT HEADER (compact)
 
247
  # ============================================================
248
- header_col1, header_col2 = st.columns([1, 3])
 
249
 
250
- with header_col1:
251
- if "image_url" in product_info:
252
- st.image(product_info["image_url"], width=200)
253
 
254
- with header_col2:
255
- st.subheader(product_info["name"])
256
- st.caption(f"**{product_info['brand']}** | Retail: €{retail_price:,} | Lease: €{lease_price}/mo (€{total_lease_cost} total)")
257
 
258
- st.markdown("---")
259
 
260
- # ============================================================
261
- # EXECUTIVE SUMMARY (visible in all views)
262
- # ============================================================
263
- st.markdown("**Executive Summary**")
264
-
265
- # Model Status Badge
266
- st.markdown(f'''
267
- <span style="background-color: {status_color}; color: white; padding: 0.3rem 0.8rem;
268
- border-radius: 20px; font-weight: 600; font-size: 0.85rem;">
269
- Model: {model_status}</span>
270
- <span style="color: #888; margin-left: 1rem; font-size: 0.85rem;">
271
- {operating_margin:.1f}% margin across {max_cycles} cycles</span>
272
- ''', unsafe_allow_html=True)
273
-
274
- # 5 KPI Metrics Row
275
- kpi_cols = st.columns(5)
276
- with kpi_cols[0]:
277
- st.metric("A: Monthly Lease", f"€{lease_price}", help="Revenue driver")
278
- with kpi_cols[1]:
279
- st.metric("B: Operating Margin", f"{operating_margin:.1f}%",
280
- delta="healthy" if operating_margin >= 25 else "tight",
281
- help="Lifecycle profit / revenue")
282
- with kpi_cols[2]:
283
- st.metric("C: Manufacturing", f"€{mfg_cost}", help="First-cycle cost")
284
- with kpi_cols[3]:
285
- st.metric("D: Recovery Rate", f"{eolrr:.1%}", help="Enables reuse cycles")
286
- with kpi_cols[4]:
287
- st.metric("E: Max Cycles", f"{max_cycles}", help="Families per product")
288
-
289
- # Contextual insight based on status
290
- if model_status == "Loss":
291
- st.error("Action needed: Raise lease price, reduce costs, or increase cycles.")
292
- elif model_status == "Break-even":
293
- st.warning(f"Margin thin at {operating_margin:.1f}%. Review pricing or costs.")
294
- else:
295
- st.success(f"Strong: {operating_margin:.1f}% margin, {eolrr:.0%} recovery, {max_cycles} cycles.")
296
 
297
- st.markdown("---")
298
 
299
  # ============================================================
300
  # VIEW: STRATEGY (C-Level)
 
243
 
244
 
245
  # ============================================================
246
+ # SHARED PRODUCT HEADER & EXECUTIVE SUMMARY
247
+ # (Hidden for Strategy view - it has its own clean layout)
248
  # ============================================================
249
+ if selected_view != "Strategy":
250
+ header_col1, header_col2 = st.columns([1, 3])
251
 
252
+ with header_col1:
253
+ if "image_url" in product_info:
254
+ st.image(product_info["image_url"], width=200)
255
 
256
+ with header_col2:
257
+ st.subheader(product_info["name"])
258
+ st.caption(f"**{product_info['brand']}** | Retail: €{retail_price:,} | Lease: €{lease_price}/mo (€{total_lease_cost} total)")
259
 
260
+ st.markdown("---")
261
 
262
+ # Executive Summary
263
+ st.markdown("**Executive Summary**")
264
+
265
+ st.markdown(f'''
266
+ <span style="background-color: {status_color}; color: white; padding: 0.3rem 0.8rem;
267
+ border-radius: 20px; font-weight: 600; font-size: 0.85rem;">
268
+ Model: {model_status}</span>
269
+ <span style="color: #888; margin-left: 1rem; font-size: 0.85rem;">
270
+ {operating_margin:.1f}% margin across {max_cycles} cycles</span>
271
+ ''', unsafe_allow_html=True)
272
+
273
+ kpi_cols = st.columns(5)
274
+ with kpi_cols[0]:
275
+ st.metric("A: Monthly Lease", f"€{lease_price}", help="Revenue driver")
276
+ with kpi_cols[1]:
277
+ st.metric("B: Operating Margin", f"{operating_margin:.1f}%",
278
+ delta="healthy" if operating_margin >= 25 else "tight",
279
+ help="Lifecycle profit / revenue")
280
+ with kpi_cols[2]:
281
+ st.metric("C: Manufacturing", f"€{mfg_cost}", help="First-cycle cost")
282
+ with kpi_cols[3]:
283
+ st.metric("D: Recovery Rate", f"{eolrr:.1%}", help="Enables reuse cycles")
284
+ with kpi_cols[4]:
285
+ st.metric("E: Max Cycles", f"{max_cycles}", help="Families per product")
286
+
287
+ if model_status == "Loss":
288
+ st.error("Action needed: Raise lease price, reduce costs, or increase cycles.")
289
+ elif model_status == "Break-even":
290
+ st.warning(f"Margin thin at {operating_margin:.1f}%. Review pricing or costs.")
291
+ else:
292
+ st.success(f"Strong: {operating_margin:.1f}% margin, {eolrr:.0%} recovery, {max_cycles} cycles.")
 
 
 
 
 
293
 
294
+ st.markdown("---")
295
 
296
  # ============================================================
297
  # VIEW: STRATEGY (C-Level)