import { css } from 'lit';
/**
* Shared host styles every component pulls in. Sets default font, color,
* container query support, and the entry fade-in.
*/
export const baseStyles = css`
:host {
display: block;
container-type: inline-size;
font-family: var(
--roxy-font-sans,
system-ui,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
sans-serif
);
color: var(--roxy-fg, #0a0a0a);
background: transparent;
font-size: var(--roxy-text-base, 1rem);
line-height: var(--roxy-leading-normal, 1.5);
animation: roxy-fade-in var(--roxy-motion-duration, 200ms)
var(--roxy-motion-easing, cubic-bezier(0.4, 0, 0.2, 1)) both;
}
/**
* Opt out of the component's own card surface. When the embedder already
* wraps the component in their own card, set the \`bare\` attribute to drop
* the painted background + shadow so there is no nested card chrome. The
* inner border stays a hairline; override --roxy-border to remove it too.
*/
:host([bare]) {
--roxy-surface: transparent;
--roxy-shadow-sm: none;
--roxy-shadow-md: none;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
/* Every component result heading and the self-fetch form title read the
* display-font token. It defaults to --roxy-font-sans, so this is a no-op for
* existing consumers; a preset that sets --roxy-font-display (the practitioner
* theme ships a serif) restyles every heading in one token with no per-component
* markup change. */
h1,
h2,
h3,
h4 {
font-family: var(
--roxy-font-display,
var(
--roxy-font-sans,
system-ui,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
sans-serif
)
);
}
@keyframes roxy-fade-in {
from {
opacity: 0;
transform: translateY(2px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (prefers-reduced-motion: reduce) {
:host {
animation: none;
}
}
.roxy-skeleton {
background: linear-gradient(
90deg,
var(--roxy-border, #e4e4e7) 0%,
color-mix(in srgb, var(--roxy-border, #e4e4e7) 60%, transparent) 50%,
var(--roxy-border, #e4e4e7) 100%
);
background-size: 200% 100%;
animation: roxy-shimmer 1.4s ease-in-out infinite;
border-radius: var(--roxy-radius-md, 8px);
}
@keyframes roxy-shimmer {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
@media (prefers-reduced-motion: reduce) {
.roxy-skeleton {
animation: none;
}
}
/* Removed from the visual layout but kept in the accessibility tree. The data
* tables use it on their
so a screen-reader user hears what the
* table holds before the first cell, while the rendered card is unchanged.
* Out of flow, 1px and clipped, so it can never shift or widen its parent. */
.roxy-sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: 0;
padding: 0;
border: 0;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
.roxy-empty {
padding: var(--roxy-space-lg, 1.5rem);
color: var(--roxy-muted, #71717a);
text-align: center;
font-size: var(--roxy-text-sm, 0.875rem);
}
.roxy-error {
display: grid;
gap: var(--roxy-space-sm, 0.5rem);
justify-items: start;
padding: var(--roxy-space-lg, 1.5rem);
background: var(--roxy-surface, #fff);
border: 1px solid var(--roxy-danger, #dc2626);
border-radius: var(--roxy-radius-md, 8px);
color: var(--roxy-danger-fg, #991b1b);
font-size: var(--roxy-text-sm, 0.875rem);
}
:host(:focus-within) .roxy-card {
outline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));
outline-offset: 2px;
}
/* Credit line under a self-fetch or auto-mount result (never controlled mode). */
.roxy-attribution {
margin-top: var(--roxy-space-sm, 0.5rem);
font-size: var(--roxy-text-xs, 0.75rem);
color: var(--roxy-muted, #71717a);
text-align: right;
}
.roxy-attribution a {
color: inherit;
text-decoration: none;
}
.roxy-attribution a:hover {
color: var(--roxy-accent-ink, #b45309);
text-decoration: underline;
}
.roxy-attribution a:focus-visible {
outline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));
outline-offset: 2px;
}
/* Re-query affordance above a self-fetch result (uncontrolled mode only). */
.roxy-edit-bar {
display: flex;
justify-content: flex-end;
margin-bottom: var(--roxy-space-sm, 0.5rem);
}
.roxy-edit {
padding: var(--roxy-space-xs, 0.25rem) var(--roxy-space-md, 1rem);
background: none;
border: 1px solid var(--roxy-border, #e4e4e7);
border-radius: var(--roxy-radius-md, 8px);
color: var(--roxy-fg, #0a0a0a);
font-family: inherit;
font-size: var(--roxy-text-sm, 0.875rem);
cursor: pointer;
}
.roxy-edit:hover {
border-color: var(--roxy-accent, #f59e0b);
color: var(--roxy-accent-ink, #b45309);
}
.roxy-edit:focus-visible {
outline: 2px solid var(--roxy-ring, rgba(245, 158, 11, 0.4));
outline-offset: 2px;
}
/* Force the text-style variant on every Unicode glyph in the component.
* macOS and iOS substitute coloured emoji glyphs for the planetary and
* gender Unicode code points (Mars, Venus, Mercury, etc.) when the
* system colour-emoji font wins font selection. The text-style variant
* keeps glyphs monochrome so they inherit the surrounding fill colour
* and match the brand palette consistently across platforms.
*
* font-variant-emoji is part of CSS Fonts 4 (Safari 17+, Chrome 134+,
* Firefox 139+). On older browsers the rule is silently ignored.
*/
:host {
font-variant-emoji: text;
}
`;