{
  "name": "EmailMessage",
  "type": "component",
  "description": "An email thread header row: a round author chip, a sender line and a recipient line.",
  "export": "@gtmi/strix-react/atoms/email-message",
  "path": "@gtmi/strix-react/atoms/email-message",
  "props": [
    {
      "name": "author",
      "type": "agent | me",
      "required": true,
      "description": "Who the row is about. Drives data-author and the default glyph, not the colours -- Figma's two variants are colour-identical."
    },
    {
      "name": "sender",
      "type": "ReactNode",
      "required": true,
      "description": "The sender line."
    },
    {
      "name": "recipient",
      "type": "ReactNode",
      "required": true,
      "description": "The recipient line."
    },
    {
      "name": "icon",
      "type": "ReactNode",
      "description": "The glyph in the chip. A slot, because Figma's agent glyph is the Twilio product mark and a design system cannot supply anyone else's brand."
    },
    {
      "name": "className",
      "type": "string",
      "description": "Merged through cn(), so a caller's utility wins."
    }
  ],
  "parts": [
    {
      "name": "email-message",
      "description": "Root, via data-slot. Also carries data-author."
    },
    {
      "name": "email-message-chip",
      "description": "The 32px round author chip, aria-hidden"
    },
    {
      "name": "email-message-glyph",
      "description": "The 16px glyph inside the chip"
    },
    {
      "name": "email-message-content",
      "description": "The two-line stack"
    },
    {
      "name": "email-message-sender",
      "description": "The sender line"
    },
    {
      "name": "email-message-recipient",
      "description": "The recipient line"
    }
  ],
  "ai_tags": ["email", "message", "sender", "recipient", "thread", "header", "avatar"],
  "since": "0.2.0",
  "figma": {
    "file": "zT3vGm4QlFEI2Jp9nxyFKI",
    "fileName": "Demo components library",
    "node": "22:5781",
    "component": ".email-message"
  },
  "tokens_used": [
    "--color-text-primary",
    "--color-text-secondary",
    "--color-icon-accent",
    "--color-surface-identity-chip",
    "--color-border-neutral-soft",
    "--spacing-gap-200",
    "--spacing-padding-vertical-sm",
    "--radius-2x-large"
  ],
  "notes": "THE AXIS IS COVERED ELSEWHERE; THE ROW IS NOT. That distinction is why this is its own component rather than a variant. ChatLog already generalised the author distinction into authorColor plus side, so no new axis is needed -- but a ChatLogMessageEntry is author + text on ONE line with no avatar slot and no second addressee line. This is a message HEADER (from X, to Y) rather than a line of conversation, and an email thread list is a different pattern from a chat log. Grafting an avatar slot and a recipient line onto a conversation primitive would widen it into a mail primitive, which is the objection the earlier decline recorded and which still stands -- what changed is that the row got its own home instead of no home.\n\nTHE AUTHOR AXIS CARRIES NO COLOUR AT ALL, AND THAT IS EVIDENCE RATHER THAN AN OMISSION. Both Figma variants paint both text lines gray-300, both paint the chip gray-850, both paint the glyph accesible-red-dark-theme, and both use the same border. The ONLY difference is which glyph sits in the chip. That directly supports the call ChatLog already made: cr-web-demo tinted the agent's name #F83D53 and the user's white, and ChatLog rejected both hardcoded hexes for a measured scale whose default is one ink for every author. Figma agrees more strongly than ChatLog does -- it does not tint the author at all. A test asserts both authors render identical class strings, so a per-author tint cannot creep back in.\n\nTHE GLYPH-ON-CHIP PAIRING IS THE ONE THAT MATTERS UNDER 1.4.11, because the glyph is the only thing distinguishing Agent from Me -- a non-text signal that must be perceivable. Figma's own is 3.84:1 on its chip and clears 3:1. It is measured here against the chip rather than against the page, because that is where it sits: a token has no contrast, a token on a named surface does.\n\nTHE CHIP FILL IS SUBSTITUTED, AND THE TEST PINS ITS OPACITY. Figma's gray-850 #191f36 is a near-black chip drawn for a #000d25 page -- 1.19:1 against that page even in the theme it was drawn for, and a dark hole in light mode. --color-surface-neutral-semi-medium is opaque in both themes (#f1f5ff / #232e47) and is the same fill ChannelAvatar gives its logo tile and ChannelMessage its business bubble, so an email header and the messages under it agree. A test asserts the fill resolves to an opaque hex in BOTH themes, because a translucent fill's composite depends on its backdrop and would make the glyph pairing above a fiction. Mutation-tested with --color-surface-primary, which is rgba() in dark: it fails and names the token and the theme.\n\nTHE TWO LINES ARE SEPARATED BY ROLE, NOT ONLY BY WEIGHT. Figma inks both gray-300 -- 7.43:1 on its dark page, 2.61:1 on a white one -- and leans entirely on one weight step at one size. Two text roles keep the hierarchy where hue does not read (a monochrome display, a user stylesheet), and the gray-300 literal does not survive inversion anyway.\n\nTHE RULE IS DECORATION, NOT A CONTROL BOUNDARY. Figma draws gray-800 at 1.39:1 against its page. A message row is not focusable and has no hover, pressed or disabled axis in the file, so WCAG 1.4.11's 3:1 does not apply and --color-border-control is NOT the remedy. The text inside it is what makes the row perceivable.\n\nThe 52px row is 8px of vertical padding around a 36px stack of two 18px lines, so unlike .badge the height is produced by padding plus the type ramp. Horizontal padding is spacing/none: the row bleeds to its container's edges.\n\nTHE AUTHOR CHIP IS FIGMA'S gray-850 NOW, AND THE SUBSTITUTION CITED AN AGREEMENT EVERY OTHER PARTY HAD ALREADY LEFT. It drew --color-surface-neutral-semi-medium #232e47, justified as \"the same fill ChannelAvatar gives its logo tile and ChannelMessage its business bubble, so an email header and the messages under it agree\". Rule 3 removed the light mode; ChannelMessage moved to --color-surface-field when its bubbles were reverted; ChannelAvatar's tile moved to Figma's gray-850 one wave earlier. Same substitution, same justification, second component — so the token is --color-surface-identity-chip, named for the treatment rather than for either atom. The 1.19:1 against the page is real and is NOT a conflict: a chip is not a control boundary, and 1.4.11 asks about the glyph on it, which is 16.27:1.\n\nNO ASSERTION PINNED THE CHIP'S FILL, which is why the substitution survived a full port of this atom. It was found by a stray #232e47 in the decoded pixels of Phone-email — the same way ChannelAvatar's was found in the four channel screens. There is a hex pin on it now."
}
