# Handoff: Cydekick Pricing Module

## Overview
A five-screen **Pricing management module** for the Cydekick Laravel ERP. It lets a merchandiser define markup rules by brand/category, configure per-channel selling fees, inspect a single product's calculated price across every sales channel, and audit every recalculation. The designs match the existing Cydekick app chrome (navy sidebar + navy header, white card panels, status pills, channel badges, text row-actions).

## About the Design Files
The files in this bundle are **design references created in HTML/React (via inline Babel)** — prototypes showing the intended look, layout, and behavior. **They are not production code to paste in.** The task is to **recreate these screens inside the Cydekick codebase using its established patterns** — Blade templates + whatever JS layer the app already uses (Livewire / Alpine / Vue / Inertia). Reuse existing partials for the sidebar, header, cards, tables, pills, and buttons rather than reproducing the CSS here. Treat the HTML as the source of truth for structure, spacing, copy, and states.

## Fidelity
**High-fidelity.** Final colors, typography, spacing, and interaction states are all specified. Recreate the UI to match, using the codebase's existing component library / CSS. Where the app already has a token or component (a pill, a channel badge, a card header), use that instead of introducing a new one — the hex values below are provided so you can confirm they match.

---

## Screens / Views

### 1. Pricing Rules — List (`rules`)
- **Purpose:** Browse/manage markup rules. Higher priority wins when multiple rules match a product.
- **Layout:** Standard page body (padding 22px 26px). Page head: H1 + description on the left, primary **New Rule** button top-right. Below, a single white card containing a filter bar then a full-width table.
- **Filter bar:** left-aligned search input ("Search rules…"), spacer, then three dropdown filters — Brand / Category / Status (each a bordered pill, `label: value ▸`).
- **Table columns:** Rule (name bold + `PR-0xx` id mono sub), Scope (a colored tag `Brand` / `Category` / `Brand + Category` stacked above the scope value in muted text), Priority (centered mono), Tiers (centered mono), Status (Active/Inactive pill), Last modified (date + "by <name>" sub), Actions.
- **Row actions:** text links — **Edit** (blue), **Duplicate** (muted grey), **Deactivate/Activate** (muted grey). Clicking Edit or the rule name → screen 2.

### 2. Pricing Rule — Detail / Edit (`rule-detail`)
- **Purpose:** Edit a rule's metadata and its ordered ladder of cost tiers.
- **Layout:** Narrow body (max-width 1120px). Back link ("← Back to Pricing Rules"), page head with rule name H1 + `PR-014 · last modified…` mono sub, and Cancel / **Save Rule** buttons top-right. Two stacked cards.
- **Card 1 — Rule details:** grid `1fr 200px` → Rule name input + Priority input ("Lower number wins ties" helper). Divider. Then a row: **Scope** segmented control (`Brand | Category | Brand + Category`), Brand select, Category select (the irrelevant select dims to 0.4 opacity depending on scope), and a **Status** toggle switch (green when active) with an Active/Inactive label.
- **Card 2 — Cost tiers (the "ladder"):** card header has title, subtitle ("each tier's min should meet the previous tier's max"), and a right-aligned amber warning pill `⚠ 1 gap detected`. Column header row: Min cost / Max cost / Markup type / Markup value. Each tier row is a grid `44px 1fr 1fr 150px 1fr 40px`:
  - **Left node:** a 26px circle numbered 1..N in blue, connected downward to the next node by a 2px vertical line — this is the visual ladder/sequence.
  - Min cost (£-prefixed mono input), Max cost (£-prefixed, empty = "No limit"), Markup type (small segmented `% | £`), Markup value (suffix `%` for percentage, prefix `£` for fixed), and a delete (trash) icon button that tints red on hover.
  - **Validation:** when a tier's `min` ≠ the previous tier's `max`, render an amber inline warning banner *above* that tier: `⚠ Gap — Tier N starts at £X but Tier N-1 ends at £Y — costs between are unpriced.` (In the mock, tier 4 starts at £210 while tier 3 ends at £200.) Overlap (min < previous max) should use the same treatment with "overlap" wording.
- **Add tier:** ghost blue `+ Add tier` button below the ladder.

### 3. Channel Fee Profiles — List + Detail (`fees` / `fee-detail`)
- **List purpose:** one row per channel showing its fee structure.
- **List table columns:** Channel (badge), Fee structure (summary e.g. `1.5% + £0.20` mono bold + "Flat rate" / "Base rate + category tiers" sub), Category overrides (centered count or muted "None"), Status pill, Last updated, Actions (Edit → detail, Duplicate).
- **Detail purpose:** flexible fee builder. Because channels differ (flat vs category-tiered), start simple and progressively disclose.
- **Detail layout:** narrow body, back link, page head = channel badge + "<Channel> Fee Profile" + Cancel / **Save Profile**.
  - **Card 1 — Base fee:** header title + subtitle + active toggle on the right. Body: **Percentage fee** input (`%` suffix) `+` **Fixed fee** input (`£` prefix), and a right-aligned live preview chip: "On a £40.00 sale: **£5.42** fee".
  - **Card 2 — Category overrides (collapsible):** header is clickable to expand/collapse (chevron rotates), shows a count tag, and an **+ Add category override** ghost button on the right. Body is a mini table grid `1.4fr 1fr 1fr 130px 40px`: Category select, Percentage (`%`), Fixed (`£`), "Effective on £40" computed mono value, delete button. Adding appends an empty row; removing deletes it. Empty state: "No category overrides — the base fee applies to all products."

### 4. Product Pricing View (`product`) — the key operational screen
- **Purpose:** See ONE product's calculated price on every channel it's listed on, with fee breakdowns and staleness.
- **Layout:** full-width body. Breadcrumb, page head = product name H1 + SKU mono sub + secondary **Recalculate all** button.
- **Summary strip** (white bordered bar, flex row with 1px separators): Cost price (£24.60, large mono), Brand/Category (two tags), Matched pricing rule (name + `PR-019` + tier line "Tier 2 · £25–75 · +45%"), and right-aligned "Listed on" channel badges.
- **Channel cards grid:** `repeat(auto-fill, minmax(320px, 1fr))`, gap 16px. Each card:
  - Header: channel badge + status pill (**"Up to date"** green, or **"Needs recalculation"** amber). A stale card gets an amber border + soft amber glow (`box-shadow: 0 0 0 3px rgba(245,158,11,0.08)`).
  - Large calculated price (34px mono) + "calculated price" label.
  - Breakdown lines: Cost price, Markup (+45%), Base price, then a **Fees (n)** toggle row (dashed top border, chevron rotates) that expands a shaded sub-panel of individual fee line items (e.g. "Referral fee 15.3% +£6.94", "FBA handling +£1.94"). **Fees default collapsed**; in the mock eBay is pre-expanded to demonstrate. Then a bold **Calculated price** total line.
  - Footer: a clock icon + "Calculated Today 09:12" (or "Last calculated <date>" when stale), and a **Recalculate Now** button. On a stale card the button is amber-filled (prominent); otherwise a plain bordered button. Clicking shows a spinning icon + "Recalculating…" for ~1.1s (mock only — wire to the real recalc job).
- **Interaction note:** the stale/amber state is an *expected transient*, not an error — never red.

### 5. Calculation Log Viewer (`log`)
- **Purpose:** Dense audit trail of every recalculation, newest first. Scanability over visual weight.
- **Layout:** full-width body, page head + secondary **Export CSV**. One card: filter bar (search product/SKU + Channel / Reason / Date dropdowns), then a dense table (row padding 9px), then a footer ("Showing 14 of 2,184 calculations" + Prev/Next pagination buttons).
- **Table columns:** Timestamp (mono, muted), Product (name + SKU sub), Channel (badge), Cost (right mono), Rule matched (name + id sub), Markup (centered muted mono), Final price (right, bold mono), Trigger (a small reason tag).
- **Trigger reason tags** (dot + label): `Cost change` (amber), `Rule change` (blue), `Fee change` (cyan), `Manual` (slate).

---

## Interactions & Behavior
- **Navigation:** sidebar "Pricing" group is expanded with 4 sub-items (Pricing Rules, Channel Fees, Product Pricing, Calculation Log) mapping to screens 1/3/4/5. Rules list → rule detail; Fees list → fee detail; both details have a back link. In the prototype this is React `useState`; in the app these are routes (e.g. `/pricing/rules`, `/pricing/rules/{id}/edit`, `/pricing/fees`, `/pricing/fees/{channel}/edit`, `/pricing/products/{sku}`, `/pricing/log`).
- **Toggles/segmented controls:** local state; persist on Save.
- **Collapsible sections** (fee overrides card, per-channel fee breakdown): chevron rotates 90°, content mounts/unmounts. Transition 0.16s.
- **Recalculate Now:** optimistic spinner for ~1.1s in the mock → replace with the actual queued recalc job; flip pill from stale→fresh and update the timestamp on completion.
- **Tier validation:** recompute on every min/max edit; show gap/overlap banners live; surface an aggregate "N gaps detected" pill in the card header.

## State Management
- `screen` / route currently active.
- Rule detail: `active` (bool), `scope` ('brand'|'category'|'combo'), `tiers[]` ({ n, min, max|null, type:'pct'|'fixed', val }).
- Fee detail: `active` (bool), base pct/fixed, `overrides[]` ({ cat, pct, fixed }), `showOverrides` (bool).
- Product pricing: `open` map of which channel fee-breakdowns are expanded, `busy` channel id during recalc.
- Data fetching: rules list, single rule w/ tiers, fee profiles, single profile w/ overrides, product + per-channel computed prices + fee line items, paginated calculation log with filters (product, channel, date range, reason).

## Design Tokens
**Colors**
- Navy sidebar/header `#0B1B3B`; sidebar hover `rgba(255,255,255,0.05)`; active nav `rgba(47,91,255,0.14)` text `#93C5FD`.
- Primary blue `#2F5BFF` (hover `#2449DA`); blue soft bg `#EEF2FF`.
- Ink `#0A1228`; muted `#6B7280`; soft `#9CA3AF`; border `#E5E7EB`; border-soft `#F1F2F4`; page bg `#F6F7F9`.
- Green (active/fresh) ink `#047857` bg `#ECFDF5` dot `#10B981`.
- Amber (stale/warn) ink `#B45309` bg `#FEF6E7` dot `#F59E0B`.
- Red (danger) ink `#B91C1C` bg `#FEE2E2`.
- Slate (inactive/manual) ink `#475569` bg `#F1F3F6`.
- Scope tags: brand `#4338CA` on `#EEF2FF`; category `#0E7490` on `#ECFEFF`; combo `#6D28D9` on `#F5F3FF`.
- **Channel badges** (muted, tinted bg + colored letter mark): Shopify text `#4D7014` bg `rgba(122,175,58,0.12)` mark `#7CAF3A`; Amazon text `#92600A` bg `rgba(232,162,0,0.13)` mark `#E8A200`; eBay text `#A3161B` bg `rgba(229,50,56,0.10)` mark `#E53238`; Temu text `#9A4A06` bg `rgba(242,104,12,0.12)` mark `#F2680C`.

**Typography** — Inter (UI/body), Familjen Grotesk (H1s / brand, weight 700, letter-spacing -0.02em), JetBrains Mono (SKUs, prices, ids, numeric cells). Table header 11px 600 uppercase tracking 0.05em muted; body cells 13px; large price 34px mono 600; H1 23px.

**Spacing / radius** — body pad 22px 26px; card radius 11px, padding ~16–18px; inputs 36px tall radius 7px; buttons radius 7px; pills radius 999px; tags/rtags radius 5–6px.

**Shadows** — cards flat with 1px border; stale card `0 0 0 3px rgba(245,158,11,0.08)`; segmented-on `0 1px 2px rgba(16,24,40,0.08)`.

## Assets
No raster assets. All icons are inline SVG (nav glyphs, chevrons, plus, back arrow, search, refresh, trash, clock, download). Channel "logos" are simple letter marks, not official brand logos — swap for real brand marks if your brand guidelines allow. Fonts load from Google Fonts.

## Files
- `Cydekick Pricing.html` — entry point: all shared CSS (design tokens + every component class), app shell, and the router that switches screens.
- `pricing-shell.jsx` — sidebar, header, channel badges, pills, toggle, segmented control, filter, icons, `money()` helper.
- `pricing-rules.jsx` — screens 1 & 2 (rules list + rule detail with tier ladder & validation) + sample rule/tier data.
- `pricing-fees.jsx` — screen 3 (fee list + fee detail builder) + sample fee/override data.
- `pricing-product.jsx` — screen 4 (product pricing) + sample product/channel/fee-breakdown data.
- `pricing-log.jsx` — screen 5 (calculation log) + sample log rows.

Open `Cydekick Pricing.html` in a browser to click through all five screens via the sidebar.
