  /* SPDX-License-Identifier: AGPL-3.0-or-later */
  /* Item card: one shape for anything the journal can point at (summary,
     category, dream category, favorite, person, place, project). Spec:
     docs/design_handoff_card/README.md. The root is .item-card because
     .card is already the plain panel under dreams, patterns and triage; the
     parts keep the handoff's names so the Figma layers can mirror them:

       article.item-card[.sm|.lg][.horizontal|.vertical]
         a.card-visual      glyph, aria-hidden, tabindex=-1
         div.card-body
           div.card-type    eyebrow
           a.card-title     the one tab stop
           p.card-desc      plain text, never inside a link
           div.card-badges > span.badge.card-badge × n, span.card-more "+N"

     md is the default size and has no class. Width fills the grid track
     (.card-row); height is fixed per size, so long content clamps instead of
     stretching the card. Below 670px every card goes horizontal unless it
     is pinned .vertical. Built by static/js/card.js. */

  /* ---- vertical (md) ---- */
  .item-card {
    display: flex; flex-direction: column; overflow: hidden;
    width: 100%; min-width: 13rem; height: 19rem;
    background: var(--bg-raised); border: 1px solid var(--border-default);
    border-radius: var(--radius-lg); color: var(--text-default);
  }
  .card-visual {
    flex: none; height: 7rem;
    display: flex; align-items: center; justify-content: center;
    background: var(--bg-muted); border-bottom: 1px solid var(--border-default);
    color: var(--text-accent); font: italic 2.4rem/1 var(--font-body);
    transition: background-color var(--dur-hover) ease;
  }
  .card-visual:hover { background: var(--card-thumb-hover); color: var(--text-accent); }
  .card-body {
    flex: 1; min-height: 0; display: flex; flex-direction: column;
    gap: .35rem; padding: .8rem .9rem .85rem;
  }
  .card-type {
    font: 600 var(--font-3xs)/1.3 var(--font-ui);
    letter-spacing: .1em; text-transform: uppercase; color: var(--text-accent-muted);
  }
  .card-title {
    font: 700 1rem/1.25 var(--font-body); color: var(--text-default);
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; border-radius: 2px;
    transition: color var(--dur-hover) ease;
  }
  .card-title:hover { color: var(--text-accent); }
  .card-title:focus-visible { outline: 2px solid var(--text-accent); outline-offset: 2px; }
  .card-desc {
    margin: 0; font: var(--font-sm)/1.45 var(--font-body); color: var(--text-muted);
    user-select: text; cursor: text;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  }
  /* pinned to the bottom, one row, never wraps: a badge that doesn't fit
     gets an ellipsis rather than being cut off */
  .card-badges { margin-top: auto; display: flex; gap: .3rem; overflow: hidden; }
  /* each badge is a .badge (components.css): fill, rule, pill, type and the
     ellipsis come from there; the card only sizes it per card size */
  .card-badge { flex: 0 1 auto; min-width: 0; }
  .card-more {
    flex: none; font: var(--font-2xs)/1.4 var(--font-ui); color: var(--text-muted);
    padding: .1rem .3rem; white-space: nowrap; font-variant-numeric: tabular-nums;
  }

  /* ---- sm: no description, two badges ---- */
  .item-card.sm { min-width: 9.5rem; height: 12rem; }
  .item-card.sm .card-visual { height: 5rem; font-size: 1.8rem; }
  .item-card.sm .card-body { gap: .3rem; padding: .6rem .7rem .65rem; }
  .item-card.sm .card-type { font-size: .68rem; }
  .item-card.sm .card-title { font-size: .9rem; }
  .item-card.sm .card-desc { display: none; }
  .item-card.sm .card-badges { gap: var(--space-1); }
  .item-card.sm :is(.card-badge, .card-more) { font-size: .68rem; padding-block: .05rem; }
  .item-card.sm .card-badge { padding-inline: .45rem; }

  /* ---- lg: four-line description, four badges ---- */
  .item-card.lg { min-width: 18rem; height: 24.5rem; }
  .item-card.lg .card-visual { height: 9.5rem; font-size: 3.2rem; }
  .item-card.lg .card-body { gap: var(--space-2); padding: 1rem 1.1rem 1.05rem; }
  .item-card.lg .card-title { font-size: var(--font-lg); }
  .item-card.lg .card-desc { font-size: .92rem; line-height: 1.5; -webkit-line-clamp: 4; }
  .item-card.lg .card-badges { gap: .35rem; }
  .item-card.lg :is(.card-badge, .card-more) { font-size: var(--font-xs); }
  .item-card.lg .card-badge { padding-inline: .55rem; }

  /* ---- horizontal: visual left, one-line title ----
     Forced with .horizontal at any width (lists, side panels); every card
     not pinned .vertical takes the same shape below 670px. The two blocks
     are the same declarations: a media query can't share a selector list
     with a class. md and lg share one shape; sm has its own. */
  .item-card.horizontal { flex-direction: row; min-width: 0; height: 8.5rem; }
  .item-card.horizontal .card-visual {
    width: 7rem; height: auto; font-size: 2.2rem;
    border-bottom: 0; border-right: 1px solid var(--border-default);
  }
  .item-card.horizontal .card-body { min-width: 0; gap: var(--space-1); padding: .7rem .9rem; }
  .item-card.horizontal .card-type { font-size: .68rem; }
  .item-card.horizontal .card-title {
    font-size: 1rem; display: block; white-space: nowrap; text-overflow: ellipsis;
  }
  .item-card.horizontal .card-desc { font-size: var(--font-sm); line-height: 1.4; -webkit-line-clamp: 2; }
  .item-card.horizontal .card-badges { gap: .3rem; }
  .item-card.horizontal :is(.card-badge, .card-more) { font-size: .72rem; padding-block: .05rem; }
  .item-card.horizontal .card-badge { padding-inline: .5rem; }
  .item-card.horizontal.sm { height: 5.75rem; }
  .item-card.horizontal.sm .card-visual { width: 5rem; font-size: 1.7rem; }
  .item-card.horizontal.sm .card-body { padding: .6rem .8rem; }
  .item-card.horizontal.sm .card-title { font-size: .95rem; }

  @media (max-width: 669px) {
    .item-card:not(.vertical) { flex-direction: row; min-width: 0; height: 8.5rem; }
    .item-card:not(.vertical) .card-visual {
      width: 7rem; height: auto; font-size: 2.2rem;
      border-bottom: 0; border-right: 1px solid var(--border-default);
    }
    .item-card:not(.vertical) .card-body { min-width: 0; gap: var(--space-1); padding: .7rem .9rem; }
    .item-card:not(.vertical) .card-type { font-size: .68rem; }
    .item-card:not(.vertical) .card-title {
      font-size: 1rem; display: block; white-space: nowrap; text-overflow: ellipsis;
    }
    .item-card:not(.vertical) .card-desc { font-size: var(--font-sm); line-height: 1.4; -webkit-line-clamp: 2; }
    .item-card:not(.vertical) .card-badges { gap: .3rem; }
    .item-card:not(.vertical) :is(.card-badge, .card-more) { font-size: .72rem; padding-block: .05rem; }
    .item-card:not(.vertical) .card-badge { padding-inline: .5rem; }
    .item-card.sm:not(.vertical) { height: 5.75rem; }
    .item-card.sm:not(.vertical) .card-visual { width: 5rem; font-size: 1.7rem; }
    .item-card.sm:not(.vertical) .card-body { padding: .6rem .8rem; }
    .item-card.sm:not(.vertical) .card-title { font-size: .95rem; }
  }

  /* ---- the row: the layout contract ----
     The track floor matches the card's min-width, so a 46rem column holds
     4 sm, 3 md or 2 lg, and 72rem holds 6, 5 or 3. One column below 670px,
     or md and lg would still sit two-up there. */
  .card-row { display: grid; gap: var(--space-6); grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); }
  .card-row.sm { grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); }
  .card-row.lg { grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); }
  @media (max-width: 669px) {
    .card-row, .card-row.sm, .card-row.lg { grid-template-columns: minmax(0, 1fr); }
  }
