/* ============================================================
   components/cards.css — .dd-cards, a deck of cards that
   compare the same rows, read one card at a time (#112).

   **This is a layout over `.dd-card`, not a second card.** The
   surface, its radius, its shadow and `.dd-card__title` are
   `card.css`'s and stay there; everything here is the deck, the
   sizing it needs, the label/value rows and the arrows below.

   Built for the blog's `cards` block and deliberately not
   blog-shaped: anything that answers the same questions about
   several things reaches for this instead of growing a table
   nobody can read on a phone.

   Markup contract:

     <div class="dd-cards" data-dd-cards>
       <ul class="dd-cards__deck" data-dd-cards-deck tabindex="0">
         <li class="dd-card">
           <div class="dd-cards__head">
             <span class="dd-cards__num">1.</span>
             <h3 class="dd-card__title">…</h3>
           </div>
           <dl class="dd-cards__rows">
             <dt class="dd-cards__label">…</dt>
             <dd class="dd-cards__value">…</dd>
           </dl>
           <a class="dd-cards__link" href="…">…</a>
         </li>
       </ul>
       <div class="dd-cards__nav" data-dd-cards-nav hidden>
         <button data-dd-cards-step="-1">…</button>
         <p class="dd-cards__count"><span data-dd-cards-at>1</span> / 6</p>
         <button data-dd-cards-step="1">…</button>
       </div>
     </div>

   **One card fills the host, and the deck pages through them.**
   A card is `100%` of the column rather than a fixed width: the
   owner's call, 2026-09-08 — a strip of narrow cards did not use
   the space, and a stage worth four rows of explanation is worth
   the reader's whole attention while they are on it. Reading
   *across* still works, because every card lands in the same box
   at the same size and the rows line up between one card and the
   next.

   **It is a scroller, not a slideshow.** Every card stays in the
   DOM and in the accessibility tree; the arrows drive
   `scrollTo`, and with no JS the deck is scrolled by hand and
   loses nothing but the arrows. `components.js` un-hides the
   nav and keeps the count.

   `tabindex="0"` on the deck is not optional: a card may carry
   no link, so without it there is nothing inside to tab to and
   no way to scroll the region without a pointer.
   ============================================================ */

.dd-cards {
  margin-block: var(--space-8, 40px);
  width: auto;
}

.dd-cards__deck {
  display: flex;
  gap: var(--space-4, 16px);
  align-items: stretch;
  overflow-x: auto;
  /* Mandatory rather than proximity: a deck read one card at a time should
     never come to rest showing two halves. */
  scroll-snap-type: x mandatory;
  /* The scrollbar is furniture on a control that has arrows and a count. */
  scrollbar-width: none;
  /* The list is the layout; its bullets and indents are not. */
  list-style: none;
  margin: 0;
  /* Room for the cards' own shadow, which a scroller otherwise clips. */
  padding: var(--space-1, 4px) 0 var(--space-3, 12px);
}

.dd-cards__deck::-webkit-scrollbar {
  display: none;
}

.dd-cards__deck:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: var(--radius-lg);
}

/* Deck-scoped sizing on the kit's card surface. Nothing here restyles
   `.dd-card` itself — a card in a deck is the same card, in a row. */
.dd-cards .dd-card {
  flex: 0 0 100%;
  /* `flex-basis: 100%` alone still lets a long card grow past the host, which
     re-introduces the horizontal drift snapping is there to remove. */
  max-width: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  display: flex;
  flex-direction: column;
  padding: var(--space-5, 20px);
}

/* ---- the head: number, title, then the rule ---------------------
   The rule runs *after* the title rather than in place of it (owner,
   2026-09-08). It is `::after` on the head and takes the slack, so it
   reaches the card's edge whatever the title's length. */
.dd-cards__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-2, 8px);
  margin: 0 0 var(--space-4, 16px);
}

.dd-cards__head::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--border);
  /* Baseline alignment would sit the rule on the text baseline; this drops it
     to the middle of the line box, where a rule between words belongs. */
  align-self: center;
}

.dd-cards__num {
  font-family: var(--font-mono);
  font-size: var(--fs-label, 13px);
  color: var(--text-muted);
  flex: 0 0 auto;
}

.dd-cards .dd-card__title {
  font-size: var(--fs-body, 17px);
  margin: 0;
  flex: 0 0 auto;
}

.dd-cards__rows {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3, 12px);
  /* The rows take the slack, so the link stays pinned to the bottom of every
     card however long its neighbours are. */
  flex: 1 1 auto;
}

.dd-cards__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label, 13px);
  letter-spacing: 0.02em;
  color: var(--text-muted);
  margin: 0;
}

.dd-cards__value {
  margin: 0;
  font-size: var(--fs-small, 15px);
  line-height: 1.55;
}

/* Bullets are the common case on a deck: three of them scan where a sentence
   has to be read. Tight, hanging, and marked with the brand dot rather than a
   browser disc. */
.dd-cards__bullets {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2, 8px);
}

.dd-cards__bullets li {
  position: relative;
  padding-left: var(--space-4, 16px);
}

.dd-cards__bullets li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

.dd-cards__link {
  margin-top: var(--space-5, 20px);
  font-family: var(--font-mono);
  font-size: var(--fs-label, 13px);
  color: var(--link);
}

.dd-cards__link::after {
  content: " →";
}

/* ---- the arrows, below the deck ---------------------------------
   Centred under the card rather than flanking it: the card is the whole
   column, so there is no room beside it, and a control under the thing it
   moves is where a reader's thumb already is on a phone. */
.dd-cards__nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4, 16px);
  margin-top: var(--space-3, 12px);
}

/* The nav ships `hidden` and `components.js` clears it, so this is the whole
   no-JS story: without it the `display` above wins and a reader with no script
   gets two arrows that do nothing (conventions.md §3). */
.dd-cards__nav[hidden] {
  display: none;
}

/* An arrow that cannot go anywhere says so rather than disappearing — a
   control that vanishes moves the two beside it. */
.dd-cards__arrow[disabled] {
  opacity: 0.35;
  cursor: default;
  transform: none;
}

.dd-cards__count {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-label, 13px);
  color: var(--text-muted);
  /* The count changes width between "1" and "10"; a fixed minimum stops the
     arrows stepping sideways as the reader pages. */
  min-width: 4ch;
  text-align: center;
}
