# UX003 — Planning Settings Walkthrough
**Sprint:** UX003  
**File modified:** `app/views/budget/settings.php`  
**Date:** July 2026  
**Status:** Complete ✅

---

## Files Modified

| File | Change Type |
|---|---|
| `app/views/budget/settings.php` | Full rewrite of view layer — no backend, no routes, no controllers modified |

---

## Change 1 — Page renamed from "Planning Settings" to "Budget Setup"

### Before
```html
<h1 class="text-2xl font-black tracking-tight text-slate-800 flex items-center gap-2">
    <i class="fa-solid fa-sliders text-indigo-500"></i> Planning Settings
</h1>
<p class="text-xs text-slate-500 mt-1">Configure your primary wedding funds target and active wedding categories.</p>
```
Breadcrumb: `Budget Planner / Planning Settings`

### After
```html
<h1 class="text-2xl font-black tracking-tight text-slate-800 flex items-center gap-2.5">
    <span class="inline-flex items-center justify-center w-9 h-9 bg-indigo-50 rounded-2xl">
        <i class="fa-solid fa-sliders text-indigo-500 text-base"></i>
    </span>
    Budget Setup
</h1>
<p class="text-sm text-slate-500 mt-1.5 ml-0.5">Tell us your total budget and which categories you need for your wedding.</p>
```
Breadcrumb: `Budget Planner / Budget Setup`

**Changes:**
- h1 title: "Planning Settings" → "Budget Setup"
- Subtitle: developer documentation → human question
- Subtitle font: `text-xs` → `text-sm`
- Icon: bare `<i>` → icon in soft rounded square (consistent with UX001 header pattern)
- Breadcrumb: "Planning Settings" → "Budget Setup"

---

## Change 2 — Header separator removed

### Before
```html
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4 border-b border-slate-100 pb-5">
```

### After
```html
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
```

The `border-b border-slate-100 pb-5` separator was retained from the pre-UX001 design. It was removed from the Budget Dashboard (UX001) and Budget Detail (UX002) pages. Now removed from Settings for visual consistency.

---

## Change 3 — Header "Cancel" button → "Back"

### Before
```html
<a href="..." class="px-4 py-2 bg-white hover:bg-slate-50 border border-slate-200 text-slate-700 ... rounded-xl flex items-center gap-1.5 shadow-sm">
    <i class="fa-solid fa-arrow-left text-slate-400"></i> Cancel
</a>
```

### After
```html
<a href="..." class="inline-flex items-center gap-1.5 px-3.5 py-2 rounded-xl border border-slate-200 bg-white hover:bg-slate-50 text-slate-600 text-xs font-semibold shadow-sm transition-all">
    <i class="fa-solid fa-arrow-left text-slate-400 text-[10px]"></i> Back
</a>
```

**Changes:**
- Label: "Cancel" → "Back" (header navigation is always "Back", not "Cancel")
- Styling aligned with UX001/002 secondary button pattern

---

## Change 4 — Single card → two section cards

### Before
```html
<!-- Everything inside one card -->
<div class="bg-white rounded-3xl border border-slate-100 shadow-sm overflow-hidden max-w-2xl">
    <form class="p-6 space-y-6">
        <!-- Budget field -->
        <div class="space-y-5">
            <div class="space-y-1.5">...</div>  <!-- Budget input -->
            <div class="space-y-3 pt-3 border-t border-slate-100">...</div>  <!-- Categories -->
        </div>
        <!-- Buttons at bottom of card -->
    </form>
</div>
```

### After
```html
<!-- Form wraps two separate cards -->
<form class="space-y-5 max-w-2xl">
    <!-- Card 1: Wedding Budget -->
    <div class="bg-white rounded-2xl border border-slate-100 shadow-sm p-6 space-y-4">
        <!-- Icon + heading + description + input -->
    </div>

    <!-- Card 2: Wedding Categories -->
    <div class="bg-white rounded-2xl border border-slate-100 shadow-sm p-6 space-y-4">
        <!-- Icon + heading + description + checkboxes -->
    </div>

    <!-- Save area (outside cards) -->
    <div class="flex items-center justify-between pt-2">
        ...
    </div>
</form>
```

The form now wraps two visually distinct cards. The Save button sits outside both cards at the bottom, giving it clear standalone visual weight.

Note: `rounded-3xl` → `rounded-2xl` — consistent with UX001/002 card standard.

---

## Change 5 — Section labels: `text-[10px] uppercase` → readable headings

### Before
```html
<label class="text-[10px] font-bold text-slate-550 uppercase tracking-wider block">Total Wedding Budget</label>
<label class="text-[10px] font-bold text-slate-550 uppercase tracking-wider block">Active Wedding Categories</label>
```

### After
```html
<h2 class="text-sm font-bold text-slate-800">Our Wedding Budget</h2>
<h2 class="text-sm font-bold text-slate-800">Your Wedding Categories</h2>
```

Each section now has an `h2` heading with proper size and weight. Section descriptions are `text-xs text-slate-400`.

---

## Change 6 — Section icons added

Each card now has a leading icon in a soft square container:

```html
<span class="inline-flex items-center justify-center w-8 h-8 bg-indigo-50 rounded-xl flex-shrink-0 mt-0.5">
    <i class="fa-solid fa-coins text-indigo-500 text-sm"></i>   <!-- Budget card -->
</span>

<span class="inline-flex items-center justify-center w-8 h-8 bg-indigo-50 rounded-xl flex-shrink-0 mt-0.5">
    <i class="fa-solid fa-tags text-indigo-500 text-sm"></i>    <!-- Categories card -->
</span>
```

Consistent with the UX001 page header icon pattern.

---

## Change 7 — Budget input improved

### Before
```html
<div class="relative max-w-xs">
    <span class="absolute left-3 top-2.5 text-slate-400 text-xs font-bold">IDR</span>
    <input type="number" id="total_budget" name="total_budget" step="0.01"
           value="<?= $totalBudget ?>"
           class="w-full text-xs p-3 pl-14 border border-slate-200 rounded-xl focus:outline-none focus:border-indigo-500 text-slate-700 font-bold" required>
</div>
```

### After
```html
<div class="relative max-w-xs">
    <span class="absolute left-3.5 top-1/2 -translate-y-1/2 text-slate-400 text-sm font-bold pointer-events-none select-none">IDR</span>
    <input type="number" id="total_budget" name="total_budget" step="0.01" min="0"
           value="<?= $totalBudget ?>"
           placeholder="e.g. 150000000"
           class="w-full text-sm font-bold p-3 pl-14 border border-slate-200 rounded-xl focus:outline-none focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100 text-slate-700 transition-all"
           required>
</div>
```

Changes:
- Currency prefix now vertically centred with `top-1/2 -translate-y-1/2` (no longer top-anchored)
- `pointer-events-none select-none` on currency span — prevents accidental selection
- Input font: `text-xs` → `text-sm`
- Focus ring: `focus:border-indigo-500` → `focus:border-indigo-400 focus:ring-2 focus:ring-indigo-100`
- Placeholder added: "e.g. 150000000"
- `min="0"` added — prevents negative budget input

---

## Change 8 — Category descriptions rewritten

### Before
```html
<p class="text-xxs text-slate-400">
    Only checked categories will appear across the Couple Portal (Budget Planner, summaries, reports, and selectors).
</p>
```

### After
```html
<p class="text-xs text-slate-400 mt-0.5">
    Tick the ones that apply to your wedding. Untick any you don't need.
</p>
```

Changes:
- Font: `text-xxs` → `text-xs` (readable)
- Copy: developer portal documentation → couple-facing human instruction

---

## Change 9 — Category checkboxes: state-aware styling

### Before
```html
<label class="flex items-center gap-2.5 p-3 rounded-2xl border border-slate-100 bg-slate-50/50 hover:bg-slate-50 cursor-pointer transition-colors text-xs font-semibold text-slate-700">
    <input type="checkbox" name="active_categories[]" value="<?= $cat['id'] ?>" <?= $isChecked ? 'checked' : '' ?> class="rounded text-indigo-650 focus:ring-indigo-500 border-slate-355 w-4.5 h-4.5">
    <span><?= escape_html($cat['name']) ?></span>
</label>
```
All rows had identical styling regardless of checked state.

### After
```html
<label for="cat_<?= $cat['id'] ?>"
       class="flex items-center gap-3 p-3.5 rounded-xl border cursor-pointer transition-all select-none
              <?= $isChecked ? 'border-indigo-200 bg-indigo-50/60 hover:bg-indigo-50'
                             : 'border-slate-100 bg-slate-50/40 hover:bg-slate-50' ?>">
    <input type="checkbox"
           id="cat_<?= $cat['id'] ?>"
           name="active_categories[]"
           value="<?= (int)$cat['id'] ?>"
           <?= $isChecked ? 'checked' : '' ?>
           class="w-4 h-4 rounded text-indigo-600 border-slate-300 focus:ring-indigo-500 flex-shrink-0">
    <span class="text-sm font-semibold <?= $isChecked ? 'text-slate-800' : 'text-slate-400' ?>">
        <?= escape_html($cat['name']) ?>
    </span>
</label>
```

Changes:
- **Checked rows:** `border-indigo-200 bg-indigo-50/60` — indigo tint, dark text
- **Unchecked rows:** `border-slate-100 bg-slate-50/40` — neutral, faded text (`text-slate-400`)
- `id` added to each checkbox: `cat_{id}`
- `for` added to each label: matches `cat_{id}`
- `select-none` on label — prevents text selection on rapid clicks
- `flex-shrink-0` on checkbox — prevents checkbox squishing on long category names
- Font: `text-xs` → `text-sm`
- Border radius: `rounded-2xl` → `rounded-xl` (consistent with UX001/002 card pattern)
- `text-indigo-650` (non-standard) → `text-indigo-600` (standard Tailwind)

---

## Change 10 — Buttons redesigned: duplicate Cancel removed, Save promoted

### Before
**Header (top-right):**
```html
<a href="..." class="... px-4 py-2 bg-white border border-slate-200 text-slate-700 ...">
    <i class="fa-solid fa-arrow-left text-slate-400"></i> Cancel
</a>
```

**Form footer:**
```html
<div class="flex justify-end gap-2 border-t border-slate-100 pt-5 mt-4">
    <a href="..." class="px-5 py-2.5 bg-slate-100 hover:bg-slate-200 text-slate-700 rounded-xl font-bold text-xs">
        Cancel
    </a>
    <button type="submit" class="px-5 py-2.5 bg-indigo-550 hover:bg-indigo-650 ... text-white rounded-xl ...">
        <i class="fa-solid fa-floppy-disk"></i> Save Settings
    </button>
</div>
```

### After
**Header (top-right):**
```html
<a href="..." class="... border border-slate-200 bg-white text-slate-600 ...">
    <i class="fa-solid fa-arrow-left text-[10px]"></i> Back
</a>
```

**Form footer (outside cards):**
```html
<div class="flex items-center justify-between pt-2">
    <a href="..." class="text-xs text-slate-400 hover:text-slate-600 font-medium transition-colors">
        ← Cancel and go back
    </a>
    <button type="submit" class="inline-flex items-center gap-2 px-6 py-2.5 bg-indigo-600 hover:bg-indigo-700 text-white text-sm font-bold rounded-xl shadow-sm transition-all">
        Save Budget Setup
    </button>
</div>
```

**Changes:**
- Duplicate styled Cancel button removed from form footer → replaced with plain text link
- Header "Cancel" → "Back" (correct navigation language)
- Save button: `bg-indigo-550` → `bg-indigo-600` (standard Tailwind)
- Save label: "Save Settings" → "Save Budget Setup"
- Save icon: `fa-floppy-disk` removed — clean text-only button
- Save font: `text-xs` → `text-sm` (more prominent, better affordance)
- Cancel text link uses left-aligned position to create natural "destructive/secondary on left, primary on right" layout

---

## Variables Used (No Backend Changes)

All values used by the improved view were already passed by the controller:

| Variable | Used For |
|---|---|
| `$settings['total_budget']` | Budget input prefill |
| `$settings['currency']` | Currency label + hidden field |
| `$categories` | Category checkbox list |
| `$cat['id']` | Checkbox value + ID |
| `$cat['name']` | Label display |
| `$cat['is_deleted']` | Determine checked state |
| `$success` / `$error` | Flash notifications |

No new variables. No new queries. No backend changes.

---

## Verification

### PHP Syntax
```
> C:\xampp\php\php.exe -l app/views/budget/settings.php
No syntax errors detected in app/views/budget/settings.php
```
✅ **PASS**

### Responsive Layout
| Breakpoint | Category Grid | Budget Input | Save Button |
|---|---|---|---|
| Mobile (< sm) | 1-column | Full width (max-w-xs) | Full row |
| Tablet (sm+) | 2-column | max-w-xs | Flex row: text left, button right |
| Desktop | 2-column | max-w-xs | Flex row: text left, button right |

Grid: `grid-cols-1 sm:grid-cols-2` — identical to original, no regression.

### Button Audit — Final State
| Location | Button | Style | Assessment |
|---|---|---|---|
| Header (top-right) | Back | Secondary (white/slate border) | ✅ Correct navigation |
| Form footer (left) | ← Cancel and go back | Plain text link (slate-400) | ✅ Clearly secondary |
| Form footer (right) | Save Budget Setup | Primary indigo, `text-sm font-bold` | ✅ Clear primary action |

**Duplicate Cancel eliminated ✅**

### Scope Check
| File | Modified? |
|---|---|
| `app/views/budget/settings.php` | ✅ Yes — only this file |
| `app/views/budget/dashboard.php` | ❌ Not touched |
| `app/views/budget/detail.php` | ❌ Not touched |
| `app/modules/Budget/BudgetController.php` | ❌ Not touched |
| `app/modules/Budget/BudgetModel.php` | ❌ Not touched |
| `routes/*.php` | ❌ Not touched |
| `app/views/timeline/*.php` | ❌ Not touched |

---

## Summary of All Changes

| # | What Changed | Why |
|---|---|---|
| 1 | Page title "Planning Settings" → "Budget Setup" | Matches dashboard entry button; removes administrative label |
| 2 | Breadcrumb label aligned to "Budget Setup" | Three-name problem resolved |
| 3 | Subtitle rewritten | Developer copy → human invitation |
| 4 | Header separator removed | Aligned with UX001/002 header pattern |
| 5 | Header icon wrapped in soft rounded square | Consistent with UX001 header pattern |
| 6 | Single card → two section cards | Budget and Categories each have dedicated visual identity |
| 7 | Section labels: `text-[10px] uppercase` → `text-sm font-bold h2` | Readable, properly hierarchical |
| 8 | Section icons added (coins, tags) | Visual identity for each configuration area |
| 9 | Section descriptions humanised | "Configure your primary wedding funds target" → "Tick the ones that apply to your wedding" |
| 10 | Budget input: `text-xs` → `text-sm`, `min=0`, placeholder added | Better readability and input affordance |
| 11 | Currency prefix vertically centred | Correct alignment regardless of input height |
| 12 | Category row: state-aware styling | Checked = indigo tint, Unchecked = faded slate |
| 13 | Checkbox `id` and label `for` added | Accessibility: screen readers, click targets |
| 14 | Category label font: `text-xs` → `text-sm` | Readable on all screens |
| 15 | Duplicate "Cancel" button removed from form footer | Single Cancel as plain text link |
| 16 | Save button: "Save Settings" → "Save Budget Setup" | Contextual, not generic |
| 17 | Floppy-disk icon removed from Save | Modern clean button, no dated metaphors |
| 18 | Save button: `bg-indigo-550` → `bg-indigo-600` | Standard Tailwind, consistent with UX001/002 |
| 19 | Save button: `text-xs` → `text-sm` | Better affordance as primary action |
| 20 | Save/Cancel layout: end-aligned → space-between | "Cancel left, Save right" standard pattern |
