vojo/src/app/features/bots/AiChatPrivacy.css.ts

163 lines
4.9 KiB
TypeScript

import { style } from '@vanilla-extract/css';
import { color, config, toRem } from 'folds';
// DAWN `--amber` (stream-v2-dawn.jsx) — the "gold" accent the bridge widgets use for risk/notice
// callouts. folds has no amber token, and apps/widget-*/styles.css hardcode this same literal, so
// we match it here for the consent callout's gold frame.
const VOJO_GOLD = '#d4b88a';
// Centered privacy dialog — a fully self-styled card (NOT a folds modal recipe, whose fixed-rem
// sizing didn't give these caps and clipped the body in an earlier attempt). Owns its own surface,
// radius, border and shadow so the body fills the full width on every platform. Width caps at 520px
// (the modal width the removed widget's About panel used), shrinking to 90vw on phones.
export const DialogCard = style({
width: '90vw',
maxWidth: toRem(520),
maxHeight: '85vh',
display: 'flex',
flexDirection: 'column',
minHeight: 0,
overflow: 'hidden',
backgroundColor: color.Surface.Container,
borderRadius: config.radii.R400,
border: `${config.borderWidth.B300} solid ${color.Surface.ContainerLine}`,
boxShadow: '0 20px 60px rgba(0, 0, 0, 0.5)',
});
// Branded header: a fleet shield badge + title + one-line subtitle, then the close button. No
// bottom-border bar (that's what made it read as a generic cinny dialog) — the body's own spacing
// separates it.
export const Header = style({
flexShrink: 0,
display: 'flex',
alignItems: 'flex-start',
gap: config.space.S300,
padding: `${config.space.S400} ${config.space.S400} ${config.space.S300}`,
});
// Rounded-square fleet badge, same accent vocabulary as the bot avatars (BotShell.HeroAvatar).
export const HeaderBadge = style({
flexShrink: 0,
width: toRem(40),
height: toRem(40),
borderRadius: config.radii.R400,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: color.Primary.Container,
color: color.Primary.Main,
});
export const HeaderText = style({
flexGrow: 1,
minWidth: 0,
display: 'flex',
flexDirection: 'column',
gap: toRem(2),
paddingTop: toRem(2),
});
export const HeaderTitle = style({
fontSize: toRem(18),
fontWeight: 700,
lineHeight: toRem(22),
color: color.Surface.OnContainer,
});
export const HeaderSubtitle = style({
fontSize: toRem(13),
lineHeight: toRem(17),
color: color.SurfaceVariant.OnContainer,
opacity: 0.7,
});
// Folds `Scroll` owns the overflow + the app's thin, hover-revealed scrollbar styling (so it
// matches every other scroll surface). Here we only give it the flex sizing to fill the card's
// remaining height between the header and the bottom; minHeight:0 lets it shrink so it scrolls
// instead of pushing the card past its maxHeight.
export const BodyScroll = style({
flexGrow: 1,
minHeight: 0,
});
export const Body = style({
display: 'flex',
flexDirection: 'column',
gap: config.space.S500,
padding: `0 ${config.space.S400} ${config.space.S400}`,
});
export const SectionTitle = style({
fontSize: toRem(14),
fontWeight: 600,
color: color.Surface.OnContainer,
});
export const SectionBody = style({
fontSize: toRem(14),
lineHeight: toRem(21),
color: color.SurfaceVariant.OnContainer,
});
// "Using it = OK with this" — the consent line is the one binding sentence, so it gets the gold
// callout treatment the WhatsApp bridge uses for its ToS-risk notice (apps/widget-whatsapp
// `.about-warn-callout`): a gold FRAME + faint amber wash, but the text itself stays the normal
// readable colour — only the rim is gold, not the words.
export const Consent = style({
margin: 0,
padding: `${toRem(12)} ${toRem(14)}`,
borderRadius: toRem(8),
border: `1px solid ${VOJO_GOLD}`,
backgroundColor: 'rgba(212, 184, 138, 0.08)',
fontSize: toRem(13),
lineHeight: toRem(19),
color: color.Surface.OnContainer,
});
export const Links = style({
display: 'flex',
flexDirection: 'column',
gap: config.space.S200,
});
export const LearnMore = style({
fontSize: toRem(13),
color: color.SurfaceVariant.OnContainer,
opacity: 0.7,
});
// Clean provider link: a raised chip showing the provider name + the full URL verbatim, so the
// destination is explicit. fleet-tinted on hover/focus.
export const PolicyLink = style({
display: 'flex',
flexDirection: 'column',
gap: toRem(1),
padding: `${config.space.S200} ${config.space.S300}`,
borderRadius: config.radii.R400,
backgroundColor: color.SurfaceVariant.Container,
textDecoration: 'none',
selectors: {
'&:hover, &:focus-visible': {
backgroundColor: color.SurfaceVariant.ContainerHover,
outline: 'none',
},
},
});
export const LinkProvider = style({
fontSize: toRem(13),
fontWeight: 600,
color: color.Surface.OnContainer,
});
export const LinkUrl = style({
fontSize: toRem(12),
fontFamily: 'ui-monospace, "JetBrains Mono", "SF Mono", monospace',
color: color.Primary.Main,
wordBreak: 'break-all',
selectors: {
[`${PolicyLink}:hover &, ${PolicyLink}:focus-visible &`]: {
textDecoration: 'underline',
},
},
});