feat Align accordion indicators on a chevron

The logging accordion used plus and minus. The routine accordion used two text triangles. Both were CSS text, which a screen reader can include in the accessible name of the summary. Both accordions now share one chevron that CSS draws with borders, so it has no text. It points down when closed and turns to point up when open. The turn uses the same duration as the panel unfold, and reduced motion switches it off. A chevron is the strongest signal for "opens in place" in the NN/g accordion icon study. On the routine page, the chevron stays on the first row of the summary when the recovery status wraps below it.

Commit
7005b003b6b2253f6aa109ea71d0023295af5a49
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
lib/web/assets/hito.css
index 746001b6..d3ad7018 100644..100644
@@ -1124,12 +1124,25 @@
1124 1124 cursor: pointer;
1125 1125 list-style: none;
1126 1126 }
1127 Removed: .slot-accordion > summary::after {
1127 Added: /* The folding indicator is a chevron shared by every accordion. It is drawn
1128 Added: with borders, so it carries no text for a screen reader to announce. It
1129 Added: points down when closed and turns to point up when open. The turn uses the
1130 Added: same duration as the unfold. */
1131 Added: .slot-accordion > summary::after,
1132 Added: .routine-workout > summary::after {
1133 Added: flex: 0 0 auto;
1134 Added: align-self: center;
1135 Added: width: 0.55rem;
1136 Added: height: 0.55rem;
1128 1137 margin-left: auto;
1129 Removed: content: "+";
1130 Removed: color: var(--muted-ink);
1138 Added: border-right: 2px solid var(--muted-ink);
1139 Added: border-bottom: 2px solid var(--muted-ink);
1140 Added: content: "";
1141 Added: transform: rotate(45deg);
1142 Added: transition: transform var(--duration-base) ease;
1131 1143 }
1132 Removed: .slot-accordion[open] > summary::after { content: "−"; }
1144 Added: .slot-accordion[open] > summary::after,
1145 Added: .routine-workout[open] > summary::after { transform: rotate(-135deg); }
1133 1146 /* The summary's level-two heading is inline: the number, then the label. It
1134 1147 keeps the global h2 size. It resets only the default heading margin, so the
1135 1148 heading sits centered in the summary bar. */
@@ -1184,7 +1197,9 @@
1184 1197 .slot-panel-body { padding: 0 1rem 1rem; }
1185 1198 @media (prefers-reduced-motion: reduce) {
1186 1199 .slot-accordion::details-content,
1187 Removed: .routine-workout::details-content { transition: none; }
1200 Added: .routine-workout::details-content,
1201 Added: .slot-accordion > summary::after,
1202 Added: .routine-workout > summary::after { transition: none; }
1188 1203 }
1189 1204
1190 1205 /* The elapsed workout timer occupies the middle navigation slot while
@@ -1375,12 +1390,8 @@
1375 1390 padding: 0.8rem 1rem;
1376 1391 cursor: pointer;
1377 1392 }
1378 Removed: .routine-workout > summary::after {
1379 Removed: margin-left: auto;
1380 Removed: content: "▸";
1381 Removed: color: var(--muted-ink);
1382 Removed: }
1383 Removed: .routine-workout[open] > summary::after { content: "▾"; }
1393 Added: /* The chevron stays on the first row when the recovery status wraps below. */
1394 Added: .routine-workout > summary::after { order: 1; }
1384 1395 .routine-day {
1385 1396 margin: 0;
1386 1397 font-size: var(--font-size-h3);
@@ -1394,6 +1405,7 @@
1394 1405 font-weight: 600;
1395 1406 }
1396 1407 .routine-recovery {
1408 Added: order: 2;
1397 1409 flex-basis: 100%;
1398 1410 color: var(--muted-ink);
1399 1411 font-size: 0.92rem;