Replace the grey theme with a green-slate light/dark pair
All checks were successful
Build and deploy static pages / build-and-push (push) Successful in 13s

PaperMod ships grey on grey, which read as flat and dim on pages that are
mostly tables. Both schemes are now redefinitions of PaperMod's own
variables, so the theme picks them up without further overrides, plus
--accent, --warm and --wash for the placements below. Every text pair
clears WCAG AA.

Venue tables drop the full 1px grid for horizontal rules, a tinted header
and an accent row hover; domain and tag code spans become chips. Warm
marks the one cell worth finding first in a headered table — the ICORE
rank, the SCImago quartile, the still-open cycle — and detail-page fact
tables are excluded, since bold there is a row label, not emphasis.

The FullCalendar variable mapping was dark-only, leaving light mode on
the library's stock chrome; it now maps once through theme variables and
covers both. Event colours were saturated with white text on top, so they
become five pale chips carrying explicit dark ink, legible on either
theme.

Ranks were also emitting '**A***', which closes the emphasis on the
second star and leaves the third loose — visible once ranks had their own
colour.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 20:28:35 +02:00
parent 69b2c06b28
commit 4de1553c21
7 changed files with 364 additions and 90 deletions

View File

@@ -178,6 +178,12 @@ def load_venue_digests(papers_dir: Path) -> dict[str, list[dict]]:
# Markdown body renderers
# ---------------------------------------------------------------------------
def _bold_rank(rank: str) -> str:
"""Bold a rank that may carry a literal asterisk. '**A***' closes the
emphasis on the second star, leaving the third one loose outside it."""
return "**" + str(rank).replace("*", r"\*") + "**"
def _conf_body(fm: dict, digests: list[dict] | None = None, base_path: str = "") -> str:
rank = fm.get("icore_rank") or ""
hp = fm.get("homepage") or ""
@@ -196,7 +202,7 @@ def _conf_body(fm: dict, digests: list[dict] | None = None, base_path: str = "")
lines = [f"\n*{fm.get('full_name', '')}*\n"]
lines += [
"| | |", "|---|---|",
f"| **ICORE Rank** | **{rank}** |",
f"| **ICORE Rank** | {_bold_rank(rank)} |",
f"| **Domains** | {domains} |",
]
if hp:
@@ -471,7 +477,7 @@ def _conferences_section_body(venues: dict, icore: dict, deadlines: dict,
link = f"[{acronym}]({base_path}/venues/conferences/{acronym.lower()}/)"
abs_cell = abstract if (abstract and abstract != paper) else ""
dig_cell = str(n_dig) if n_dig else ""
lines.append(f"| {link} | {full_name} | **{rank}** | {domains} | {abs_cell} | {paper} | {notif} | {event} | {location} | {dig_cell} |")
lines.append(f"| {link} | {full_name} | {_bold_rank(rank)} | {domains} | {abs_cell} | {paper} | {notif} | {event} | {location} | {dig_cell} |")
return "\n".join(lines) + "\n"
@@ -503,6 +509,18 @@ def _journals_section_body(venues: dict, venue_digests: dict | None = None, base
# Calendar events builder (for FullCalendar)
# ---------------------------------------------------------------------------
# One chip colour per event kind. Backgrounds stay pale and dark ink is set
# explicitly, so a chip is legible on both the light and the dark site theme —
# FullCalendar's default white event text would not be.
EVENT_COLORS = {
"abstract": ("#f0d2a4", "#4a3212"),
"paper": ("#f2b3ac", "#5a1f19"),
"notification": ("#b9dfd0", "#14402f"),
"event": ("#bdd2ee", "#1a3557"),
"special": ("#d8c8f0", "#35215c"),
}
def _calendar_events(venues: dict, deadlines: dict, base_path: str = "") -> list[dict]:
events: list[dict] = []
for conf in venues.get("conferences") or []:
@@ -515,15 +533,17 @@ def _calendar_events(venues: dict, deadlines: dict, base_path: str = "") -> list
cycle_name = cycle.get("name") or ""
prefix = f"{acronym} {cycle_name}".strip()
cfp_url = cycle.get("cfp_url") or dl.get("cfp_url") or ""
for field, label, color in [
("abstract_deadline", "abstract deadline", "#f4a261"),
("submission_deadline", "paper deadline", "#e63946"),
("notification", "notification", "#2a9d8f"),
for field, label, kind in [
("abstract_deadline", "abstract deadline", "abstract"),
("submission_deadline", "paper deadline", "paper"),
("notification", "notification", "notification"),
]:
color, text_color = EVENT_COLORS[kind]
iso = _parse_date(cycle.get(field) or "")
if iso:
ev: dict = {"title": f"{prefix}{label}", "start": iso,
"url": url, "color": color, "allDay": True}
"url": url, "color": color,
"textColor": text_color, "allDay": True}
props: dict = {}
if location:
props["location"] = location
@@ -537,16 +557,17 @@ def _calendar_events(venues: dict, deadlines: dict, base_path: str = "") -> list
start, end = _parse_date_range(dl.get("event_dates") or "")
if start:
color, text_color = EVENT_COLORS["event"]
ev = {"title": acronym, "start": start, "url": url,
"color": "#457b9d", "allDay": True}
"color": color, "textColor": text_color, "allDay": True}
if end:
ev["end"] = end
if location:
ev["extendedProps"] = {"location": location}
events.append(ev)
# Journal special issue deadlines — one purple series, distinct from conferences
journal_color = "#7b2cbf"
# Journal special issue deadlines — one violet series, distinct from conferences
journal_color, journal_text_color = EVENT_COLORS["special"]
for journal in venues.get("journals") or []:
acronym = journal.get("acronym", "")
url = f"{base_path}/venues/journals/{acronym.lower()}/"
@@ -563,7 +584,7 @@ def _calendar_events(venues: dict, deadlines: dict, base_path: str = "") -> list
if iso:
ev = {"title": f"{acronym} SI — {si_title}{label}",
"start": iso, "url": url, "color": journal_color,
"allDay": True}
"textColor": journal_text_color, "allDay": True}
if cfp_url:
ev["extendedProps"] = {"cfp_url": cfp_url}
events.append(ev)