Section Components

Public page sections are explicit, registered Blade components.

Reusable public UI components should be prop-driven Blade components under:

resources/views/components/rrr

Use anonymous index components when a component has related child pieces:

resources/views/components/rrr/hero/index.blade.php
resources/views/components/rrr/hero/video.blade.php

These render as:

<x-rrr.hero />
<x-rrr.hero.video />

rrr components should not read SitePageSection models or section JSON directly. Public site section components should adapt stored data into explicit component props.

Component Conventions

Reusable rrr components should prefer Flux primitives for structure and controls:

<flux:heading />
<flux:text />
<flux:button />
<flux:icon />

Use semantic Tailwind color utilities backed by CSS variables wherever possible:

<section class="bg-surface">
    <flux:heading>
        {{ $heading }}
    </flux:heading>

    <flux:text class="text-muted">
        {{ $description }}
    </flux:text>
</section>

The color vocabulary should stay aligned with docs/brand-colors.md:

primary
secondary
info
success
warning
danger
surface
surface-muted
muted
border

The implementation order for reusable component styling is:

  1. Flux component variants when they express the intent.
  2. Semantic Tailwind utilities backed by platform CSS variables.
  3. Shared CSS classes when a utility does not exist yet.
  4. Inline style only as a temporary bridge or for truly dynamic values.

Let normal heading and body text inherit from the page or Flux default unless the component needs a deliberate color role such as text-muted or text-primary. Avoid hardcoded palette classes like text-zinc-950, dark:bg-zinc-950, or text-indigo-700 in reusable rrr components unless the color is intentionally not brandable. Avoid raw class-array configuration from data; expose clear props or enums instead.

The renderer lives in:

resources/views/components/site-section.blade.php

It maps a stored site_page_sections.type value to a known component. Do not render arbitrary component names from database values.

Current Section Types

intro_hero
powered_sites
splash_card
hero_image
person_feature
cta_card_grid
image_location
legal_content
contact_cta

Reusable Components

rrr.hero

<x-rrr.hero
    heading="Test Heading"
    description="Short supporting copy."
    heading-color="primary"
    :ctas="[
        [
            'label' => 'Start Here',
            'url' => '/start',
            'variant' => 'primary',
            'icon' => 'arrow-right',
            'iconPosition' => 'after',
        ],
        [
            'label' => 'Learn More',
            'url' => '/about',
            'variant' => 'outline',
            'icon' => 'information-circle',
            'iconPosition' => 'before',
        ],
    ]"
/>

Props:

heading
description
ctas
headingColor
descriptionColor

Color props are optional. If headingColor is not passed, the heading inherits the page or Flux default text color. descriptionColor defaults to muted. Allowed color roles are:

primary
secondary
info
success
warning
danger
muted

The ctas prop accepts up to two CTA arrays. Each CTA is passed to rrr.button and may contain:

label
url
variant
icon
iconPosition

label and url are required. variant accepts Flux button variants and defaults to outline. Pass primary explicitly when the CTA should use the primary/accent background. icon accepts a Flux icon name. iconPosition accepts before or after and defaults to before.

rrr.button

<x-rrr.button
    label="Get Started"
    url="/start"
    variant="primary"
    icon="arrow-right"
    icon-position="after"
/>

rrr.button is the shared CTA control for reusable sections. It delegates rendering, visual variants, dark mode, and icon sizing to Flux.

rrr.appearance-switch

Use the default component for Flux's documented light/dark toggle:

<x-rrr.appearance-switch />

Use the dropdown variant when the interface should expose light, dark, and system options:

<x-rrr.appearance-switch.dropdown />

Both components use Flux's built-in $flux.dark and $flux.appearance state directly.

Adding A Section Type

Add a section type in this order:

  1. Add a Blade component in resources/views/components/site-sections.
  2. Register the type in x-site-section.
  3. Add a Full Demo example in App\Services\SiteSandboxDemo.
  4. Seed at least one real page or sandbox test case when the section is part of the production foundation.
  5. Document the expected data shape here.

Data Rules

Section JSON should contain stable content:

headings
body copy
image paths
button labels
external URLs that are part of content
display flags

Section JSON should not contain runtime state:

current environment
current host
current request URL
database query results
authenticated user state

Runtime state should come from a controller or service and be passed to the section renderer as context.

Current Data Shapes

intro_hero

eyebrow
title
summary
show_environment_badge

powered_sites

heading
show_environment_badge

The linked site collection is provided by App\Services\PoweredSiteDirectory.