{"version":3,"file":"Chat.module.cjs","names":[],"sources":["../../../src/components/Chat/Chat.module.css"],"sourcesContent":[".panel {\n    display: flex;\n    flex-direction: column;\n    min-width: 0;\n    min-height: 0;\n    height: var(--tempest-chat-height, 100%);\n    background-color: var(--tempest-bg);\n    color: var(--tempest-text);\n    font-family: var(--tempest-font-sans);\n}\n\n.header {\n    flex: 0 0 auto;\n    padding: var(--tempest-space-3) var(--tempest-space-4);\n    border-bottom: 1px solid var(--tempest-border);\n}\n\n.thread {\n    display: flex;\n    flex: 1 1 auto;\n    flex-direction: column;\n    gap: var(--tempest-space-3);\n    min-height: 0;\n    padding: var(--tempest-space-4);\n    overflow-y: auto;\n    overscroll-behavior: contain;\n}\n\n.thread:focus-visible {\n    outline: 2px solid var(--tempest-primary);\n    outline-offset: -2px;\n}\n\n.day {\n    display: flex;\n    align-items: center;\n    gap: var(--tempest-space-3);\n}\n\n.day::before,\n.day::after {\n    flex: 1 1 auto;\n    height: 1px;\n    background-color: var(--tempest-border);\n    content: \"\";\n}\n\n.dayLabel {\n    color: var(--tempest-text-subtle);\n    font-size: var(--tempest-text-xs);\n    text-transform: capitalize;\n}\n\n.run {\n    display: flex;\n    gap: var(--tempest-space-3);\n    align-items: flex-start;\n    max-width: 100%;\n}\n\n/*\n * Own messages mirror the row instead of moving to a second column: the avatar,\n * the name and the bubbles keep the same source order, so a screen reader still\n * reads \"who, then what\" while the eye reads it from the other side.\n */\n.ownRun {\n    flex-direction: row-reverse;\n}\n\n.avatar {\n    flex: 0 0 auto;\n}\n\n.runBody {\n    display: flex;\n    flex-direction: column;\n    gap: var(--tempest-space-1);\n    min-width: 0;\n    max-width: min(78%, 42rem);\n}\n\n.ownRun .runBody {\n    align-items: flex-end;\n}\n\n.author {\n    color: var(--tempest-text-muted);\n    font-size: var(--tempest-text-xs);\n    font-weight: var(--tempest-weight-medium);\n}\n\n.bubbles {\n    display: flex;\n    flex-direction: column;\n    gap: var(--tempest-space-1);\n    margin: 0;\n    padding: 0;\n    list-style: none;\n}\n\n.bubbleRow {\n    display: flex;\n    align-items: center;\n    gap: var(--tempest-space-2);\n}\n\n.ownRun .bubbleRow {\n    flex-direction: row-reverse;\n}\n\n.bubble {\n    display: flex;\n    flex-direction: column;\n    gap: var(--tempest-space-1);\n    min-width: 0;\n    padding: var(--tempest-space-2) var(--tempest-space-3);\n    border: 1px solid var(--tempest-border);\n    border-radius: var(--tempest-radius-lg);\n    background-color: var(--tempest-surface);\n    font-size: var(--tempest-text-sm);\n    line-height: var(--tempest-leading-normal);\n}\n\n.ownBubble {\n    border-color: transparent;\n    background-color: var(--tempest-primary-soft);\n    color: var(--tempest-primary-on-soft);\n}\n\n/*\n * A failed message keeps its text readable and states the failure at the border\n * and in the meta row. Tinting the whole bubble danger-red would make the message\n * itself hard to read — and re-reading it is exactly what somebody does before\n * deciding to retry.\n */\n.failedBubble {\n    border-color: var(--tempest-danger);\n    background-color: var(--tempest-danger-bg);\n    color: var(--tempest-text);\n}\n\n.body {\n    overflow-wrap: anywhere;\n    white-space: pre-wrap;\n}\n\n/*\n * The timestamp uses the muted token, not the subtle one, and switches to the\n * bubble's own foreground when the bubble is tinted.\n *\n * `--tempest-text-subtle` is solved against the page and surface backgrounds. On\n * `--tempest-primary-soft` it is a different composite, and the real browser\n * measured it below the 4.5:1 text floor — the same trap the syntax tokens hit.\n * Size is what de-emphasises the meta row here; colour still has to pass.\n */\n.meta {\n    display: flex;\n    align-items: center;\n    justify-content: flex-end;\n    gap: var(--tempest-space-2);\n    color: var(--tempest-text-muted);\n    font-size: var(--tempest-text-2xs);\n    font-variant-numeric: tabular-nums;\n}\n\n.ownBubble .meta {\n    color: var(--tempest-primary-on-soft);\n}\n\n.status {\n    display: inline-flex;\n    align-items: center;\n}\n\n.statusFailed {\n    color: var(--tempest-danger);\n    font-weight: var(--tempest-weight-bold);\n}\n\n/*\n * A bubble row carries more than a bubble now: the actions button sits beside it\n * and the reaction chips hang under it, so the row wraps and the chips are given\n * the whole width to fall onto.\n */\n.bubbleRow {\n    flex-wrap: wrap;\n}\n\n.reactions {\n    display: flex;\n    flex-basis: 100%;\n    flex-wrap: wrap;\n    gap: var(--tempest-space-1);\n    margin: 0;\n    padding: 0;\n    list-style: none;\n}\n\n.ownRun .reactions {\n    justify-content: flex-end;\n}\n\n.reaction {\n    display: inline-flex;\n    align-items: center;\n    gap: var(--tempest-space-1);\n    padding: 0 var(--tempest-space-2);\n    border: 1px solid var(--tempest-border);\n    border-radius: var(--tempest-radius-full, 999px);\n    background-color: var(--tempest-surface);\n    color: var(--tempest-text);\n    font: inherit;\n    font-size: var(--tempest-text-xs);\n    line-height: 1.8;\n    cursor: pointer;\n}\n\n.reaction:disabled {\n    cursor: default;\n}\n\n/*\n * Your own reaction is marked by a tinted chip and its own foreground, never by\n * `--tempest-text-subtle` over the tint: that token is solved against the page\n * background and fails the text floor on a tinted surface.\n */\n.reactionMine {\n    border-color: transparent;\n    background-color: var(--tempest-primary-soft);\n    color: var(--tempest-primary-on-soft);\n    font-weight: var(--tempest-weight-medium);\n}\n\n/*\n * The ⋮ button is always in the DOM — on touch there is no hover to reveal it,\n * and a control that only appears on hover is a control a phone does not have.\n * A fine pointer gets it faded until the row is hovered or it is focused.\n */\n.actionsButton {\n    flex: 0 0 auto;\n    padding: 0 var(--tempest-space-1);\n    border: none;\n    background: none;\n    color: var(--tempest-text-muted);\n    font: inherit;\n    line-height: 1;\n    cursor: pointer;\n}\n\n@media (hover: hover) and (pointer: fine) {\n    .actionsButton {\n        opacity: 0;\n        transition: var(--tempest-transition-opacity, opacity 120ms ease);\n    }\n\n    .bubbleRow:hover .actionsButton,\n    .actionsButton:focus-visible {\n        opacity: 1;\n    }\n}\n\n/* The reply stub: a tinted strip with a bar on the side it is anchored to. */\n.quote {\n    display: flex;\n    flex-direction: column;\n    gap: 2px;\n    width: 100%;\n    padding: var(--tempest-space-1) var(--tempest-space-2);\n    border-left: 3px solid var(--tempest-primary);\n    border-radius: var(--tempest-radius-sm);\n    background-color: var(--tempest-surface-2);\n    color: var(--tempest-text);\n    font-size: var(--tempest-text-xs);\n    text-align: left;\n}\n\n.quoteButton {\n    border-top: none;\n    border-right: none;\n    border-bottom: none;\n    font: inherit;\n    font-size: var(--tempest-text-xs);\n    cursor: pointer;\n}\n\n/*\n * The author of a quote is text, so it is coloured like text.\n *\n * `--tempest-primary` here measured **4.35:1** against `--tempest-surface-2` in a\n * real browser — below the 4.5:1 floor for a 12px label, and invisible to the\n * jsdom axe sweep, which disables `color-contrast` because nothing is painted.\n * The brand still marks the quote: it is the bar down the side, which is a\n * non-text indicator and only owes 3:1.\n */\n.quoteAuthor {\n    color: var(--tempest-text);\n    font-weight: var(--tempest-weight-medium);\n}\n\n.quoteText {\n    overflow: hidden;\n    display: -webkit-box;\n    -webkit-box-orient: vertical;\n    -webkit-line-clamp: 2;\n    line-clamp: 2;\n    overflow-wrap: anywhere;\n}\n\n/*\n * A revoked quote reads as absent, which is the point: the text of a deleted\n * message must not survive inside the reply to it.\n */\n.quoteRevoked {\n    color: var(--tempest-text-muted);\n    font-style: italic;\n}\n\n.tombstone {\n    display: flex;\n    align-items: center;\n    gap: var(--tempest-space-1);\n    color: var(--tempest-text-muted);\n    font-style: italic;\n}\n\n.deletedBubble {\n    border-style: dashed;\n    background-color: transparent;\n}\n\n.edited {\n    font-style: italic;\n}\n\n/* Read by everyone is the only state that turns the ticks. */\n.statusRead {\n    color: var(--tempest-info, var(--tempest-primary));\n}\n\n.attachments {\n    display: flex;\n    flex-direction: column;\n    gap: var(--tempest-space-1);\n    max-width: 320px;\n}\n\n/* Holds the row's height while the attachments chunk is still loading. */\n.attachmentsFallback {\n    min-height: var(--tempest-space-8, 2rem);\n}\n\n.imageAttachment {\n    padding: 0;\n    border: none;\n    border-radius: var(--tempest-radius-md);\n    background: none;\n    line-height: 0;\n    cursor: pointer;\n}\n\n.imageAttachment img {\n    max-width: 100%;\n    max-height: 260px;\n    border-radius: var(--tempest-radius-md);\n    object-fit: cover;\n}\n\n.videoAttachment {\n    max-width: 100%;\n    border-radius: var(--tempest-radius-md);\n}\n\n.voiceAttachment {\n    display: flex;\n    flex-direction: column;\n    gap: var(--tempest-space-1);\n}\n\n/*\n * The waveform is the difference between a voice note and a grey rectangle: it\n * is what tells somebody whether this is a word or a two-minute monologue.\n */\n.waveform {\n    display: flex;\n    align-items: flex-end;\n    gap: 2px;\n    height: 28px;\n}\n\n.waveform span {\n    flex: 1 1 auto;\n    min-width: 2px;\n    border-radius: 1px;\n    background-color: var(--tempest-primary);\n    opacity: 0.7;\n}\n\n.fileAttachment {\n    display: flex;\n    flex-direction: column;\n    gap: 2px;\n    padding: var(--tempest-space-2);\n    border: 1px solid var(--tempest-border);\n    border-radius: var(--tempest-radius-md);\n    color: var(--tempest-text);\n    text-decoration: none;\n}\n\n.fileName {\n    overflow-wrap: anywhere;\n    font-weight: var(--tempest-weight-medium);\n}\n\n.fileMeta {\n    color: var(--tempest-text-muted);\n    font-size: var(--tempest-text-2xs);\n    font-variant-numeric: tabular-nums;\n}\n\n.retry {\n    padding: 0;\n    border: none;\n    background: none;\n    color: var(--tempest-danger);\n    font: inherit;\n    font-size: var(--tempest-text-xs);\n    text-decoration: underline;\n    cursor: pointer;\n}\n\n.typing {\n    flex: 0 0 auto;\n    margin: 0;\n    padding: 0 var(--tempest-space-4) var(--tempest-space-2);\n    color: var(--tempest-text-subtle);\n    font-size: var(--tempest-text-xs);\n}\n\n.composer {\n    display: flex;\n    flex: 0 0 auto;\n    align-items: flex-end;\n    gap: var(--tempest-space-2);\n    padding: var(--tempest-space-3) var(--tempest-space-4);\n    border-top: 1px solid var(--tempest-border);\n}\n\n.field {\n    flex: 1 1 auto;\n    min-width: 0;\n    padding: var(--tempest-space-2) var(--tempest-space-3);\n    border: 1px solid var(--tempest-border);\n    border-radius: var(--tempest-radius-md);\n    background-color: var(--tempest-bg);\n    color: inherit;\n    font: inherit;\n    font-size: var(--tempest-text-sm);\n    line-height: var(--tempest-leading-normal);\n    resize: none;\n}\n\n.field:focus-visible {\n    outline: 2px solid var(--tempest-primary);\n    outline-offset: -1px;\n}\n\n.field:disabled {\n    background-color: var(--tempest-surface-2);\n    color: var(--tempest-text-subtle);\n    cursor: not-allowed;\n}\n\n.composerActions {\n    display: flex;\n    align-items: center;\n    gap: var(--tempest-space-2);\n}\n\n.send {\n    padding: var(--tempest-space-2) var(--tempest-space-4);\n    border: none;\n    border-radius: var(--tempest-radius-md);\n    background-color: var(--tempest-primary);\n    color: var(--tempest-primary-foreground);\n    font: inherit;\n    font-size: var(--tempest-text-sm);\n    font-weight: var(--tempest-weight-medium);\n    cursor: pointer;\n}\n\n.send:disabled {\n    background-color: var(--tempest-surface-3);\n    color: var(--tempest-text-subtle);\n    cursor: not-allowed;\n}\n\n@media (max-width: 480px) {\n    .runBody {\n        max-width: 88%;\n    }\n}\n"],"mappings":";"}