Files
arcadia-admin/app/components
jules c640721c8e ai: composer chip inherits active config's reasoning default
Pulls the reasoning storage out of ai.tsx and into the shared
llm-configs.ts helpers so Settings → LLM and the /ai composer
coordinate via one localStorage key (crema.ai.reasoning):

- loadActiveReasoning / saveActiveReasoning: read/write helpers.
- subscribeActiveReasoning: dispatches a CustomEvent on writes
  (same-tab) plus a storage-event listener (cross-tab), so the
  chip updates live when the operator stars a different config in
  another tab or in the settings panel.

Wiring:
- Settings panel onMakeActive() now also calls
  saveActiveReasoning(c.reasoning_effort ?? "off"). Starring a
  config seeds the chip with that config's default.
- /ai chip useEffect subscribes to changes; a star in Settings
  while /ai is open flips the chip in real time.
- resetAndClear no longer wipes reasoningEffort. Clearing the
  conversation shouldn't silently undo the operator's stated
  intent for thinking-mode (which is bound to their active config,
  not to the conversation).

Net behaviour:
- Star a config with reasoning_effort=medium → chip on /ai shows
  THINK MEDIUM next time you visit (or immediately if /ai is open).
- Cycle the chip while on /ai → just an override for the current
  conversation, not back-propagated to the saved config.
- Edit the config in Settings to change its default → propagates to
  the chip on next star (intentional — direct edits don't auto-
  re-activate).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 20:18:06 +10:00
..

components/

Component layers in this project.

ui/          shadcn primitives — token-driven, reskinnable per design system
forms/       composed form widgets
data/        data display (tables, filters, empty states)
layout/      app shell, page chrome, navigation wrappers
marketing/   landing and marketing blocks
[system]/    design-system-specific components (e.g. m3/, apple/)

The one rule

Custom components import from ui/, never the reverse.

ui/ is the primitive layer. It must stay reskinnable by swapping tokens in app/themes/*.css alone. If a component can't be expressed that way (M3 ripple, Apple segmented control, etc.), it belongs in a system-specific folder — not ui/ and not the shared folders above.

Tokens, not values

Every custom component should reference semantic tokens:

  • Colors: bg-primary, text-muted-foreground, border-border
  • Radius: rounded-md, rounded-lg
  • Fonts: font-sans, font-heading

Hardcoded hex, oklch, or px values are a bug — they break theming.