<details>/<summary> is the native solution and should be the default. This pattern is only needed when several panels must be open at once (radio instead of checkbox closes the others) or when a visual animation is needed that <details> can't deliver cleanly without interpolate-size.

The classic max-height trick (max-height: 0 → e.g. 600px) animates to a guessed fixed value, not the real content height — longer text gets cut off, or empty space is left over. 0fr → 1fr on grid-template-rows always animates exactly to the real height, no number-guessing required.

The checkbox stays focusable (only opacity:0, no display:none), the label has real text as its accessible name — no aria-hidden needed.