**Major release.** First publicly-cut tag after v1.6.3, aggregating every change since. Two breaking changes (both in `### Changed`): custom `Pushery\WireKit\Contracts\ChartAdapter` implementations must add three new methods to satisfy the expanded interface, AND `<x-wirekit::container>` inline-padding tiers now read from the `--padding-wk-x-*` token family instead of `--space-wk-*` so a container nested in `<x-wirekit::main>` inherits the same content-edge spine. Developers using only the built-in `ChartJsAdapter` or the new `ApexChartsAdapter`, and developers using `<x-wirekit::container>` with default padding values, see no behavioral change beyond a 0.5-rem horizontal alignment correction. Every other change is additive and back-compatible.

### Added

- **Optional ApexCharts chart adapter alongside the existing Chart.js adapter.** Switch with one line in `config/wirekit.php`: `'charts' => ['library' => 'apexcharts']`. Same `<x-wirekit::chart>` Blade tag for both libraries; zero breaking change. ApexCharts unlocks 9 chart types Chart.js does not ship natively — candlestick, boxplot, range-bar, range-area, heatmap, treemap, funnel, radial-bar, sparkline. Dedicated `dist/wirekit-apex.js` adapter bundle (~2 KB gzip glue, no ApexCharts library code; the developer installs `apexcharts` via npm). **Note: ApexCharts is not MIT-licensed — the free Community License covers organizations under $2M USD annual revenue; Commercial License required above. WireKit ships only the adapter glue (MIT). See [docs/components/chart.md#license-apexcharts-only](https://docs.wirekit.app/components/chart) for the full terms.**
- **`<x-wirekit::sparkline>` — NEW first-class component.** Inline trend sparkline (axis-less line chart) for KPI strips and dashboard cells. Six props (`data` / `trend` / `inline` / `height` / `scope`). Auto-detects trend from first-vs-last data and tints green / red / muted accordingly; manual `trend="up|down|neutral"` override available. Inline mode renders at surrounding text height (1.25em / 4rem width); block mode at configurable height (default 2.5rem). Delegates to `<x-wirekit::chart type="sparkline">` so both adapters render correctly — ApexCharts uses native sparkline mode, Chart.js falls back to a plain line.
- **`<x-wirekit::chart-mixed>` — NEW component for multi-axis dashboards.** Each dataset declares its own `type` (line / bar / column / area) plus an optional `yAxisID` for multi-axis configurations. Both adapters consume the per-dataset type field natively — Chart.js via the per-dataset `type` field, ApexCharts via `series[].type`.
- **`wireStream` prop on `<x-wirekit::chart>` for real-time data updates.** Subscribe a chart to a Livewire-emitted event and append each fired payload via the library's imperative API (`chart.update('none')` for Chart.js / `chart.appendData()` for ApexCharts). `wireStreamMode="strict"` (default) FIFO-trims at `wireStreamCap` points (default 100); `wireStreamMode="stream"` grows unbounded.
- **`annotations` prop on `<x-wirekit::chart>` for vertical lines / horizontal regions / point callouts.** ApexCharts has annotations built-in; Chart.js requires `chartjs-plugin-annotation` (the Alpine factory emits a console.warn when annotations are supplied but the plugin is missing — graceful degradation).
- **Smooth dark-mode preset transitions on chart re-theming** (~250 ms ease-out). Both adapters interpolate colors during `.dark` toggle instead of snapping. Collapsed to instant under `prefers-reduced-motion: reduce`.
- **Two new chart-system docs subhierarchies on docs.wirekit.app:** `/components/charts-chartjs/` (full Chart.js demo set — bar / line / area / pie-doughnut / scatter-bubble / radar-polar / advanced / theming) and `/components/charts-apex/` (full ApexCharts demo set — line / area / bar / column / range-bar / pie-donut / radial-bar / radar / scatter-bubble / heatmap / treemap / candlestick / boxplot / funnel / timeline / sparklines / annotations / streaming / mixed / motion / theming). Every page ships realistic seed data drawn from B2B SaaS, e-commerce, DevOps, finance, marketing domains.
- **`wirekit:install --apex-license=community|commercial|oem` flag.** Records the developer's license tier into `config/wirekit.php` `charts.apex_license` after printing the License Notice once at install time. Suppresses the `wirekit:doctor` reminder for `commercial` and `oem` tiers.
- **`wirekit:doctor` ApexCharts checks.** Detects `apexcharts` npm package presence, validates the active license tier, confirms `dist/wirekit-apex.js` is published.
- **`wirekit-apex.js` registered as publishable** under both the `wirekit-scripts` and `wirekit-assets` tags. Running `php artisan vendor:publish --tag=wirekit-assets` now copies the adapter glue to `public/vendor/wirekit/wirekit-apex.js` alongside the other JS bundles. The route fallback at `/wirekit/wirekit-apex.js` also works for setups that prefer route-based serving over publishing. Eliminates the manual `cp vendor/.../dist/wirekit-apex.js public/vendor/wirekit/` step that ApexCharts adopters previously had to run after every `composer update`.
- **`<x-wirekit::reading-toc>` — NEW primitive in the reading family.** Horizontal sticky-strip TOC sibling to `reading-spine`. Same auto-build-from-headings + IntersectionObserver active-section model, different rendered shape (a flat row of links across the top or bottom of the article container). Use case: marketing landing pages with 3-4 anchored sections (Hero, Features, Pricing, FAQ) where a vertical sidebar feels excessive. Seven props (`target`, `levels`, `position`, `offset`, `hideBelow`, `flush`, `scope`). Defaults to `levels="2"` for landing-page flat structure; mobile-hidden via `hideBelow="sm"` since narrow viewports cannot host a horizontal strip without overflow. The `flush` prop zeroes the first link's left-edge padding and the last link's right-edge padding so the visible text aligns flush with the strip's content edges (use when the TOC sits directly under `<x-wirekit::brand-bar>` or `<x-wirekit::main>` and the developer wants the first link on the same vertical content-edge spine as the surrounding brand text and h2 headings). Real `<a href="#section-id">` links inside a `<nav aria-label="Page sections">` landmark — keyboard-navigable + screen-reader native. `prefers-reduced-motion: reduce` collapses smooth-scroll to instant. Reuses spine's `--reading-spine-color-idle` / `-active` for theme consistency; adds 5 layout-specific tokens (`--reading-toc-bg` / `-padding-y` / `-padding-x` / `-gap` / `-link-max-width`) plus 2 color aliases.
- **`<x-wirekit::brand-bar>` — NEW navigation primitive.** Page-chrome wrapper for the canonical "logo + tagline + actions" header pattern. Three named slots: `brand` (typically a `<x-wirekit::brand>` primitive), `tagline` (secondary muted text), `actions` (right-anchored sign-in / theme-toggle / account-widget content via `margin-left: auto`). Props: `as` (`header` | `nav`), `divider` (`bottom` | `none`), `padding` (`none`/`sm`/`md`/`lg`/`xl`), `sticky` (pins to `top: 0` during scroll with an opaque background fallback). Carries the content-edge spine via `padding="lg"` reading from `--padding-wk-x-lg`, so the brand visible-text aligns with `<x-wirekit::main padding="lg">`, `<x-wirekit::reading-toc flush>`, and the article h2 headings below on the same vertical X-coordinate — out of the box, no custom CSS.
- **`<x-wirekit::prose :density>` — NEW prop on the existing component.** `comfortable` (default) keeps the long-form-article heading scale (h2 mt = 2.5 rem for generous section breaks, h1 = 1.875 rem). `compact` tightens for marketing pages (h2 mt = 0.75 rem, h1 one type-scale tier smaller, p mb = 0.5 rem). Eliminates the need to override prose typography with developer-side `.my-section h2 { margin: ... }` rules when the prose lives inside a tight marketing layout. Default `comfortable` keeps backward-compatible rendering.
- **`<x-wirekit::reading-shell :toc="true">` — opt-in toc toggle.** Defaults to `false` in every density preset (comfortable / compact / minimal). Marketing landing pages explicitly opt in via `:toc="true" :spine="false"`; blog posts and docs pages keep the spine sidebar.
- **Marketing Landing TOC recipe** at `/recipes/marketing-landing-toc` — sibling to long-form-article. Demonstrates the canonical Hero / Features / Pricing / FAQ landing-page pattern with the new sticky TOC strip, plus the `offset` prop pattern for layouts with a fixed nav above the strip.
- **Long-form Article recipe** at `/recipes/long-form-article` — canonical Medium / Substack-style article layout: reading-progress bar at the top, reading-spine sidebar on the right, reading-bookmark resume pill, reading-meta time-to-read. Demonstrates the full reading-* family in one composition, both via the `<x-wirekit::reading-shell>` sugar wrapper and via direct primitive composition for power-user customization.
- **Documentation Reader recipe** at `/recipes/documentation-reader` — documentation-style article shell with reading-progress bar, dense-section reading-spine, fixed-nav offset on the TOC strip, reading-bookmark across multi-page-session reads. Shows the docs-rhythm pattern (heading-scale + dense per-paragraph code blocks) alongside the same reading-* primitives.
- **`<x-wirekit::reading-minimap>` — NEW primitive in the reading family.** Every-item density overview of a scrollable container, with two rendering modes:
  - `mode="stripes"` (default) — every item matched by `itemSelector` renders as a 1–2 px stripe at proportional vertical position. `itemStyle="block"` upgrades to per-paragraph rectangles whose height tracks the source item's natural height (skeleton-style content texture).
  - `mode="rendered"` — code-editor-style abstract content canvas. Walks every text-bearing node via `TreeWalker`, gets per-rendered-line rects via `Range.getClientRects()`, draws each as a rectangle on a DPR-aware canvas. Per-element-type color palette (h1–h6 each its own alpha tier, code indigo, table rose, blockquote slate-bolder, image amber, WireKit `wk-*` components emerald, prose / default slate-muted). 13 `--reading-minimap-color-{h1..h6,code,table,blockquote,prose,wirekit,image,default}` tokens for full re-theming without JS.
  - Translucent viewport-overlay rectangle tracks the host's visible region; click stripe → smooth-scroll target so item is centered (instant under `prefers-reduced-motion: reduce`); drag overlay → pan host scroll position with browser-scrollbar-matched translation; hover stripe (non-touch) → tooltip following the cursor with the item label.
  - Two canonical use cases: long-form article density-overview (sibling to `reading-spine`) and sidebar navigation density-overview.
  - 5000-tag silent fallback to stripe mode on very long articles. No DOM clone in rendered mode → no parse step → no surface for HTML-injection vectors.
- **`<x-wirekit::reading-meta perParagraph>` — Medium-style inline annotations.** Opt-in mode that injects small `<span class="wk-reading-meta-paragraph">N min</span>` annotations immediately before each `<p>` in the target with at least `paragraphMinWords` words (default 30). Annotations show estimated remaining-time FROM that paragraph onward, re-computed on scroll. `aria-hidden="true"` on every annotation — canonical SR text remains the total/remaining display. Default off; opt-in.
- **`<x-wirekit::reading-progress variant="auto">` — theme-reactive fill mode.** Falls back to `currentColor` when the developer hasn't set `--reading-progress-fill` — useful for embedded contexts (iframes, browser extensions) where the bar should match the surrounding text color. Joins the canonical 6-value variant set (`primary | neutral | success | warning | danger | info`).
- **`<x-wirekit::reading-shell density>` preset prop.** Three values (`comfortable` | `compact` | `minimal`) adjust the shell's per-primitive defaults: progress-bar height, spine expand mode, which primitives render by default. Per-primitive toggles (`:spine="false"` etc.) win over the density preset.
- **14 new design tokens for the reading-* family**: 1 on `reading-progress` (`--reading-progress-fill`), 7 on the new `reading-minimap` (width, stripe-height, stripe-gap, color-idle, color-active, viewport-bg, viewport-border), 2 on `reading-meta` perParagraph mode (paragraph-color, paragraph-spacing). All themeable in `:root {}`.
- **`<x-wirekit::stat>` composes `animate` (counter count-up) with `animateIn` (entrance reveal).** The Blade template emits an outer wrapper that carries the entrance reveal while the inner element keeps the counter handler — the two scopes layer cleanly. Single-flag usages render byte-identical.
- **`<x-wirekit::cta>` and `<x-wirekit::footer>` accept the `animateIn` prop.** Both marketing primitives now match the existing `animateIn` surface on `<x-wirekit::card>`, `<x-wirekit::feature>`, `<x-wirekit::hero>`, and others. Passing `animateIn="slide-up"` (or any of the 11 base presets) wires `<x-wirekit::reveal>` semantics inline without an extra wrapper element. Honors `prefers-reduced-motion: reduce`.
- **`stagger` prop on `<x-wirekit::feature-grid>` and `<x-wirekit::stats>`.** When set on the wrapper and an entrance preset is configured on the children, each child's animation fires with an incremental delay — produces a clean cascade instead of every card landing at once. Boolean form uses a 75ms step (`stagger`); integer form overrides for custom rhythm (`:stagger="125"`). Pure CSS via `:nth-child` rules with an index cap at 8 to bound delay on long lists; collapses to 0 under reduced motion. Zero JS bundle impact.
- **`delay` prop on `<x-wirekit::reveal>`.** Holds the entrance for a beat before it begins — useful for sequencing cards or letting a hero-section heading land before the supporting copy follows. Accepts five named tokens (`none`, `sm`, `md`, `lg`, `xl`) mapping to themeable CSS variables, or a raw integer in milliseconds for one-offs. Composed via inline `animation-delay` on the existing `wk-animate-{preset}` class — no JS plugin change needed. Collapses to `0ms` under `prefers-reduced-motion: reduce`.
- **Five new motion-delay tokens in `dist/wirekit.css`:** `--motion-wk-delay-none` (`0ms`), `--motion-wk-delay-sm` (`75ms`), `--motion-wk-delay-md` (`150ms`), `--motion-wk-delay-lg` (`300ms`), `--motion-wk-delay-xl` (`500ms`). All developer-overridable in `:root {}`.
- **CSS class `.wk-stagger`** plus eight `:nth-child` rules and a cap-at-8 index ceiling. Drives the `stagger` prop on feature-grid and stats. Reduced-motion override zeroes per-child delays inside the existing `@media (prefers-reduced-motion: reduce)` block.
- **`wirekit:doctor` thirteenth check — `:root` vs `.dark` color-token symmetry.** The doctor now reads the developer's `resources/css/app.css`, extracts the `:root {}` and `.dark {}` blocks, and emits a warning when `--color-wk-*` tokens are declared in one block but missing from the other. Asymmetric color tokens produce theme drift the developer sees as "looks wrong in dark mode" without an obvious cause.
- **`<x-wirekit::reading-progress>`** — viewport-pinned reading-progress indicator for long-form articles. Bar (default) or dot (`indicator="dot"`) variants; both fill 0 → 100% on scroll using compositor-only properties (`transform: scaleX` / `stroke-dasharray`). Five `variant` colors, three `height` tokens (`sm`/2px, `md`/3px, `lg`/5px), `showAfter` scroll threshold, `target=` selector, `segments` chapter markers, `milestones` events (`wirekit:reading-progress:milestone` Alpine dispatch fired ONCE per session at 25 / 50 / 75 / 100% boundaries). `role="progressbar"` + dynamic `aria-valuenow`. Zero-KB bundle impact.
- **`<x-wirekit::reading-spine>`** — sidebar mini-TOC that auto-builds from page headings. Pins to the right edge at md+ breakpoints; tracks scroll position via `IntersectionObserver`; expands on hover or focus. Configurable `target=`, `levels=`, `position=`, `expand=` (`hover` / `focus` / `always` / `always-md`), `offset=`. Real anchor links so navigation works without JS. Five opt-in extensions: `numbered`, `fillSections`, `backToTop`, `expand="always-md"`, and a `wirekit:reading-spine:section-changed` event. Filter slot composition pattern. Bundle impact: ~600 bytes gzip.
- **`<x-wirekit::reading-bookmark>`** — persists scroll position to `localStorage` while reading; surfaces a "Resume reading where you left off?" pill on return-visit when conditions are met (previous-session dwell time ≥ `minDwellSeconds`, scroll moved past `threshold * scrollHeight`). Cross-tab consistency via `storage` event. `try/catch` wrapping every storage op — silently degrades on private-browsing / quota-exceeded. Required `key` prop (typically `"article-{slug}"`).
- **`<x-wirekit::reading-meta>`** — small text element showing `~12 min read` (initial estimate) and optionally `~5 min remaining` (live-tracking on scroll). Skips non-prose nodes (`pre`, `code`, `figure`, `figcaption`, `img`, `picture`, `svg`, `[data-language]`). CJK-aware: when more than 40% of text is CJK ideographs, falls back to character-based estimation with a configurable `cjkCharsPerMinute` baseline (default 500). `wpm` clamps to `≥ 50`; `totalMinutes` floors to 1. `role="status" aria-live="polite"`.
- **`<x-wirekit::reading-shell>`** — composition wrapper that renders `<x-wirekit::reading-progress>` + `<x-wirekit::reading-spine>` + `<x-wirekit::reading-bookmark>` + `<x-wirekit::reading-minimap>` + `<x-wirekit::reading-meta>` around the slot content in one tag. Mirrors the `<x-wirekit::app-shell>` "one tag, full UX" pattern. Per-component opt-out via `:progress="false"` etc. Forwards every documented child prop via flat surface.
- **CSS variable tokens for the reading-* family in `dist/wirekit.css`:** three height tokens for the bar (`--reading-progress-height-{sm,md,lg}`), the dot diameter (`--reading-progress-dot-size`), seven spine layout / color tokens, three bookmark pill tokens, two reading-meta tokens.
- **`@media print { display: none !important }`** rule for every reading-* primitive — only the article body prints, not the reading chrome.
- **`prefers-reduced-motion: reduce` gating for the entire reading-* family** in the global `@media (prefers-reduced-motion: reduce)` block.
- **`<x-wirekit::replay-button>` — NEW companion primitive.** Renders an icon-button that walks the closest `[data-replay-target]` ancestor and re-mounts it (`Alpine.initTree`) so its `x-data="wirekitAnimate(...)"` / counter / chart-motion fires again. Standardizes the "re-play this animation" affordance every animation-capable component carries via the `data-replayable="true"` contract — developers can place the button explicitly anywhere alongside a primitive, or rely on docs.wirekit.app's preview chrome auto-injecting it. Two props: `label` (button `aria-label`, default `"Replay"`), `scope` (named personalization scope).
- **`replayable` prop on `<x-wirekit-chart>`.** Opt INTO the docs.wirekit.app `↻ Replay` button surface by emitting `data-replayable="true"` on the chart root. Set it explicitly when the entrance animation is worth re-watching (bar-grow / line-trace / slice-sweep on `/components/charts-apex/motion`), or rely on the auto-detect path: whenever `wireStream` is bound (every streaming chart on `/components/charts-apex/streaming`), the attribute is emitted automatically. Back-compat preserved: callers who already passed `data-replayable` raw via the attribute bag continue to work — the Blade view skips its own emission to avoid duplication.

### Changed

- **`Pushery\WireKit\Contracts\ChartAdapter` interface expanded from 4 → 7 methods.** Net-new: `name()` / `rendersTo()` / `supportedTypes()`. Existing `scripts()` / `normalizeData()` / `defaultOptions()` / `alpineComponent()` unchanged. Developers using only built-in adapters see no impact (both `ChartJsAdapter` and `ApexChartsAdapter` ship the new methods). Custom adapter implementations need to add the three new methods to satisfy the interface. **BREAKING for developers with a hand-written `ChartAdapter` implementation.**
- **`<x-wirekit::container>` inline-padding moved from `--space-wk-*` to `--padding-wk-x-*`.** `padding="sm|md|lg|xl"` now reads from the `--padding-wk-x-*` content-edge spine instead of the `--space-wk-*` block-rhythm scale. Resolves a silent 0.5 rem horizontal drift when nesting `<x-wirekit::container padding="lg">` inside `<x-wirekit::main padding="lg">` — both now share the same content-edge X-coordinate. Developers who depended on the wider previous value (e.g. `padding="lg"` was 1.5 rem, now 1 rem) should bump to `padding="xl"` (also 1.5 rem) for unchanged visual output. **BREAKING for developers relying on the exact pixel value of container's horizontal padding.**
- **`<x-wirekit::sidebar>` inline-padding fixed.** Was applying `--padding-wk-y-sm` (the y-axis token) on all four edges; now correctly splits into `px-[var(--padding-wk-x-sm)] py-[var(--padding-wk-y-sm)]` and moves the inter-item `gap` to `--space-wk-sm` (the canonical gap token). Sidebar items at the inboard edge now align with `<x-wirekit::header>` and `<x-wirekit::main>` rendered alongside on the same vertical content-edge spine. Back-compat: visual change is a few-pixel adjustment to the sidebar's internal padding; no API change.
- **Color-prop unification across `<x-wirekit::message>`, `<x-wirekit::alert>`, `<x-wirekit::callout>`, and `<x-wirekit::progress>`.** Every component that exposes a color prop now accepts the same canonical six-value set (`primary, neutral, success, warning, danger, info`). `progress` adopts `primary` as the canonical name; the historical `accent` value continues to work as a back-compat alias. New [Variants & Intents](https://docs.wirekit.app/variants-and-intents) page documents the canonical set, the per-component prop tables, and the visual-synonym semantics in one place.
- **Bundle size**: `dist/wirekit.js` grew from 25 → 26 KB gzip (83 → 86 KB raw) covering the new reading-* family and chart-adapter expansion. Stays within the ±2 KB drift budget per `docs/dependencies.md`. Core bundle (chart-only) unchanged at ~2 KB gzip / 11 KB raw. ESM bundle ~25 KB gzip / 82 KB raw.
- **`.wk-reading-toc__list` inline-padding ships without `!important`.** Developers running a typography prose-wrapper (e.g. a `@tailwindcss/typography` body or any `body.prose`-style class) should carve out `[class*="wk-"]` from their `ul/ol/li` rules — same pattern they already use for the `max-width: 75ch` typography clamp. Without the carve-out the `padding-left: 1.75rem` in a typical prose stylesheet wins on specificity over `.wk-reading-toc__list { padding-inline: 0.25rem }` and pushes WireKit list-based components (reading-toc, list, breadcrumb) off the content-edge spine. Recommended typography rule shape: `.prose ul:not([class*="wk-"]), .prose ol:not([class*="wk-"]) { padding-left: 1.75rem }`.

### Documentation

- **`docs/integration.md` — new "Performance — Conditional Asset Loading" section** documenting a server-side flag pattern for emitting `highlight.js` and `Chart.js` `<script>` tags only on pages that actually use `<x-wirekit::code-block>` or `<x-wirekit::chart>`. Saves ~95 KB gzip on lightweight routes (landing pages, theming guide, recipes without code/charts) without breaking caching or first-paint correctness. Pattern is documentation-only; no helper class shipped — adapt the `str_contains()` detection to your DocsParser / class-naming conventions.
- **`/theming/design-tokens` — NEW comprehensive reference page** for every WireKit CSS variable: colors, typography, motion, sizing, component-specific tokens, and the chart-theming palette. Single landing page where developers can find any token by name before reaching for its component's docs page.
- **`/getting-started/livewire-starter-kit` — NEW recipe page** for fitting WireKit into an existing Livewire Starter Kit project. Walks the four touchpoints where Starter-Kit defaults differ from a clean-room `wirekit:install` (theme preset, font stack, dark-mode flip, sidebar conflict resolution) so existing Starter-Kit developers don't have to discover them ad-hoc.