Documentation Index
Fetch the complete documentation index at: https://docs.fanfare.io/llms.txt
Use this file to discover all available pages before exploring further.
Styling
The Fanfare SDK provides multiple approaches to customize widget appearance, from CSS variables to scoped styles and container classes.
CSS Custom Properties
All widgets use CSS custom properties for styling, making them easy to customize:
:root {
/* Colors */
--fanfare-primary: #3b82f6;
--fanfare-primary-hover: #2563eb;
--fanfare-primary-foreground: #ffffff;
--fanfare-background: #ffffff;
--fanfare-foreground: #1f2937;
--fanfare-muted: #f3f4f6;
--fanfare-muted-foreground: #6b7280;
--fanfare-border: #e5e7eb;
--fanfare-destructive: #ef4444;
--fanfare-success: #22c55e;
--fanfare-warning: #f59e0b;
/* Typography */
--fanfare-font-family: system-ui, -apple-system, sans-serif;
--fanfare-font-size-xs: 0.75rem;
--fanfare-font-size-sm: 0.875rem;
--fanfare-font-size-base: 1rem;
--fanfare-font-size-lg: 1.125rem;
--fanfare-font-size-xl: 1.25rem;
/* Spacing */
--fanfare-spacing-xs: 0.25rem;
--fanfare-spacing-sm: 0.5rem;
--fanfare-spacing-md: 1rem;
--fanfare-spacing-lg: 1.5rem;
--fanfare-spacing-xl: 2rem;
/* Border Radius */
--fanfare-radius: 0.5rem;
--fanfare-radius-sm: 0.25rem;
--fanfare-radius-lg: 0.75rem;
--fanfare-radius-full: 9999px;
/* Shadows */
--fanfare-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--fanfare-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
--fanfare-shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
}
Target specific widgets using their tag names:
/* Style only the queue widget */
fanfare-queue-widget {
--fanfare-primary: #8b5cf6;
--fanfare-radius: 1rem;
}
/* Style only the auction widget */
fanfare-auction-widget {
--fanfare-primary: #ef4444;
--fanfare-radius: 0;
}
/* Style only the draw widget */
fanfare-draw-widget {
--fanfare-primary: #10b981;
--fanfare-radius: 0.75rem;
}
Container Classes
Add custom classes to widget containers:
<fanfare-queue-widget queue-id="queue_123" container-class="my-custom-widget premium-style" />
.my-custom-widget {
max-width: 400px;
margin: 0 auto;
padding: 1rem;
}
.premium-style {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 1rem;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
}
Shadow DOM Considerations
Widgets are built with SolidJS and may use Shadow DOM encapsulation. To ensure your styles apply:
Using CSS Variables (Recommended)
CSS variables pierce Shadow DOM boundaries:
/* This will work even with Shadow DOM */
fanfare-queue-widget {
--fanfare-primary: #8b5cf6;
}
Using ::part() Selectors
Widgets expose parts for styling:
fanfare-queue-widget::part(card) {
border: 2px solid var(--fanfare-primary);
}
fanfare-queue-widget::part(button) {
font-weight: 700;
text-transform: uppercase;
}
fanfare-queue-widget::part(title) {
font-size: 1.5rem;
}
Layout Integration
Responsive Container
function ResponsiveWidget() {
return (
<div className="widget-container">
<fanfare-queue-widget queue-id="queue_123" />
</div>
);
}
.widget-container {
width: 100%;
max-width: 480px;
margin: 0 auto;
padding: 1rem;
}
@media (max-width: 640px) {
.widget-container {
padding: 0.5rem;
}
}
Grid Layout
function WidgetGrid() {
return (
<div className="widget-grid">
<fanfare-queue-widget queue-id="queue_1" />
<fanfare-draw-widget draw-id="draw_1" />
<fanfare-auction-widget auction-id="auction_1" />
</div>
);
}
.widget-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1.5rem;
padding: 1rem;
}
Animation Customization
Transition Timing
fanfare-experience-widget {
--fanfare-transition-duration: 200ms;
--fanfare-transition-timing: ease-in-out;
}
Loading Animation
/* Custom loading spinner */
fanfare-queue-widget::part(spinner) {
border-color: var(--fanfare-primary);
border-top-color: transparent;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
State Transitions
/* Smooth state changes */
fanfare-queue-widget::part(content) {
transition:
opacity 200ms ease,
transform 200ms ease;
}
fanfare-queue-widget[data-status="loading"]::part(content) {
opacity: 0.5;
transform: scale(0.98);
}
Brand Examples
Blue Theme
:root {
--fanfare-primary: #3b82f6;
--fanfare-primary-hover: #2563eb;
--fanfare-background: #ffffff;
--fanfare-foreground: #1e3a5f;
}
Purple Theme
:root {
--fanfare-primary: #8b5cf6;
--fanfare-primary-hover: #7c3aed;
--fanfare-background: #faf5ff;
--fanfare-foreground: #581c87;
}
Green Theme
:root {
--fanfare-primary: #10b981;
--fanfare-primary-hover: #059669;
--fanfare-background: #ecfdf5;
--fanfare-foreground: #064e3b;
}
Dark Theme
:root {
--fanfare-primary: #60a5fa;
--fanfare-primary-hover: #3b82f6;
--fanfare-background: #1f2937;
--fanfare-foreground: #f9fafb;
--fanfare-muted: #374151;
--fanfare-border: #4b5563;
}
Z-Index Management
Widgets respect your z-index stacking context:
/* Ensure widget modals appear above your content */
fanfare-experience-widget {
--fanfare-z-modal: 1000;
--fanfare-z-overlay: 999;
}
Print Styles
@media print {
fanfare-queue-widget,
fanfare-draw-widget,
fanfare-auction-widget {
display: none;
}
}
/* Or show a static version */
@media print {
fanfare-queue-widget::part(actions) {
display: none;
}
fanfare-queue-widget::part(card) {
box-shadow: none;
border: 1px solid #000;
}
}
Accessibility Considerations
Focus Styles
fanfare-queue-widget::part(button):focus-visible {
outline: 2px solid var(--fanfare-primary);
outline-offset: 2px;
}
High Contrast Mode
@media (prefers-contrast: high) {
fanfare-queue-widget {
--fanfare-border: #000000;
--fanfare-foreground: #000000;
--fanfare-background: #ffffff;
}
}
Reduced Motion
@media (prefers-reduced-motion: reduce) {
fanfare-experience-widget {
--fanfare-transition-duration: 0ms;
}
fanfare-queue-widget::part(spinner) {
animation: none;
}
}