/*
Card

Builds on @elements/style's .card family (.card, .card-head, .card-body,
.card-foot) and keeps its look: a surface with a soft rule under the
header and a tinted footer. Adds shadcn's parts (title, description, an
action at the header's top right), two sizes, and one spacing variable
every part pads with.

  .card.ui-card              the surface, padded parts from --card-spacing
  .card.ui-card.is-sm        --surface-padding-sm
  .card-head                 grid: title and description, action at right
  .card-title / .card-description / .card-action
  .card-body / .card-foot
  .card-bleed                content that runs edge to edge
  .card > img                media that runs edge to edge
*/

@layer components {

.card.ui-card {
  --card-spacing: var(--surface-padding);

  display:        flex;
  flex-direction: column;
  min-width:      0;
  border-width:   var(--surface-border-width);
  border-radius:  var(--radius-surface);
  color:          var(--ink);
  font-size:      var(--text-ui);
}

.card.ui-card.is-sm {
  --card-spacing: var(--surface-padding-sm);
}

.ui-card > .card-head {
  display:               grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-auto-rows:        auto;
  align-items:           start;
  column-gap:            var(--surface-gap);
  row-gap:               var(--space-1);
  padding:               var(--card-spacing);
}

.ui-card > .card-head > :not(.card-action) {
  grid-column: 1;
}

.ui-card > .card-body {
  padding: var(--card-spacing);
}

/* A body right under a header with no rule between them would double the
   padding; the header's rule stays, so the spacing stays even. */

.ui-card > .card-foot {
  display:         flex;
  flex-wrap:       wrap;
  align-items:     center;
  justify-content: flex-end;
  gap:             var(--space-2);
  padding:         calc(var(--card-spacing) * 0.75) var(--card-spacing);
  margin-top:      auto;
}

.ui-card > .card-foot.is-start {
  justify-content: flex-start;
}

.ui-card > .card-foot.is-stack {
  flex-direction:  column;
  align-items:     stretch;
}

.card-title {
  margin:         0;
  font-family:    var(--font-heading);
  font-size:      var(--text-title);
  font-weight:    var(--weight-strong);
  letter-spacing: var(--tracking-heading);
  line-height:    var(--leading-heading);
  color:          var(--ink);
  overflow-wrap:  anywhere;
}

/* shadcn steps the title down a size in a small card. */
.card.ui-card.is-sm .card-title {
  font-size: var(--text-ui);
}

.card-description {
  margin:      0;
  color:       var(--ink-soft);
  font-size:   var(--text-ui);
  line-height: var(--leading-body);
  overflow-wrap: anywhere;
}

.card-action {
  grid-column:  2;
  grid-row:     1 / span 2;
  align-self:   start;
  justify-self: end;
  display:      flex;
  align-items:  center;
  gap:          var(--space-2);
}

.ui-card > img,
.ui-card > picture,
.ui-card > video,
.ui-card > .aspect-ratio {
  display:    block;
  width:      100%;
  object-fit: cover;
}

.card-bleed {
  margin-inline: calc(var(--card-spacing) * -1);
}

.ui-card > .card-body > .card-bleed:first-child {
  margin-top: calc(var(--card-spacing) * -1);
}

.ui-card > .card-body > .card-bleed:last-child {
  margin-bottom: calc(var(--card-spacing) * -1);
}

/* A focusable bleed (a scrolling box is a tab stop) is flush with the
   card's edges, where the card clips its overflow and the footer meets it,
   so an outer ring would be cut off. Its ring is drawn inside the edge.
   The transparent outline is what forced colors paints once it drops the
   box-shadow; its negative offset keeps it inside the edge too. */
.card-bleed:focus-visible {
  outline:        var(--focus-ring-width) solid transparent;
  outline-offset: calc(var(--focus-ring-width) * -1);
  box-shadow:     inset 0 0 0 var(--focus-ring-width) var(--focus);
}

}
