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
+45 -39
View File
@@ -431,11 +431,16 @@ $summary_item_style = 'padding:3px 0;';
// //
// $show_dot suppresses the dot on rows whose upcoming-day matches // $show_dot suppresses the dot on rows whose upcoming-day matches
// the previous row, so each calendar day has exactly one dot. // 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 ( $event_row = static function (
Fact $fact, Fact $fact,
string $body_html, string $body_html,
bool $is_first,
bool $is_last,
bool $show_dot, bool $show_dot,
) )
use ( use (
@@ -448,25 +453,15 @@ $event_row = static function (
$card_corner_radius, $card_corner_radius,
$palette, $palette,
): string { ): string {
$avatar_extra = ''; $avatar_extra = 'border-top:1px solid ' . $palette['border'] . ';'
$content_extra = ''; . 'border-bottom:1px solid ' . $palette['border'] . ';'
. 'border-top-left-radius:' . $card_corner_radius . 'px;'
. 'border-bottom-left-radius:' . $card_corner_radius . 'px;';
if ($is_first) { $content_extra = 'border-top: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-top-right-radius:' . $card_corner_radius . 'px;'
$content_extra .= 'border-top:1px solid ' . $palette['border'] . ';' . 'border-bottom-right-radius:' . $card_corner_radius . 'px;';
. 'border-top-right-radius:' . $card_corner_radius . 'px;';
}
if ($is_last) {
$avatar_extra .= 'border-bottom:1px solid ' . $palette['border'] . ';'
. 'border-bottom-left-radius:' . $card_corner_radius . 'px;';
$content_extra .= 'border-bottom:1px solid ' . $palette['border'] . ';'
. '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); $parts = $date_parts($fact);
@@ -477,13 +472,24 @@ $event_row = static function (
. 'box-shadow:0 0 0 4px ' . $palette['bg'] . ';"></span>' . '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>'; : '<span style="display:inline-block;width:14px;margin-left:-31px;margin-right:14px;vertical-align:middle;"></span>';
$date_html = // When the dot is suppressed, also drop the day+month (it's
'<span style="display:inline-block;vertical-align:middle;">' // the same as the row above) and show only the year — a touch
. '<div style="font-weight:600;font-size:13px;letter-spacing:0.12em;color:' // larger than the always-visible year so it reads on its own.
. $palette['ink'] . ';">' . e($parts['day_month']) . '</div>' if ($show_dot) {
. '<div style="font-weight:300;font-size:11px;color:' $date_html =
. $palette['mute'] . ';margin-top:1px;">' . e($parts['year']) . '</div>' '<span style="display:inline-block;vertical-align:middle;">'
. '</span>'; . '<div style="font-weight:600;font-size:13px;letter-spacing:0.12em;color:'
. $palette['ink'] . ';">' . e($parts['day_month']) . '</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>' return '<tr>'
. '<td style="' . $avatar_cell_base . $avatar_extra . '">' . $record_avatars($fact) . '</td>' . '<td style="' . $avatar_cell_base . $avatar_extra . '">' . $record_avatars($fact) . '</td>'
@@ -493,10 +499,10 @@ $event_row = static function (
. '</tr>'; . '</tr>';
}; };
// Outer section table is transparent. Each event row contributes its // Outer section table is transparent. border-spacing puts a 10px
// own card-surfaced avatar+content TDs plus the timeline TD. // vertical gap between rows so each card stands on its own.
$card_open = '<table role="presentation" cellpadding="0" cellspacing="0" border="0" ' $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>'; $card_close = '</table>';
?><!doctype html> ?><!doctype html>
@@ -554,8 +560,8 @@ $card_close = '</table>';
</p> </p>
<?php if ($detailed !== []) : ?> <?php if ($detailed !== []) : ?>
<?= $card_open ?> <?= $card_open ?>
<?php $prev_jd = null; $total = count($detailed); ?> <?php $prev_jd = null; ?>
<?php foreach ($detailed as $i => $fact) : ?> <?php foreach ($detailed as $fact) : ?>
<?php <?php
$age = $upcoming_age($fact); $age = $upcoming_age($fact);
$body = '<span style="display:inline-block;vertical-align:middle;margin-right:12px;">' . $event_icon('BIRT') . '</span>' $body = '<span style="display:inline-block;vertical-align:middle;margin-right:12px;">' . $event_icon('BIRT') . '</span>'
@@ -565,7 +571,7 @@ $card_close = '</table>';
. '</span>'; . '</span>';
$show_dot = ($fact->jd ?? 0) !== $prev_jd; $show_dot = ($fact->jd ?? 0) !== $prev_jd;
$prev_jd = $fact->jd ?? 0; $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 ?> <?php endforeach ?>
<?= $card_close ?> <?= $card_close ?>
@@ -603,8 +609,8 @@ $card_close = '</table>';
</p> </p>
<?php if ($detailed !== []) : ?> <?php if ($detailed !== []) : ?>
<?= $card_open ?> <?= $card_open ?>
<?php $prev_jd = null; $total = count($detailed); ?> <?php $prev_jd = null; ?>
<?php foreach ($detailed as $i => $fact) : ?> <?php foreach ($detailed as $fact) : ?>
<?php <?php
$age = $upcoming_age($fact); $age = $upcoming_age($fact);
$body = '<span style="display:inline-block;vertical-align:middle;margin-right:12px;">' . $event_icon('MARR') . '</span>' $body = '<span style="display:inline-block;vertical-align:middle;margin-right:12px;">' . $event_icon('MARR') . '</span>'
@@ -614,7 +620,7 @@ $card_close = '</table>';
. '</span>'; . '</span>';
$show_dot = ($fact->jd ?? 0) !== $prev_jd; $show_dot = ($fact->jd ?? 0) !== $prev_jd;
$prev_jd = $fact->jd ?? 0; $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 ?> <?php endforeach ?>
<?= $card_close ?> <?= $card_close ?>
@@ -652,8 +658,8 @@ $card_close = '</table>';
</p> </p>
<?php if ($detailed !== []) : ?> <?php if ($detailed !== []) : ?>
<?= $card_open ?> <?= $card_open ?>
<?php $prev_jd = null; $total = count($detailed); ?> <?php $prev_jd = null; ?>
<?php foreach ($detailed as $i => $fact) : ?> <?php foreach ($detailed as $fact) : ?>
<?php <?php
$kind = $event_kind($fact); $kind = $event_kind($fact);
$body = '<span style="display:inline-block;vertical-align:middle;margin-right:12px;">' . $event_icon($kind) . '</span>' $body = '<span style="display:inline-block;vertical-align:middle;margin-right:12px;">' . $event_icon($kind) . '</span>'
@@ -663,7 +669,7 @@ $card_close = '</table>';
. '</span>'; . '</span>';
$show_dot = ($fact->jd ?? 0) !== $prev_jd; $show_dot = ($fact->jd ?? 0) !== $prev_jd;
$prev_jd = $fact->jd ?? 0; $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 ?> <?php endforeach ?>
<?= $card_close ?> <?= $card_close ?>