Gap between event cards; dotless rows drop day, keep just year

- Each event row is now a self-contained card (full border on
  all four sides, rounded all four corners). border-spacing on
  the section table inserts a 10px vertical gap between cards
  so they read as distinct entries. The timeline rail breaks
  along with the cards, which actually reads better — each event
  feels like its own beat on the timeline rather than rungs of a
  ladder.
- When two events share an upcoming day, the second row
  (dotless) used to repeat "17. MAI" — wasted vertical space.
  It now only prints the year, bumped up to 14px so it carries
  on its own. The always-visible year is also slightly larger
  (13px vs 11px) and tonally lifted from #aaa muted to #777
  tertiary so it pairs evenly with the day-month line above it.
This commit is contained in:
2026-05-15 13:26:15 +02:00
parent 461c99fcd1
commit abe77a9b9d
+39 -33
View File
@@ -431,11 +431,16 @@ $summary_item_style = 'padding:3px 0;';
//
// $show_dot suppresses the dot on rows whose upcoming-day matches
// the previous row, so each calendar day has exactly one dot.
// Every row is now a self-contained mini-card (full border on all
// sides, rounded corners). Vertical gaps between rows come from the
// outer table's border-spacing — the rail naturally breaks between
// rows along with the cards.
//
// $show_dot suppresses the dot AND the day+month line on rows whose
// upcoming-day matches the previous (only the year is then shown).
$event_row = static function (
Fact $fact,
string $body_html,
bool $is_first,
bool $is_last,
bool $show_dot,
)
use (
@@ -448,25 +453,15 @@ $event_row = static function (
$card_corner_radius,
$palette,
): string {
$avatar_extra = '';
$content_extra = '';
if ($is_first) {
$avatar_extra .= 'border-top:1px solid ' . $palette['border'] . ';'
. 'border-top-left-radius:' . $card_corner_radius . 'px;';
$content_extra .= 'border-top:1px solid ' . $palette['border'] . ';'
. 'border-top-right-radius:' . $card_corner_radius . 'px;';
}
if ($is_last) {
$avatar_extra .= 'border-bottom:1px solid ' . $palette['border'] . ';'
$avatar_extra = 'border-top:1px solid ' . $palette['border'] . ';'
. 'border-bottom:1px solid ' . $palette['border'] . ';'
. 'border-top-left-radius:' . $card_corner_radius . 'px;'
. 'border-bottom-left-radius:' . $card_corner_radius . 'px;';
$content_extra .= 'border-bottom:1px solid ' . $palette['border'] . ';'
$content_extra = 'border-top:1px solid ' . $palette['border'] . ';'
. 'border-bottom:1px solid ' . $palette['border'] . ';'
. 'border-top-right-radius:' . $card_corner_radius . 'px;'
. 'border-bottom-right-radius:' . $card_corner_radius . 'px;';
} else {
$avatar_extra .= 'border-bottom:1px solid ' . $palette['border'] . ';';
$content_extra .= 'border-bottom:1px solid ' . $palette['border'] . ';';
}
$parts = $date_parts($fact);
@@ -477,13 +472,24 @@ $event_row = static function (
. 'box-shadow:0 0 0 4px ' . $palette['bg'] . ';"></span>'
: '<span style="display:inline-block;width:14px;margin-left:-31px;margin-right:14px;vertical-align:middle;"></span>';
// When the dot is suppressed, also drop the day+month (it's
// the same as the row above) and show only the year — a touch
// larger than the always-visible year so it reads on its own.
if ($show_dot) {
$date_html =
'<span style="display:inline-block;vertical-align:middle;">'
. '<div style="font-weight:600;font-size:13px;letter-spacing:0.12em;color:'
. $palette['ink'] . ';">' . e($parts['day_month']) . '</div>'
. '<div style="font-weight:300;font-size:11px;color:'
. $palette['mute'] . ';margin-top:1px;">' . e($parts['year']) . '</div>'
. '<div style="font-weight:400;font-size:13px;color:'
. $palette['ink3'] . ';margin-top:2px;">' . e($parts['year']) . '</div>'
. '</span>';
} else {
$date_html =
'<span style="display:inline-block;vertical-align:middle;'
. 'font-weight:400;font-size:14px;color:' . $palette['ink2'] . ';">'
. e($parts['year'])
. '</span>';
}
return '<tr>'
. '<td style="' . $avatar_cell_base . $avatar_extra . '">' . $record_avatars($fact) . '</td>'
@@ -493,10 +499,10 @@ $event_row = static function (
. '</tr>';
};
// Outer section table is transparent. Each event row contributes its
// own card-surfaced avatar+content TDs plus the timeline TD.
// Outer section table is transparent. border-spacing puts a 10px
// vertical gap between rows so each card stands on its own.
$card_open = '<table role="presentation" cellpadding="0" cellspacing="0" border="0" '
. 'style="width:100%;border-collapse:separate;border-spacing:0;">';
. 'style="width:100%;border-collapse:separate;border-spacing:0 10px;">';
$card_close = '</table>';
?><!doctype html>
@@ -554,8 +560,8 @@ $card_close = '</table>';
</p>
<?php if ($detailed !== []) : ?>
<?= $card_open ?>
<?php $prev_jd = null; $total = count($detailed); ?>
<?php foreach ($detailed as $i => $fact) : ?>
<?php $prev_jd = null; ?>
<?php foreach ($detailed as $fact) : ?>
<?php
$age = $upcoming_age($fact);
$body = '<span style="display:inline-block;vertical-align:middle;margin-right:12px;">' . $event_icon('BIRT') . '</span>'
@@ -565,7 +571,7 @@ $card_close = '</table>';
. '</span>';
$show_dot = ($fact->jd ?? 0) !== $prev_jd;
$prev_jd = $fact->jd ?? 0;
echo $event_row($fact, $body, $i === 0, $i === $total - 1, $show_dot);
echo $event_row($fact, $body, $show_dot);
?>
<?php endforeach ?>
<?= $card_close ?>
@@ -603,8 +609,8 @@ $card_close = '</table>';
</p>
<?php if ($detailed !== []) : ?>
<?= $card_open ?>
<?php $prev_jd = null; $total = count($detailed); ?>
<?php foreach ($detailed as $i => $fact) : ?>
<?php $prev_jd = null; ?>
<?php foreach ($detailed as $fact) : ?>
<?php
$age = $upcoming_age($fact);
$body = '<span style="display:inline-block;vertical-align:middle;margin-right:12px;">' . $event_icon('MARR') . '</span>'
@@ -614,7 +620,7 @@ $card_close = '</table>';
. '</span>';
$show_dot = ($fact->jd ?? 0) !== $prev_jd;
$prev_jd = $fact->jd ?? 0;
echo $event_row($fact, $body, $i === 0, $i === $total - 1, $show_dot);
echo $event_row($fact, $body, $show_dot);
?>
<?php endforeach ?>
<?= $card_close ?>
@@ -652,8 +658,8 @@ $card_close = '</table>';
</p>
<?php if ($detailed !== []) : ?>
<?= $card_open ?>
<?php $prev_jd = null; $total = count($detailed); ?>
<?php foreach ($detailed as $i => $fact) : ?>
<?php $prev_jd = null; ?>
<?php foreach ($detailed as $fact) : ?>
<?php
$kind = $event_kind($fact);
$body = '<span style="display:inline-block;vertical-align:middle;margin-right:12px;">' . $event_icon($kind) . '</span>'
@@ -663,7 +669,7 @@ $card_close = '</table>';
. '</span>';
$show_dot = ($fact->jd ?? 0) !== $prev_jd;
$prev_jd = $fact->jd ?? 0;
echo $event_row($fact, $body, $i === 0, $i === $total - 1, $show_dot);
echo $event_row($fact, $body, $show_dot);
?>
<?php endforeach ?>
<?= $card_close ?>