shredbx logo
shredbx shredbx shredbx shredbx Personal
  • Home
  • Lab
  • Portfolio
  • Experience
  • Services
  • Profile
  • Contact
AClaude
  • Home
  • Lab
  • Portfolio
  • Experience
  • Services
  • Profile
  • Contact
Andrei Solovev
Knowledge
Search knowledge... ⌘K
Knowledge · Rules · Process

Component Import Standard

Rules for importing UI components and animations from HTML prototypes into SBX component library

Andrei Solovev

Tags

rule

Overview

Purpose

Rules for importing UI components and animations from HTML prototypes into SBX component library

Rules

IMP-001: Copy the EXACT HTML structure, CSS values, and JS behavior from the prototype. Never approximate, never "reimplement in a different way". If the prototype uses CSS :hover on a parent element, the Svelte component uses CSS :hover on a parent element. If the prototype uses clip-path: polygon(0 0, 100% 0, 100% 35%, 0 65%), the component uses the same polygon values.

IMP-002: For CSS-driven effects (clip-path, transitions, transforms), create a Svelte component (.svelte file) that renders the exact prototype DOM structure with scoped CSS. Do NOT create a Svelte action that manipulates DOM via JavaScript unless the prototype itself requires JS (e.g., rAF animations, IntersectionObserver). Rationale: Actions recreate DOM programmatically and attach events to the wrong elements. Components render the correct DOM from the template and use CSS :hover which naturally scopes to the correct parent.

IMP-003: The hover activation zone MUST match the prototype exactly. - If prototype uses .brand-line-1:hover to trigger effects, the component's parent element is the hover zone. - NEVER attach hover to the animated element itself (e.g., "bx" span) when the prototype attaches hover to the line container. - Each line is an independent hover zone unless prototype groups them.

IMP-004: ALL CSS values must be copied exactly from the prototype: - Easing: cubic-bezier(0.23, 1, 0.32, 1) — not 0.22, not 0.36 - Duration: 0.5s — not 500ms approximation with different feel - Distances: translate(-16px, -14px) — not "d * 0.875" - Colors: #ef4444, #22d3ee — not #ff0040, #00ffff - Clip-paths: exact polygon values Read the prototype CSS, copy the values. Do not invent.

IMP-005: When two clip-path layers meet (e.g., top 50% / bottom 50%), add 1% overlap on the top layer to prevent sub-pixel rendering seams: - Top: polygon(0 0, 100% 0, 100% 51%, 0 51%) [+1% overlap] - Bottom: polygon(0 50%, 100% 50%, 100% 100%, 0 100%) [unchanged]

THEME-001: ALL components MUST use CSS custom properties from the brand CSS. NEVER use --color-surface, --color-surface-2, --color-surface-3 — these are NOT defined in the brand CSS and will fall back to hardcoded dark values, breaking light mode. Allowed variables (defined in brand.generated.css for both light and dark): --color-bg page background (#ffffff / #0a0a0b) --color-bg-secondary card/surface bg (#f6f8fa / #141415) --color-bg-tertiary nested surface (#ffffff / #1a1a1b) --color-text primary text (#1f2328 / #eeeff1) --color-text-muted secondary text (#656d76 / #8b8b90) --color-text-disabled disabled text (#8c959f / #555) --color-border borders (#d0d7de / #2a2a2d) --color-accent brand red (#e5392b) When copying from prototype, replace: background: #141415 → background: var(--color-bg-secondary) background: #1a1a2e → background: var(--color-bg-secondary) background: #0c0c0d → background: var(--color-bg-secondary) color: #8b8b90 → color: var(--color-text-muted) border-color: #2a2a2d → border-color: var(--color-border)

THEME-002: CSS var fallbacks MUST NOT be dark-only. If a fallback is needed, use a var chain: var(--color-bg-secondary, #141415) is acceptable but var(--color-surface, #141415) is NOT because --color-surface is undefined and the dark fallback always wins. WRONG: background: var(--color-surface, #1a1a2e) RIGHT: background: var(--color-bg-secondary) RIGHT: background: var(--color-bg-secondary, #141415)

PREVIEW-001: Every component MUST be wired into ALL 3 preview layers (Decision #0219): 1. component-meta.ts — COMPONENT_META entry with render strategy + stage class Declares how ComponentPreviewShell renders the component in both card (listing thumbnail) and demo (detail page) modes. File: preview-registry/component-meta.ts 2. preview-registry/index.ts — previewRegistry entry (if strategy = 'registry') Dynamic import + props function + optional wrapperClass. NOT needed for: text-animation, background-action, branded, custom, label, snippet, multi-instance (these are handled directly by ComponentPreviewShell). 3. registry.yml — demo_modes + component_meta + layers items EVERY slug MUST have explicit entries in all three sections. Missing any of these = component import is INCOMPLETE. NOTE: CardPreview.svelte and ComponentDemo.svelte no longer exist. ComponentPreviewShell.svelte replaced both (PR #135, Decision #0219).

PREVIEW-002: Every component slug MUST have an explicit entry in registry.yml demo_modes. There is no "default" mode. The mapping: theme-split → PreviewSplit (light/dark side-by-side) Use for: text animations, text blocks, branding, buttons, cards, tooltips, stacks, link-previews — anything CSS-var based theme-tabs → PreviewFull (auto/light/dark tab switcher) Use for: backgrounds, hero-backgrounds, navigation, hero-sections, landing blocks, video headers — wide/full-width components Rule of thumb: - Uses CSS vars for colors/text → theme-split - Wide or section-level → theme-tabs

PREVIEW-003: ComponentPreviewShell uses strategy-based dispatch (Decision #0219). Each component declares its render strategy in component-meta.ts: registry — standard components, loaded via previewRegistry map text-animation — text effects, rendered via shared TextAnimationCard background-action — bg animations, mounted via Svelte action or static component snippet — components requiring Svelte snippet children (static dispatch) multi-instance — components shown as list of N instances branded — site-specific branding components custom — one-off components with unique demo logic label — non-visual utilities, shows icon label only Strategy also implies a default CardFrame (browser, component, canvas, label, snippet). Override via card_frame field when needed — e.g., sections use card_frame: 'browser' for traffic-light chrome wrapper.

PREVIEW-004: Every component card MUST render actual visual content in the listing grid. A blank card or fallback text means the component was NOT properly wired. For each new component: - Add COMPONENT_META entry in component-meta.ts (strategy + stage) - Add previewRegistry entry in index.ts (if strategy = registry) - Add fixture data to _fixtures.ts if the component needs props - Verify the listing page shows a visual thumbnail, not a blank card

SEQ-001: Import ONE effect, validate it visually in the browser, get user confirmation, then proceed to the next. Never batch-import multiple effects.

SEQ-002: After importing an effect: 1. Build: `sbx build --platform svelte --dir <app-dir>` 2. Dev server: `sbx run --dir <app-dir>` (already running → HMR picks up changes automatically; do NOT use `sbx infra rebuild` — that is Docker/deploy-only, never for dev) 3. Navigate to LISTING page → verify thumbnail renders (not fallback text) 4. Navigate to DETAIL page → verify: a. Component renders correctly b. Theme switcher works (PreviewSplit or PreviewFull) c. Light mode: text readable, backgrounds adapt, borders visible d. Dark mode: same check 5. Take screenshot (playwright browser_take_screenshot) 6. Compare visually with the prototype 7. User confirms or reports issues 8. Fix issues before moving to next effect

SEQ-003: Only import effects explicitly requested by the user. Never create effects that don't exist in the prototype source files. If an effect name doesn't map to a specific prototype section, ask the user which prototype it comes from.

ARCH-001: Components go in the package by category: animations/ → text effects, background animations, scroll reveals cards/ → card components (classic, editorial, HUD, etc.) sections/ → page sections (hero, timeline, sidebar nav, video headers) text-blocks/ → terminal block, protocol block, stat headline, manifesto tooltips/ → hover-triggered tooltip variants stacks/ → overlapping stack, glowing circle stack link-previews/ → link preview, split preview interactive/ → CTAs, border effects (mouse-following, double, rainbow) blocks/ → hobby card, and other composite blocks Base path: projects/sbx/packages/core/svelte/src/lib/components/ Import via: @sbx/core-ui/components/{category}/{Name}.svelte

ARCH-002: Component props map to the prototype's CSS custom properties or configurable values: - text: string (the text content to animate) - duration: string (default from prototype --dur) - easing: string (default from prototype --ease-out) - distance: number (default from prototype hover transform values) Do NOT invent props that don't exist in the prototype (e.g., "intensity", "channelOffset", "blendMode" when the prototype doesn't parameterize these).

ARCH-003: Text animation components use the 'text-animation' render strategy, which renders via TextAnimationCard with 3 preview labels by default: 1. "shredbx" — "bx" highlighted red+weight 900, only "bx" animated 2. "eXperimental Lab" — "X" highlighted red+weight 900, only "X" animated 3. Configurable plain word — no highlight, entire word animated This is the default for ALL text animation components. Background animations use the 'background-action' strategy (full-area render with trigger: 'load').

ARCH-004: Imported components (animations, cards, tooltips, text-blocks, interactive, stacks, link-previews, blocks) use the preview-registry pattern: - component-meta.ts → COMPONENT_META entry (render strategy + stage) - preview-registry/index.ts → previewRegistry entry (component + props) - registry.yml → demo_modes + component_meta + layers items Do NOT create .presenter.ts files for imported components. The presenter pattern (IPresenter interface) is for IDE/design-tool components (blocks/, sections/panels, primitives/) that participate in the prop editor system. Component preview configuration lives in the preview-registry and component-meta metadata, not in per-component presenter files.

REG-001: Add a component to registry.yml and nav-tree.yml ONLY after it has been visually validated in the browser. Never register a component that hasn't been confirmed working.

REG-002: Registry entry is minimal: layer, category, item slug. No status overrides, no metadata, no variant lists. Status is always "draft" until user promotes.

REG-003: Every slug in registry.yml MUST have a corresponding entry in demo_modes. After adding a slug to any items list, IMMEDIATELY add it to demo_modes. The demo_mode determines which preview wrapper the detail page uses. Omitting it = the component has no theme switcher = broken import.

shredbx logo shredbx shredbx shredbx shredbx Andrei Solovev

Solution Architect & Lead Software Engineer

ExperiencePortfolioResearch & ExperimentsEducationCertificationSkills
GitHub ↗LinkedIn ↗Email ↗
AVAILABLE FOR NEW PROJECTS
// MY LATEST BEATS
Hobby & Interests

Lab

  • The Lab
  • Framework
  • Components
  • Packages
  • Games
  • Process (SDLC)
  • Knowledge
  • Blog

Andrei

  • Portfolio
  • Experience
  • Services
  • Profile
  • Contact
  • Lifestyle

Team

  • Team
  • Andrei
  • Claude

Legal

  • Privacy
  • Terms
  • Cookies
© 2026 shredbx.com. All rights reserved. — Andrei Solovev |