# TechTitans POS — IPTV Account Details · Premium Visual Enhancement

**Date:** 2026-11-12 · **Branch:** `techtitans/integration` (backend + frontend) · Local commits only (no push/deploy).

**Scope:** a **visual-only** refinement of the IPTV *Account Details* page
(`frontend/src/pages/iptv/IptvDetailPage.tsx` + `frontend/src/pages/iptv/iptv.css`). No backend, no API,
no DB schema, no business logic changed. Every existing workflow — renewal maths, free/pay credit,
discounts, tax engine, payments, invoice/quote/receipt, outstanding, expiry, permissions — is untouched.

## Goal

Make the account page look like a premium commercial retail POS — colourful, modern, attractive and
professional — while keeping it operational and uncluttered. Colour is meaningful (status/semantics),
never decorative gradients, and lives in **headers / accents / badges on white cards**; card bodies and
the page background stay light.

## Palette (scoped under `.iptv-account`)

| Token | Hex | Used for |
|---|---|---|
| Navy | `#123B55` | Titles, totals, strong headings, primary CTA end |
| Teal | `#008F83` | Monthly rate, grand total, primary CTA start, identity icons |
| Emerald | `#0B9B70` | Active service, settled balance |
| Amber | `#D97706` (amber-600) | Expiring soon, scheduling |
| Coral | `#E24B50` | Disable action icon |
| Cyan | `#0891B2` / soft `#EAF8FC` | Projected-expiry info, pending |
| Danger | `#DC2626` / soft `#FEF2F2` | Owed balance, expired |
| Mint soft | `#E8F8F0` | Renewal header, grant hint |
| Slate | `#F1F5F9` | Quick-actions header, page bg |

The brighter palette is **scoped to `.iptv-account`** so it never leaks into the deliberately
white/muted global shell.

## Changes

### Header
- **De-duplicated the status badge** — the raw `sub.status` pill was removed; a single
  `StatusBadge` (tone from `expiryStateTone`) now sits next to a larger navy account reference.
- Customer, MC ID, Provider/Portal and MAC id render as a compact identity row with subtle icons
  (user / database / globe / wifi); the compact action bar (Edit · Enable/Disable · Notes · Advanced
  settings) is aligned beneath.

### Three summary cards (operational accounts)
- **Monthly rate** — teal icon tile, strong amount.
- **Service expiry** — icon tile + amount; the tile colour is now **dynamic**: green when active,
  amber when expiring soon, red when expired, navy otherwise (mapped from `expiryStateTone`). A small
  status badge distinguishes the service state (incl. suspension) from the raw date.
- **Outstanding balance** — **coral/red only when owed**, **emerald when settled** ("All settled").
  This tile is **connection-specific**; the customer-wide balance stays separate in the left summary.
- Icon tiles enlarged (42px), amounts promoted to H2; subtle hover lift that does **not** make the
  info cards look clickable.

### Left column
- The empty space under *Connection summary & expiry* is filled with a compact **Quick actions**
  card (slate header) — a 2-column tile grid wiring **existing** handlers only:
  Change monthly charge → `setShowChargeDrawer`, Change expiry date → `setShowExpiryDrawer`,
  Add note → `setHistTab('notes')`, Enable/Disable → `askToggleEnabled`. No new business operations;
  a one-line hint notes that the expiry drawer also offers "bring to current date". Shown only for
  non-cancelled accounts with the relevant permission (`canManage` / `canAdjust`). Cards are not
  stretched to match the taller renewal form (grid `align-items: start`).

### Credit & Renewal
- Mint panel header; trimmed intro copy; grouped package / credit / discount / pay-now controls.
- The large *Grant policy* alert box was replaced with a **compact one-line teal grant hint**
  (shield icon): "An invoice alone never extends service — only a paid-in-full renewal or an
  authorized override does."
- **Prominent price summary** — the Grand Total renders in large (H2) bold teal; the
  **projected-expiry preview** sits in a subtle cyan info strip (smaller, informational), clearly
  separating "what you pay" from "what service you get".
- Strong teal→navy gradient **Review & apply** CTA; secondary **Print quote**.
- The Quote / Invoice / Receipt workflow is preserved; **Pro Forma / Branded Reprint were not
  reintroduced**.

### Account history
- Segmented tabs with a strong navy active state (Invoices / Payments / Renewals-Credits / Notes /
  Activity); compact rows with hover; colour-coded status + outstanding chips (emerald PAID /
  danger owing); Print invoice per row and Print receipt only for recorded payments; friendlier
  empty states.

## Verification

### Live Playwright (real page, sub `IPTV-2026-0026`)
Captured before/after at desktop 1440, tablet 768, mobile 390, plus zoom emulation at 125 % / 150 % /
200 % (viewport widths 1152 / 960 / 720).

| Width | Horizontal overflow |
|---|---|
| Desktop 1440 | none (`sw == cw`) |
| Tablet 768 | none |
| Mobile 390 | none |
| Zoom 125 % (1152) | none |
| Zoom 150 % (960) | none |
| Zoom 200 % (720) | none |

- **Console errors: 0.**
- Quick-actions grid collapses to one column < 420px; summary tiles and the two columns stack on
  mobile; the history table scrolls **inside its card**, never the page.
- Screenshots: `screenshots/iptv-account-visual/iptv-{before,after}-{desktop,tablet,mobile}.png`.

### Automated
- **Frontend** `IptvPages.test.tsx` → **25 passed** (behaviour unchanged).
- `tsc -b` clean · `eslint src/pages/iptv/IptvDetailPage.tsx` clean · `npm run build` succeeds
  (pre-existing bundle-size advisory only).

## Files changed

- **Frontend:** `src/pages/iptv/IptvDetailPage.tsx` (header badge de-dup, dynamic summary-card tone,
  Quick actions card, trimmed intro, compact grant hint), `src/pages/iptv/iptv.css` (palette tokens
  + Quick actions grid, grant hint, panel intro, slate panel head, larger summary icon tiles,
  prominent grand total, subtle cyan expiry preview).
- **Backend (docs only):** this report + `screenshots/iptv-account-visual/`.

## Commits (no push)

- **Frontend:** `3b1533c` — IPTV account premium visual enhancement.
- **Backend:** this commit — IPTV account visual-enhancement report + screenshots.
