---
name: semantics-frontend
description: Core protocol for Svelte 5 (Runes) Components, UX State Machines, and Visual-Interactive Validation.
---

# [DEF:Std:Semantics:Frontend]
# @COMPLEXITY: 5
# @PURPOSE: Canonical GRACE-Poly protocol for Svelte 5 (Runes) Components, UX State Machines, and Project UI Architecture.
# @RELATION: DEPENDS_ON ->[Std:Semantics:Core]
# @INVARIANT: Frontend components MUST be verifiable by an automated GUI Judge Agent (e.g., Playwright).
# @INVARIANT: Use Tailwind CSS exclusively. Native `fetch` is forbidden.

## 0. SVELTE 5 PARADIGM & UX PHILOSOPHY
- **STRICT RUNES ONLY:** You MUST use Svelte 5 Runes for reactivity: `$state()`, `$derived()`, `$effect()`, `$props()`, `$bindable()`.
- **FORBIDDEN SYNTAX:** Do NOT use `export let`, `on:event` (use `onclick`), or the legacy `$:` reactivity.
- **UX AS A STATE MACHINE:** Every component is a Finite State Machine (FSM). You MUST declare its visual states in the contract BEFORE writing implementation.
- **RESOURCE-CENTRIC:** Navigation and actions revolve around Resources. Every action MUST be traceable.

## I. PROJECT ARCHITECTURAL INVARIANTS
You are bound by strict repository-level design rules. Violating these causes instant PR rejection.
1. **Styling:** Tailwind CSS utility classes are MANDATORY. Minimize scoped `<style>`. If custom CSS is absolutely necessary, use `@apply` directives.
2. **Localization:** All user-facing text MUST use the `$t` store from `src/lib/i18n`. No hardcoded UI strings.
3. **API Layer:** You MUST use the internal `requestApi` / `fetchApi` wrappers. Using native `fetch()` is a fatal violation.

## II. UX CONTRACTS (STRICT UI BEHAVIOR)
Every component MUST define its behavioral contract in the header.
- **`@UX_STATE:`** Maps FSM state names to visual behavior.
  *Example:* `@UX_STATE: Loading -> Spinner visible, btn disabled, aria-busy=true`.
- **`@UX_FEEDBACK:`** Defines external system reactions (Toast, Shake, RedBorder).
- **`@UX_RECOVERY:`** Defines the user's recovery path from errors (e.g., `Retry button`, `Clear Input`).
- **`@UX_REACTIVITY:`** Explicitly declares the state source.
  *Example:* `@UX_REACTIVITY: Props -> $props(), LocalState -> $state(...)`.
- **`@UX_TEST:`** Defines the interaction scenario for the automated Judge Agent.
  *Example:* `@UX_TEST: Idle -> {click: submit, expected: Loading}`.

## III. STATE MANAGEMENT & STORE TOPOLOGY
- **Subscription:** Use the `$` prefix for reactive store access (e.g., `$sidebarStore`).
- **Graph Linkage:** Whenever a component reads or writes to a global store, you MUST declare it in the `[DEF]` header metadata using:
  `@RELATION: BINDS_TO -> [Store_ID]`

## IV. IMPLEMENTATION & ACCESSIBILITY (A11Y)
1. **Event Handling:** Use native attributes (e.g., `onclick={handler}`).
2. **Transitions:** Use Svelte's built-in transitions for UI state changes to ensure smooth UX.
3. **Async Logic:** Any async task (API calls) MUST be handled within a `try/catch` block that explicitly triggers an `@UX_STATE` transition to `Error` on failure and provides `@UX_FEEDBACK` (e.g., Toast).
4. **A11Y:** Ensure proper ARIA roles (`aria-busy`, `aria-invalid`) and keyboard navigation. Use semantic HTML (`<nav>`, `<main>`).

## V. LOGGING (MOLECULAR TOPOLOGY FOR UI)
Frontend logging bridges the gap between your logic and the Judge Agent's vision system.
- **[EXPLORE]:** Log branching user paths or caught UI errors.
- **[REASON]:** Log the intent *before* an API invocation.
- **[REFLECT]:** Log visual state updates (e.g., "Toast displayed", "Drawer opened").
- **Syntax:** `console.info("[ComponentID][MARKER] Message", {extra_data})` — Prefix MUST be manually applied.

## VI. CANONICAL SVELTE 5 COMPONENT TEMPLATE
You MUST strictly adhere to this AST boundary format:

```html
<!-- [DEF:ComponentName:Component] -->
<script>
  /**
   * @COMPLEXITY: [1-5]
   * @PURPOSE: Brief description of the component purpose.
   * @LAYER: UI
   * @SEMANTICS: list, of, keywords
   * @RELATION: DEPENDS_ON -> [OtherComponent]
   * @RELATION: BINDS_TO -> [GlobalStore]
   * 
   * @UX_STATE: Idle -> Default view.
   * @UX_STATE: Loading -> Button disabled, spinner active.
   * @UX_FEEDBACK: Toast notification on success/error.
   * @UX_REACTIVITY: Props -> $props(), State -> $state().
   * @UX_TEST: Idle -> {click: action, expected: Loading}
   */
  import { fetchApi } from "$lib/api";
  import { t } from "$lib/i18n";
  import { taskDrawerStore } from "$lib/stores";
  
  let { resourceId } = $props();
  let isLoading = $state(false);

  async function handleAction() {
    isLoading = true;
    console.info("[ComponentName][REASON] Opening task drawer for resource", { resourceId });
    try {
      taskDrawerStore.open(resourceId);
      await fetchApi(`/api/resource/${resourceId}/process`);
      console.info("[ComponentName][REFLECT] Process completed successfully");
    } catch (e) {
      console.error("[ComponentName][EXPLORE] Action failed", { error: e });
    } finally {
      isLoading = false;
    }
  }
</script>

<div class="flex flex-col p-4 bg-white rounded-lg shadow-md">
  <button 
    class="btn-primary" 
    onclick={handleAction} 
    disabled={isLoading}
    aria-busy={isLoading}
  >
    {#if isLoading} <span class="spinner"></span> {/if}
    {$t('actions.start')}
  </button>
</div>
<!--[/DEF:ComponentName:Component] -->