/* The card face — ours now, not fizzy's.
   ==========================================================================

   What this file used to be: fizzy's `cards/display/_preview` anatomy, ported
   whole — a 900-weight title at `--text-xx-large`, six facts in caps ruled by
   crosshair hairlines, an author avatar on the left and assignees on the
   right, a tinted fill and the warm `--shadow`.

   HANSHI 05 rules a card differently, and reference/05-boards-cards.png draws
   it: *name, value, owner, at most one state chip, plus the dotted-circle
   comment count — the only other mark a card may carry*. Rebuilt to that on
   2026-08-29 (user: "use that fully", on the design canvas that proposed it).

   Four of the six pieces are components the app already ships — `.byline`,
   `.badge`, `.comment-count`, `.avatar` — so what is left here is the card's
   own identity and nothing else: the frame, the name, and the circle that
   says who holds it. */
@layer components {
  /* Base
  /* ------------------------------------------------------------------------ */

  /* The face: paper, and the column's hue as one hairline and nothing else.
     The fill stays paper: HANSHI's first colour rule is to default to none,
     and a paper card on the column's 5% wash is what makes it read as an
     object — Basecamp's move, and the reference sheet's. The project page's
     miniature board draws its cards with the same face (dock.css). No
     shadow: HANSHI reserves the one warm --shadow for things that float, and
     a card on a board is not floating — the hairline is the whole edge. */
  .card,
  .dock-tool__face {
    --card-border-color: color-mix(in srgb, var(--card-color) 25%, var(--color-canvas));

    background-color: var(--color-canvas);
    border: var(--border-size) solid var(--card-border-color);
    border-radius: var(--border-radius);
  }

  .card {
    /* The block padding is a fixed rem and not a half token, for buttons.css's
       reason: a component's own size is its own, never the hosting surface's
       density. The inline padding is text-relative, because the card is a
       reading surface. */
    --card-padding-block: 0.75rem;
    --card-padding-inline: var(--inline-space-double);

    display: flex;
    flex-direction: column;
    gap: var(--card-gap, var(--block-space-half));
    inline-size: 100%;
    padding: var(--card-padding-block) var(--card-padding-inline);
    text-align: start;
    position: relative;
    z-index: 1;

    /* The one thing hover does: the hairline takes more of the column's hue.
       Nothing appears or disappears, so nothing transitions (HANSHI 07). */
    &:where(:hover, :focus-within) {
      --card-border-color: color-mix(in srgb, var(--card-color) 55%, var(--color-canvas));
    }
  }

  /* Name
  /* ------------------------------------------------------------------------ */

  /* Weight and spacing carry the hierarchy here, not size and colour — which
     is why this is `--text-normal` at 500 rather than fizzy's `1.6em` at 900,
     a weight the app uses nowhere else. */
  .card__title {
    --lines: 3; /* the clamp utility's parameter — three lines, like fizzy */

    /* The stretched link covers the card; the title must not stand in front of
       it. This used to be said by card-columns.css, for the board only, which
       left the title dead to a click on every other surface that draws a face
       — the column's own page, the moment it stacked them (2026-08-29). It is
       the card's own rule wherever the card is. */
    pointer-events: none;

    font-size: var(--card-title-size, var(--text-normal));
    font-weight: 500;
    line-height: 1.35;
    color: var(--color-ink);
  }

  /* Compact
  /* ------------------------------------------------------------------------ */

  /* A pipeline's card (crm-v2, the compact pass): a board of a hundred deals
     reads at a row's measure — a list row's padding, the name at the small
     size and two lines at most. What it says under the name is the same size
     in the subtle ink: weight and ink carry the hierarchy, not size (HANSHI,
     Type), indented past the mark so every line starts at the name. */
  .card--compact {
    --card-padding-block: 0.5rem;
    --card-padding-inline: var(--inline-space);
    --card-gap: 0.125rem;
    --card-title-size: var(--text-small);

    .card__title {
      --lines: 2;
    }
  }

  .card__meta {
    padding-inline-start: calc(1.25rem + var(--inline-space-half));
    font-size: var(--text-small);
    color: var(--color-ink-subtle);
  }

  /* Names only: a board read as who is where, each card one line — its mark,
     its name, its owner, and a straw dot where the next step is late. Said
     by the board's container, so a column a drop redraws keeps it. */
  .card__late {
    display: none;
    flex: none;
    align-self: center;
    inline-size: 0.375rem;
    block-size: 0.375rem;
    border-radius: 50%;
    background-color: var(--color-warning-ink);
  }

  .card-columns--names {
    .card {
      --card-padding-block: 0.3125rem;
      --avatar-size: 1.25rem;
    }

    .card__title {
      --lines: 1;
    }

    .card__meta {
      display: none;
    }

    .card__late {
      display: block;
    }
  }

  /* Owner
  /* ------------------------------------------------------------------------ */

  /* Nobody holds this card yet. The circle is a `.btn--circle` in every
     respect but its edge — dashed, which is already this app's invitation
     mark: the to-do intake row wears it (todo-form.css) and so does the ping
     strip. It is drawn at rest rather than on hover so that unclaimed work is
     countable down a column without sweeping the pointer, and so that it
     exists at all on a touch screen.

     Sized as the avatar it stands in for — `.btn--circle` is 1.75rem and so is
     `.avatar` — so the card's right edge does not shift when someone takes it.

     The border is a SHORTHAND on purpose: `.btn` declares `border:` too, and a
     dashed longhand under a later shorthand is how every ghost circle in the
     app once rendered solid (todo-form.css records that one). */
  .card__claim {
    border: 1.5px dashed var(--color-line);

    &:hover {
      border-color: var(--color-ink-light);
    }

    /* The plus arrives with the pointer. At rest the ring alone says the card
       is free, which is what keeps a column of unheld cards quiet; something
       appears, so it earns the quick speed (HANSHI 07). */
    .icon {
      opacity: 0;
      transition: opacity var(--speed-quick) var(--ease-out);
    }

    &:where(:hover, :focus-visible) .icon,
    .card:hover & .icon {
      opacity: 1;
    }
  }

  /* The touch case — where the plus does not wait for a hover that will never
     come — is hover-reveals.css, with every other control that waits for a
     pointer. The finger room needs no rule anywhere: `.card__claim` is a
     `.btn` with an aria-label and an icon, so it already matches the halo
     buttons.css grows out to --tap-target-size on the same devices. */

  /* Misc bits
  /* ------------------------------------------------------------------------ */

  /* Above the content, not beneath it (2026-08-29). It was `z-index: -1` here
     and raised to 1 inside a board column, because the board needs the whole
     card as a drag handle. Off the board that left the card unclickable
     everywhere it had words: a negative-z child paints above the card's
     background but below every in-flow descendant, so the title row swallowed
     the pointer and only the padding opened the card. One value, one place —
     the only things that must beat the link are the controls, and they say so
     just below. */
  .card__link {
    content: "";
    inset: 0;
    position: absolute;
    z-index: 1;
  }

  /* A control in the card has to out-paint the stretched link. Same rule and
     same reason as `.bucket-card`: unpositioned content paints BELOW a
     positioned overlay however late it comes, and it fails only in a real
     browser, and only on whichever control was added last. */
  .card :is(.btn, button) {
    position: relative;
    z-index: 2;
  }
}
