Color-code events by family member name anywhere in title

- Fuzzy name matching: if a member's name appears anywhere in the event
  title (word boundary, case-insensitive), it gets their color — no
  [prefix] required. e.g. "Daniel's Week" → green, "Jason Karate" → blue
- More vibrant card color palette (deeper pastels, stronger border accent)
- Bolder event title text and slightly thicker left border for clarity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-27 21:17:29 +12:00
parent 93b2dad8fd
commit 98b4de70e7
3 changed files with 32 additions and 20 deletions

29
app.py
View File

@@ -99,17 +99,28 @@ MEMBER_PREFIX_RE = re.compile(r'^\s*\[([^\]]+)\]\s*(.*)')
def parse_member_and_title(summary, family_members): def parse_member_and_title(summary, family_members):
"""Split a "[Alias] Title" event summary into (member_dict, clean_title).""" """Identify a family member from an event title.
match = MEMBER_PREFIX_RE.match(summary)
if not match:
return None, summary
alias = match.group(1).strip().lower() Checks in order:
title = match.group(2).strip() or summary 1. [Alias] prefix (strips the prefix from the displayed title)
2. Alias word appearing anywhere in the title (title kept as-is)
"""
match = MEMBER_PREFIX_RE.match(summary)
if match:
alias = match.group(1).strip().lower()
title = match.group(2).strip() or summary
for member in family_members:
if alias in member['aliases']:
return member, title
return None, title
summary_lower = summary.lower()
for member in family_members: for member in family_members:
if alias in member['aliases']: for alias in member['aliases']:
return member, title if re.search(r'\b' + re.escape(alias) + r'\b', summary_lower):
return None, title return member, summary
return None, summary
NUM_DAYS = 5 NUM_DAYS = 5

View File

@@ -35,9 +35,9 @@ class Config:
# Event titles prefixed with "[Alias]" (e.g. "[Daniel] Football Practice") # Event titles prefixed with "[Alias]" (e.g. "[Daniel] Football Practice")
# are tagged with that member's name/color and the prefix is stripped for display. # are tagged with that member's name/color and the prefix is stripped for display.
FAMILY_MEMBERS = [ FAMILY_MEMBERS = [
{'key': 'dad', 'name': 'Ludwig', 'aliases': ['ludwig', 'dad'], 'color': '#4A90D9', 'bg': '#DCEAFB'}, {'key': 'dad', 'name': 'Ludwig', 'aliases': ['ludwig', 'dad'], 'color': '#1A6BBF', 'bg': '#C2DEFA'},
{'key': 'mom', 'name': 'Michelle', 'aliases': ['michelle', 'mom'], 'color': '#D9669B', 'bg': '#FBDDEB'}, {'key': 'mom', 'name': 'Michelle', 'aliases': ['michelle', 'mom'], 'color': '#BF1A6B', 'bg': '#FAC2DC'},
{'key': 'jason', 'name': 'Jason', 'aliases': ['jason'], 'color': '#5FA85B', 'bg': '#E1F2DD'}, {'key': 'jason', 'name': 'Jason', 'aliases': ['jason'], 'color': '#1A8C1E', 'bg': '#BFEDCA'},
{'key': 'daniel', 'name': 'Daniel', 'aliases': ['daniel'], 'color': '#D9A53B', 'bg': '#FBEFD3'}, {'key': 'daniel', 'name': 'Daniel', 'aliases': ['daniel'], 'color': '#BF7A00', 'bg': '#FAE4A0'},
] ]
DEFAULT_MEMBER = {'key': 'family', 'name': 'Family', 'color': '#8C8C8C', 'bg': '#E9E9E9'} DEFAULT_MEMBER = {'key': 'family', 'name': 'Family', 'color': '#666666', 'bg': '#E0E0E0'}

View File

@@ -119,27 +119,28 @@ html, body {
.event-card { .event-card {
border-radius: 8px; border-radius: 8px;
padding: 6px 8px; padding: 6px 8px;
border-left: 4px solid transparent; border-left: 5px solid transparent;
font-size: 11.5px; font-size: 11.5px;
line-height: 1.35; line-height: 1.35;
} }
.event-time { .event-time {
font-weight: 700; font-weight: 700;
color: rgba(0, 0, 0, 0.55); color: rgba(0, 0, 0, 0.5);
font-size: 10.5px; font-size: 10.5px;
} }
.event-title { .event-title {
font-weight: 600; font-weight: 700;
color: #2B2B33; color: #1A1A2A;
overflow-wrap: anywhere; overflow-wrap: anywhere;
} }
.event-member { .event-member {
font-size: 10px; font-size: 10px;
color: rgba(0, 0, 0, 0.5); font-weight: 600;
margin-top: 1px; color: rgba(0, 0, 0, 0.45);
margin-top: 2px;
} }