# Vault-Offers Styling Implementation Guide

## Overview

Vault-Offers is a feature flag that enables compact, small-sized UI styling for users with `whitelabel_offers_only` enabled. This styling is applied across Task management pages and other areas of the application.

## Core Concept

All vault-offers styling is **conditional** - changes only apply to users with the feature flag enabled. Non-vault-offers users see the original large styling.

## CSS Position Direction — IMPORTANT

**When adjusting placeholder or element positioning with `top`, `bottom`, `left`, `right` properties:**
- **Positive values (e.g., `top: 6px`)** move the element DOWN/RIGHT (away from that edge)
- **Negative values (e.g., `top: -3px`)** move the element UP/LEFT (toward that edge)

Examples:
- `top: 6px` = 6 pixels down from the top
- `top: -3px` = 3 pixels up from the top (negative moves opposite direction)
- `left: 10px` = 10 pixels right from the left edge
- `left: -5px` = 5 pixels left from the left edge (negative moves opposite direction)

**Common mistake:** Trying to move something up by increasing the `top` value. The direction is **opposite** to what the property name suggests.

## Styling System

### 1. CSS Foundation: `VaultOffersCommon.css`
- Located at: `src/containers/VaultOffers/VaultOffersCommon.css`
- Centralized CSS utilities for all vault-offers styling
- Imported in components that use vault-offers features
- DO NOT put vault-offers styles in component-specific CSS files

### 2. JavaScript Styles: `VAULT_OFFERS_STYLES.js`
- Located at: `src/containers/VaultOffers/VAULT_OFFERS_STYLES.js`
- Reusable inline style objects for React components
- Import and use: `import { VAULT_OFFERS_STYLES } from '../VaultOffers/VAULT_OFFERS_STYLES';`

**Available styles:**
- `VAULT_OFFERS_STYLES.inputStyle` - padding: 2px 4px, height: 22px, fontSize: 0.8em
- `VAULT_OFFERS_STYLES.fieldStyle` - marginBottom: 2px
- `VAULT_OFFERS_STYLES.labelStyle` - font-size: 0.65em, fontWeight: bold
- `VAULT_OFFERS_STYLES.buttonStyle` - small button sizing
- `VAULT_OFFERS_STYLES.checkboxSmall` - width/height: 14px

## Quick Checklist: What to Fix Every Time You Add Vault-Offers Styling

**BEFORE** you finish applying vault-offers styling to a page, check EVERY item below in both the React component AND the CSS file:

**React Component:**
- ✅ Add page wrapper class: `className={isVaultOffers ? 'vault-offers-<pagename>' : ''}`
- ✅ Add `.vault-offers-input` className to ALL text inputs
- ✅ Add `.vault-offers-input` className to ALL select/dropdown elements
- ✅ Add `.vault-offers-input` className to ALL date inputs
- ✅ Add `.vault-offers-input` className to ALL textarea inputs
- ✅ Remove ANY inline `style={isVaultOffers ? VAULT_OFFERS_STYLES.inputStyle : {}}` (CSS classes handle this)
- ✅ No conflicting inline styles on input elements

**VaultOffersCommon.css:**
- ✅ Add `.vault-offers-<pagename>` to multi-selector CSS variable block with `--input-placeholder-top: 1.9rem;`
- ✅ **CRITICAL:** Add focus placeholder rules for BOTH `.input` and `.inputLG`:
  - ✅ `.vault-offers-<pagename> .input:focus + .input__placeholder,`
  - ✅ `.vault-offers-<pagename> .inputLG:focus + .input__placeholder { top: 15px !important; }`
- ✅ **CRITICAL:** Add BOTH placeholder styling rules:
  - ✅ `.vault-offers-<pagename> .input__placeholder--datain` rule: `top: 15px`, `left: 30px`, `font-size: 0.9em` (floating labels)
  - ✅ `.vault-offers-<pagename> .input__placeholder:not(.input__placeholder--datain)` rule: `font-size: 0.8em` (regular placeholders)
- ✅ Add `.vault-offers-<pagename> select` rule IF page has dropdowns: `font-size: 0.8em`, `height: 22px`, `padding: 0 4px`
- ✅ Add `.vault-offers-<pagename> .input__selectChevron` rule IF page has select inputs: `top: 2.1rem`, `right: 1.25rem`, `font-size: 0.8em`
- ✅ Add `.vault-offers-<pagename> input[type="date"]` rule IF page has dates: `font-size: 0.8em`, `height: 22px`, `padding: 0 4px`
- ✅ Add `.vault-offers-<pagename> textarea` rule IF page has textareas: `font-size: 0.8em`, `padding: 0 4px`
- ✅ Add `.vault-offers-<pagename>-modal` rule IF page has modals: `padding: 2px 4px`

**MOST COMMON MISTAKES (what breaks pages):**
- ❌ **Input wrappers still large after applying `.vault-offers-input` class** → **MISSING THE NON-INPUTLG INPUT WRAPPER CSS RULES!** This is the #1 forgotten step. You MUST add:
  ```css
  .vault-offers-[page] .input__wrapper {
      height: auto !important;
      margin-bottom: 4px !important;
      box-sizing: border-box !important;
  }
  .vault-offers-[page] .input__wrapper input {
      font-size: 0.8em !important;
      height: 22px !important;
      padding: 2px 4px !important;
  }
  ```
  **Without these rules, inputs stay at full height (6.6rem) even though the `.vault-offers-input` class was added.** The class only works if the wrapper and child input elements are explicitly sized in CSS.
- ❌ Text appears too large → missing select/input[type="date"] CSS rules
- ❌ Placeholder text too large or not styled → **missing BOTH `.input__placeholder--datain` AND `.input__placeholder:not(.input__placeholder--datain)` rules** (this is easy to forget!)
- ❌ Placeholder not moving on focus → missing `.input__placeholder--datain` CSS rule
- ❌ Wrapper padding broken → forgot to remove inline `style={VAULT_OFFERS_STYLES.inputStyle}` props
- ❌ Placeholder misaligned → missing `--input-placeholder-top: 1.9rem;` CSS variable
- ❌ **Buttons still large even though text is small** → missing `height` property on button rules. Must have: `height: 28px`, `min-height: 28px`, `line-height: 28px` (not `line-height: 1`), plus `display: flex`, `align-items: center`, `justify-content: center`
- ❌ **Modal inputs not styled properly** → missing CSS variables on modal class. **CRITICAL:** When a page has modals with Input components, add CSS variables directly to the modal class itself: `.vault-offers-[page]-modal { --input-placeholder-top: 1.9rem; --input-inputLG-wrapper-height: 1.5rem; }` This is often the MAIN FIX that makes Input styling work in modals.

## How to Add Vault-Offers Styling to a New Page

### Step 0: CRITICAL - Import VaultOffersCommon.css
**This is the most commonly forgotten step!** Without this import, NONE of the CSS rules will apply.
```jsx
import '../VaultOffers/VaultOffersCommon.css';  // REQUIRED - Add this to every component
```
If you don't see styling changes on the page after adding vault-offers classes, check this import first.

### Step 1: Import Required Dependencies
```jsx
import { VAULT_OFFERS_STYLES } from '../VaultOffers/VAULT_OFFERS_STYLES';
import '../VaultOffers/VaultOffersCommon.css';
```

### Step 2: Get Feature Flag from Redux
In your mapStateToProps (for class components):
```jsx
myprofile: state.myprofile,
```

In component:
```jsx
const isVaultOffers = myprofile && myprofile.features && myprofile.features.whitelabel_offers_only;
```

For functional components, use useSelector:
```jsx
const isVaultOffers = useSelector(state => 
  state.myprofile?.features?.whitelabel_offers_only
);
```

### Step 3: Apply Conditional Styling

#### Input Elements (Raw `<input>`)
Raw HTML inputs can use inline styles:
```jsx
<input
  className={`input primaryBorderWithFocus ${isVaultOffers ? 'vault-offers-input' : ''}`}
  style={isVaultOffers ? VAULT_OFFERS_STYLES.inputStyle : {}}
  type="text"
/>
```

#### Input Components (Custom `<Input>`) — **IMPORTANT**
**Do NOT apply inline styles to `<Input>` components.** The Input component wraps elements in a way that breaks layout when inline styles conflict with CSS. Only use className:
```jsx
<Input
  placeholder="Field Name"
  type="text"
  className={isVaultOffers ? 'vault-offers-input' : ''}
/>
```
All sizing, padding, line-height, and alignment is handled by CSS rules in `VaultOffersCommon.css`. Using inline `style` prop on Input components will cause:
- Overlapping clickable areas between inputs
- Text rendering in wrong positions
- Broken form layout

**Rule:** className only for `<Input>` components, CSS handles all styling.

#### Input Component CSS Variables — Important for Placeholder Positioning

The `<Input>` component uses inline style attributes with CSS variables to control spacing for floating placeholders. The most important variable is:
- **`--input-placeholder-top`** — Controls how far down the placeholder sits inside the input before it floats up on focus/text input

When placeholders don't align correctly in vault-offers styling:
1. Check if the Input component is setting `style="--input-placeholder-top: 2.10rem"` or similar
2. For vault-offers pages, you may need to override this variable via CSS
3. Add a CSS rule targeting the page: `.vault-offers-[page-name] { --input-placeholder-top: 1.9rem; }` (adjust value as needed)
4. This controls the vertical space allocated for the placeholder to float into

**Note:** This is a structural issue with how Input components allocate space for floating placeholders. When adding vault-offers styling to a new page with many Input components, check placeholder alignment and adjust the CSS variable if needed.

## Fixing Spacing Issues on New Pages

### Problem 1: Inputs Covering Each Other (Clickability Issue)

**Symptoms:** Cannot click on inputs in a form; clicking above the target input activates it instead.

**Root Cause:** `.input__wrapper` has default `height: 6.6rem` (105.6px) set by CSS variable `--input-inputLG-wrapper-height`. Even when the actual input is 22px tall, the wrapper stays huge, covering inputs below.

**Solution:** Set the CSS variable for the page and use `height: auto` for large input wrappers:
```css
.vault-offers-[page-name] {
    --input-inputLG-wrapper-height: 1.5rem;  /* Shrink file upload wrapper */
}

/* Regular text inputs - stay compact */
.vault-offers-[page-name] .input__wrapper {
    margin-bottom: 1px !important;
    box-sizing: border-box !important;
}

/* Large inputs (textareas, file uploads) - auto-expand to content */
.vault-offers-[page-name] .inputLG__wrapper {
    height: auto !important;  /* CRITICAL: prevents covering next input */
    margin-bottom: 1px !important;
    box-sizing: border-box !important;
}
```

**Why:** Regular inputs are 22px; `inputLG__wrapper` (used for textareas) needs `height: auto` so it expands to fit content without staying 105px tall.

### Problem 2: Large Gaps Between Inputs (Visual Spacing)

Input wrappers have default `margin: 1rem 0` (16px top and bottom), creating huge gaps in vault-offers' compact layout. 

**Solution:** Override the margin in your vault-offers CSS (use 1px, not 0.5rem):
```css
.vault-offers-[page-name] .input__wrapper,
.vault-offers-[page-name] .inputLG__wrapper {
    margin-bottom: 1px !important;  /* Very tight spacing */
}

### Problem: Datain Placeholders Floating Too High/Low

When placeholders float UP on focus/text input, they may appear in wrong position:
- **Too high:** Increase the `top` value (positive = down)
- **Too low:** Decrease the `top` value (smaller = up)

```css
.vault-offers-[page-name] .input__placeholder--datain {
    top: 15px !important;      /* Adjust based on input type */
    left: 30px !important;
    font-size: 0.9em !important;
}
```

Different input types may need different values. Test password, date, and text inputs - they may have different optimal positioning.

## CSS Variables Used by Input Components

Input components set inline style attributes with CSS variables. These can be overridden in vault-offers CSS:

| Variable | Default | Purpose | Override Example |
|---|---|---|---|
| `--input-placeholder-top` | `2.10rem` | Space allocated for placeholder to float up | `--input-placeholder-top: 1.9rem` |
| `--input-inputLG-wrapper-height` | `2.5rem` | Height of file upload wrapper | `--input-inputLG-wrapper-height: 1.5rem` |
| `--input-inputLG-file-height` | `2.5rem` | Height of file upload input | `--input-inputLG-file-height: 1.5rem` |

**How to override variables:**
```css
.vault-offers-[page-name] {
    --input-placeholder-top: 1.9rem;
    --input-inputLG-wrapper-height: 1.5rem;
    --input-inputLG-file-height: 1.5rem;
}
```

## Diagnosing Spacing Problems

1. **Inspect the element in Chrome DevTools** (F12)
2. **Look for** `style` attribute showing CSS variables
3. **Check Computed Styles** for actual margin/padding/height values
4. **Identify which variable** is causing the issue
5. **Override it** in your vault-offers CSS block for the page

#### Buttons
```jsx
<Button
  className={isVaultOffers ? 'button__success vault-offers-button' : 'button__success'}
  onClick={handleClick}
>
  Click Me
</Button>
```

#### Modal Styling with Input Components

When a modal has `<Input>` components (custom Input component, not raw HTML inputs), the modal's Modal.Body needs special CSS variables added. This is **the critical fix** that makes Input component styling work in modals:

```jsx
// In parent component (e.g., Photos.js)
<Modal show={showModal} onHide={closeModal}>
  <Modal.Header closeButton>
    <Modal.Title>Add New Photo</Modal.Title>
  </Modal.Header>
  <Modal.Body className={isVaultOffers ? 'vault-offers-photo-add-modal' : ''}>
    <Input
      placeholder='Photo Title'
      type='text'
      className={isVaultOffers ? 'vault-offers-input' : ''}
    />
    {/* more Input components */}
  </Modal.Body>
</Modal>
```

**CSS Rule Required in VaultOffersCommon.css:**
```css
.vault-offers-photo-add-modal {
    --input-placeholder-top: 1.9rem;           /* CRITICAL: Controls placeholder positioning */
    --input-inputLG-wrapper-height: 1.5rem;    /* CRITICAL: Prevents large file upload wrappers */
}

/* Input wrapper spacing */
.vault-offers-photo-add-modal .input__wrapper,
.vault-offers-photo-add-modal .inputLG__wrapper {
    margin-bottom: 7px !important;
    box-sizing: border-box !important;
}

/* Placeholder styling */
.vault-offers-photo-add-modal .input__placeholder--datain {
    top: 15px !important;
    left: 30px !important;
    font-size: 0.9em !important;
}

/* Select/dropdown styling */
.vault-offers-photo-add-modal select {
    font-size: 0.8em !important;
    height: 22px !important;
    padding: 0px 4px !important;
}

/* Select chevron positioning for dropdowns in modal */
.vault-offers-photo-add-modal .input__selectChevron {
    top: 2.1rem !important;
    right: 1.25rem !important;
    font-size: 0.8em !important;
}
```

**Why this works:** Input components use CSS variables to control placeholder positioning and wrapper height. Without these variables set on the modal class, Input components in modals will use the default 2.1rem placeholder top and 6.6rem wrapper height — way too large for vault-offers. The variables MUST be set on the modal class itself to apply to all child Input components.

**IMPORTANT - Select Chevron Positioning:** Any modal with select/dropdown inputs needs the `.input__selectChevron` rule. Without it, the dropdown arrow appears outside/below the input. Standard values: `top: 2.1rem`, `right: 1.25rem`, `font-size: 0.8em`.

#### Non-inputLG Input Wrappers (Regular Text Inputs)

**ANY** page or modal with regular text inputs (NOT file uploads) uses the standard `.input__wrapper` class. These wrappers need explicit sizing rules for vault-offers. This applies to both modals AND regular page content.

**React Implementation:**
```jsx
<div className="input__wrapper">
  <Input
    type="text"
    placeholder="Field Name"
    className={isVaultOffers ? 'vault-offers-input' : ''}
  />
</div>
```

**CSS Rules Required in VaultOffersCommon.css:**
```css
.vault-offers-[page-name] .input__wrapper {
    margin-bottom: 4px !important;      /* Reduce spacing between inputs */
    height: auto !important;             /* Prevent wrapper from taking full height */
    box-sizing: border-box !important;
}

.vault-offers-[page-name] .input__wrapper input {
    font-size: 0.8em !important;         /* Match compact input sizing */
    height: 22px !important;             /* Standard vault-offers input height */
    padding: 2px 4px !important;         /* Compact padding */
}
```

**Why:** Regular input wrappers have large default height and margins. Without explicit sizing on child inputs, they stay oversized. The `height: auto` on the wrapper and small font/height on the input element force compact rendering.

**For Modals:** Use same rules but with modal class: `.vault-offers-[page]-modal .input__wrapper`

#### Button Sizing - CRITICAL

Buttons often remain large even after reducing font-size because they lack explicit height properties. **MUST include ALL of these properties** for buttons to size correctly:

```css
.vault-offers-[page-name] .button__primary {
    font-size: 0.85em !important;
    height: 28px !important;              /* CRITICAL: explicit height */
    min-height: 28px !important;          /* CRITICAL: prevents button shrinking */
    line-height: 28px !important;         /* CRITICAL: must equal height for vertical centering */
    padding: 6px 12px !important;
    display: flex !important;              /* CRITICAL: enables centering */
    align-items: center !important;       /* CRITICAL: centers content vertically */
    justify-content: center !important;   /* CRITICAL: centers content horizontally */
}
```

**Why:** Default `.button` class has `line-height: 3.6rem` and large default height. Without explicit `height: 28px` and `line-height: 28px` (which must be equal), buttons appear oversized. The flex properties ensure text centers inside the small button instead of appearing below it.

**Common mistake:** Using `line-height: 1` instead of explicit `line-height: 28px` — text will float inside the button instead of centering.

**Apply to:** `.button__primary`, `.button__success`, `.button__warning`, `.button__flatPrimary`, and any other button classes on the page

#### Modal Header, Body, Footer Padding

Modal containers should have minimal padding for compact vault-offers layout:

**CSS Rules Required in VaultOffersCommon.css:**
```css
.vault-offers-[page]-modal .modal-header {
    padding: 4px 8px !important;
    font-size: 0.9em !important;
}

.vault-offers-[page]-modal .modal-body {
    padding: 4px 8px !important;
}

.vault-offers-[page]-modal .modal-footer {
    padding: 4px 8px !important;
    display: flex !important;             /* Keep buttons side-by-side */
    gap: 4px !important;                 /* Space between buttons */
    justify-content: flex-end !important; /* Buttons align right */
}
```

**Important:** The `display: flex` on `modal-footer` is CRITICAL. Without it, buttons may stack vertically instead of staying side-by-side.

#### Modal Buttons Layout

Modal footer buttons need both sizing rules AND proper flex layout to prevent text from appearing below the button:

**React Implementation:**
```jsx
<Modal className={isVaultOffers ? 'vault-offers-[page]-modal' : ''}>
  <Modal.Footer>
    <Button className='button__primary' onClick={handleClose}>Close</Button>
    <Button className='button__primary' onClick={handleDelete}>Delete</Button>
  </Modal.Footer>
</Modal>
```

**CSS Rules Required in VaultOffersCommon.css:**
```css
.vault-offers-[page]-modal .button__primary {
    font-size: 0.8em !important;
    height: 24px !important;
    padding: 4px 8px !important;
    min-height: 24px !important;
    line-height: 1 !important;  /* Prevent text from appearing below button */
}
```

**Important:** Use `line-height: 1` (not `line-height: 24px`) to center text vertically inside the compact button. With `line-height: 24px`, text sits at the bottom of a 24px button and appears below it.

#### Modal Buttons (Full Example)
- Modal footer buttons need special handling because modals are often rendered in a parent container
- **Issue:** `.button__success` has `line-height: 3.6rem` from the base `.button` rule, which pushes text down below compact 18px buttons
- **Solution:** Apply vault-offers class to the Modal component, then use CSS to override line-height:
```jsx
// In parent component (e.g., Documents.js)
<Modal className={isVaultOffers ? 'vault-offers-documents' : ''}>
  <Modal.Header>Add Document</Modal.Header>
  <Modal.Body>
    {/* form content */}
  </Modal.Body>
  <Modal.Footer>
    <Button className='button__success' onClick={handleSave}>ADD</Button>
  </Modal.Footer>
</Modal>
```

**CSS Rule Required in VaultOffersCommon.css:**
```css
.vault-offers-[page-name] .modal-footer .button__success,
.vault-offers-[page-name] .modal-footer button.button__success {
    line-height: 18px !important;  /* Override 3.6rem from base .button rule */
    height: 18px !important;       /* Match button height */
}
```

- **IMPORTANT:** Only apply this to modals within vault-offers contexts (add the vault-offers class to Modal)
- **Do NOT** apply button styling globally to all `.modal-footer .button__success` — this would break modals on pages without vault-offers styling
- Example: `.vault-offers-documents .modal-footer .button__success { line-height: 18px !important; }`

#### Checkboxes
```jsx
<input
  type="checkbox"
  style={isVaultOffers ? {width: '14px', height: '14px'} : {}}
/>
```

#### Labels/Titles
```jsx
<div className={isVaultOffers ? 'vault-offers-text-small' : ''}>
  Label Text
</div>
```

#### Wrapper Divs for Spacing
```jsx
<div className={isVaultOffers ? 'vault-offers-field' : ''}>
  {/* content */}
</div>
```

### Step 4: Handle Placeholder Text (Manual Inputs Only)

For manual input elements with placeholder labels, create a wrapper structure:

```jsx
<div style={{'width': '50%'}} className='input__wrapper'>
  <input
    className={`input primaryBorderWithFocus ${isVaultOffers ? 'vault-offers-input' : ''}`}
    style={isVaultOffers ? VAULT_OFFERS_STYLES.inputStyle : {}}
    type="date"
  />
  <div className={`input__placeholder input__placeholder--datain`}>
    Label Text
  </div>
</div>
```

### Step 5: Add CSS Rules if Needed

If your component/page has a unique class wrapper (like `.vault-offers-add-task` for AddTask), you may need custom CSS rules in `VaultOffersCommon.css`:

```css
/* For components without .vault-offers-field wrapper */
.vault-offers-[component-name] .input__placeholder--datain {
    top: 15px !important;
    left: 30px !important;
    font-size: 0.9em !important;
}
```

## Key CSS Classes

| Class | Use Case |
|-------|----------|
| `.vault-offers-input` | Applied to input elements (height 22px, padding 2px 4px, font-size 0.8em) |
| `.vault-offers-button` | Applied to buttons for proper sizing (height 28px, padding 6px 12px, font-size 0.85em) |
| `.vault-offers-tab-button` | Applied to tab navigation buttons (height 24px, padding 4px 8px, font-size 0.8em) |
| `.vault-offers-field` | Wrapper div for consistent spacing (margin-bottom 1px) |
| `.vault-offers-text-small` | For labels and smaller text (font-size 0.8em) |
| `.vault-offers-placeholder` | For placeholder text labels (font-size 0.9em) |
| `.vault-offers-compact-spacing` | For minimal padding/margin |
| `.vault-offers-wysiwyg-small` | For WYSIWYG editor and wrapper (smaller font, padding) |
| `.vault-offers-add-task` | Page-level wrapper class (AddTask only) |
| `.vault-offers-general-tab` | Page-level wrapper class (GeneralTab/Property Details) |
| `.vault-offers-page` | Page-level wrapper class (Property page wrapper) |

## Important Notes

### Spacing and Margins
- Input spacing is minimized for vault-offers users across all pages:
  - `.input__wrapper` margin-bottom: 1px (global reduction from 2px)
  - `.vault-offers-field` margin-bottom: 1px (reduced from 2px)
  - `.flex-wrapper-task` margins: 1px (reduced from 2px)
  - `.vault-offers-task-requirement` margin: 0px (reduced from 1px)
  - On GeneralTab (Property Details Overview/Occupancy) specifically:
    - `.vault-offers-general-tab` sets `--input-inputLG-wrapper-height: 1.5rem` (CSS variable for file upload dropzones)
    - `.property-field-header` font-size: 1rem (category headings like "Listing Information"), margin-bottom: 4px, margin-top: 6px
    - `.vault-offers-general-tab > div > div > div > div` margin-bottom: 1px, box-sizing: border-box
    - `.input__wrapper` box-sizing: border-box, max-width: 100%
    - `.wysiwyg-field-title` margin: 0.5rem (reduced from 1rem)
- This creates compact vertical spacing between inputs and sections
- Do NOT add extra margin/padding to inputs intended for vault-offers display

### Toggle Wrapper Spacing
- `.toggle__wrapper` elements can have large default margins that push toggles under inputs above them
- When applying vault-offers styling to pages with toggles (especially next to inputs), set `.toggle__wrapper` to `margin: 25px 0px` to prevent overlap
- **Check:** Always verify toggle positioning when styling pages with mixed input and toggle elements (e.g., Manage Online Offers)

### Layout Considerations - CRITICAL: Avoid Wrapper Divs That Break Layout
- **DO NOT wrap elements in `.vault-offers-field` or any vault-offers wrapper div if:**
  - Elements are meant to display side-by-side (e.g., 50% width columns, two-column layouts)
  - The wrapper would interfere with flex or grid layouts
  - Parent containers rely on specific DOM structure (like GeneralTab's two-column layout)
  
- **Why wrapper divs break layouts:**
  - `.vault-offers-field` is a block-level element that forces new lines
  - Two 50% width elements inside separate wrapper divs will stack instead of staying side-by-side
  - This breaks page layouts that depend on careful DOM structure

- **Solution - Apply styling directly to elements:**
  - Add `vault-offers-input` class directly to `<input>` and `<select>` elements
  - Apply `VAULT_OFFERS_STYLES.inputStyle` directly via style prop
  - Add conditional font-size to placeholders without extra wrapper divs
  - Only use `.vault-offers-field` for standalone, full-width form sections

### Placeholder Positioning
- Placeholder text that doesn't have `.vault-offers-field` wrapper needs a separate CSS rule
- Standard rule: `.vault-offers-field .input__placeholder--datain` applies top: 15px, left: 30px
- If inputs aren't in `.vault-offers-field`, create page-specific rule: `.vault-offers-[page] .input__placeholder--datain`

### Examples: What NOT to Do

**❌ WRONG - Wrapper div breaks two-column layout:**
```jsx
// This breaks side-by-side layout for GeneralTab
<div className={isVaultOffers ? 'vault-offers-field' : ''}>
  <div style={{'width': '50%'}} className='input__wrapper'>
    <input />
  </div>
  <div style={{'width': '50%'}} className='input__wrapper'>
    <input />
  </div>
</div>
```

**✅ RIGHT - Apply styling directly without wrapper:**
```jsx
// This keeps side-by-side layout intact
<select
  className={`input primaryBorderWithFocus ${isVaultOffers ? 'vault-offers-input' : ''}`}
  style={isVaultOffers ? VAULT_OFFERS_STYLES.inputStyle : {}}
/>
```

### Date Inputs
- Use raw `<input type="date">` elements, not `<Input type="date">` components
- Wrap in `input__wrapper` div with placeholder label
- Apply `VAULT_OFFERS_STYLES.inputStyle` directly to the input element

### Textarea/Area Inputs
- `<Input type="area">` components handle vault-offers styling automatically
- Don't apply height constraints that would hide content
- Use simple font-size adjustment if needed: `style={{fontSize: '0.8em'}}`

### WYSIWYG/Quill Editor Inputs
- Use ReactQuill component for rich text editing
- Apply `vault-offers-wysiwyg-small` class to both `editorClassName` and `wrapperClassName`
- Apply `vault-offers-text-small` class to the field label/title
- Reduce wrapper margin: `margin: isVaultOffers ? '0.5rem' : '1rem'`
- Reduce wrapper minHeight: `minHeight: isVaultOffers ? '5rem' : '10rem'`
- Example:
  ```jsx
  <div className={`wrapper ${isVaultOffers ? 'vault-offers-wysiwyg-small' : ''}`}
       style={{margin: isVaultOffers ? '0.5rem' : '1rem', minHeight: isVaultOffers ? '5rem' : '10rem'}}>
    <div className={`title ${isVaultOffers ? 'vault-offers-text-small' : ''}`}>Label</div>
    <ReactQuill
      editorClassName={`editor ${isVaultOffers ? 'vault-offers-wysiwyg-small' : ''}`}
      wrapperClassName={`wysiwygWrapper ${isVaultOffers ? 'vault-offers-wysiwyg-small' : ''}`}
      value={content}
      onChange={handler}
    />
  </div>
  ```

### Toggle/Slider Fields (Yes/No)
- Used for boolean fields like "Lockbox", occupancy toggles, etc.
- Pass `isVaultOffers` prop to Toggle component for compact styling
- Does NOT use wrapper div - styling applied directly to Toggle component
- Reduces toggle size (45px × 22px), circle size (18px × 18px), and label text (0.9em)
- Example:
  ```jsx
  <Toggle
    on={value === 'Yes'}
    onColor='green'
    offColor='red'
    onClick={handler}
    instructions={field.label}
    isVaultOffers={isVaultOffers}
  />
  ```

### Select/Dropdown Input Fields
- Apply `vault-offers-input` class and `VAULT_OFFERS_STYLES.inputStyle` to `<Input type="select">` components
- **CRITICAL:** Select boxes need additional CSS rule to reduce font-size inside `<select>` element
- For new pages, ALWAYS add this CSS rule (Input component doesn't apply vault-offers-input class to select element itself):
```css
.vault-offers-[page-name] select {
    font-size: 0.8em !important;        /* Match VAULT_OFFERS_STYLES.inputStyle */
    height: 22px !important;
    padding: 2px 4px !important;
    line-height: 1 !important;           /* Use line-height: 1 for vertical centering */
    vertical-align: middle !important;   /* Center text vertically in compact input */
}
```
- Example: `.vault-offers-expenses select { font-size: 0.8em !important; height: 22px !important; padding: 2px 4px !important; line-height: 1 !important; }`
- **Without this rule, select text appears large** and doesn't match other input sizing
- **IMPORTANT:** Use `line-height: 1` (not `line-height: 22px`) so text centers vertically in the small input. With `line-height: 22px`, text sits at bottom of input
- The values MUST match `VAULT_OFFERS_STYLES.inputStyle`: padding 2px 4px, height 22px, fontSize 0.8em

### Select Chevron (Dropdown Arrow) Positioning
- The `.input__selectChevron` element is positioned absolutely and needs adjustment for compact inputs
- **CSS Rule Required** for pages with select dropdowns:
```css
.vault-offers-[page-name] .input__selectChevron {
    top: 2.1rem !important;      /* Position chevron inside compact input */
    right: 1.25rem !important;   /* Align to right edge (inside input, not outside) */
    font-size: 0.8em !important; /* Scale down icon to match compact sizing */
}
```
- **Default positioning** (`top: 3rem; right: 2rem`) places chevron way below small inputs
- **Standard value for right:** Use `right: 1.25rem` so chevron stays inside the input, not pushed outside
- **Adjust `top` value** if chevron is showing above or below the input (positive values move down)
- Example: `.vault-offers-add-document .input__selectChevron { top: 2.1rem !important; right: 1.25rem !important; }`

### Date and Time Input Fields
- Use raw `<input type="date">` and `<input type="time">` elements
- Apply `vault-offers-input` class and `VAULT_OFFERS_STYLES.inputStyle` inline styles
- Add a placeholder div with `input__placeholder--datain` class
- Adjust placeholder positioning for vault-offers: `top: isVaultOffers ? '15px' : '-.5rem'`
- **CRITICAL CSS Rule Required:** Add to VaultOffersCommon.css for pages with date/time inputs:
```css
.vault-offers-[page-name] input[type="date"],
.vault-offers-[page-name] input[type="time"] {
    font-size: 0.8em !important;
    height: 22px !important;
    padding: 0 4px !important;
}
```
- Works for both 'datepicker' and 'timedatepicker' field types
- Example:
  ```jsx
  <input
    className={`input primaryBorderWithFocus ${isVaultOffers ? 'vault-offers-input' : ''}`}
    type='date'
    style={isVaultOffers ? VAULT_OFFERS_STYLES.inputStyle : {}}
  />
  <div className={`input__placeholder input__placeholder--datain ${isVaultOffers ? 'vault-offers-placeholder' : ''}`}
       style={{top: isVaultOffers ? '15px' : '-.5rem'}}>
    Label
  </div>
  ```

### Input Focus Placeholder Positioning
- When an input is focused, the placeholder floats up (`.input:focus + .input__placeholder`)
- Default behavior: placeholder moves to `top: -0.5rem` (above the input)
- For vault-offers, the placeholder needs to move further down due to compact input sizing
- **CSS Rule Required** for all vault-offers pages with Input components:
```css
.vault-offers-[page-name] .input:focus + .input__placeholder,
.vault-offers-[page-name] .inputLG:focus + .input__placeholder {
    top: 15px !important;  /* Placeholder position when input is focused */
}
```
- Apply to all pages with Input components: Expenses, Notes, OffersList, OfferOnline, OpenHouseList, Photos, AddDocument, Documents, History, MyProfile
- **Why 15px:** With compact 22px inputs and tight spacing, the default `-0.5rem` positioning doesn't work well. `15px` positions the floating label in a readable location above the focused input
- **CRITICAL:** Include BOTH `.input:focus` AND `.inputLG:focus` states — some inputs use regular `.input` class while file uploads and textareas use `.inputLG` class
- Without this rule, focused placeholder text may overlap or position incorrectly

### Placeholder Text Sizing (Non-Datain)
- Regular Input component placeholders that don't float need font-size reduction
- **CRITICAL CSS Rule Required:** Add to VaultOffersCommon.css for any page with regular Input components:
```css
.vault-offers-[page-name] .input__placeholder:not(.input__placeholder--datain) {
    font-size: 0.8em !important;  /* Reduce from 1rem default */
}
```
- This applies to placeholders in the Add form, form sections, etc.
- Without this rule, placeholder text ("Amount", "Description", etc.) appears too large
- The `:not(.input__placeholder--datain)` selector ensures only non-floating placeholders are affected

### AddItemList Toggle Buttons
- AddItemList component renders a toggle button ("Add [Item]") that expands a form
- By default, these buttons are too large for vault-offers (3.3rem height, 1.6rem font)
- **CRITICAL CSS Rule Required:** Add to VaultOffersCommon.css for any page using AddItemList:
```css
.vault-offers-[page-name] .addItem__button {
    height: 28px !important;
    font-size: 0.8em !important;
    line-height: 28px !important;
    padding: 0 8px !important;
    max-width: 120px !important;  /* Prevents very wide buttons */
}

.vault-offers-[page-name] .addItem__plusIcon {
    font-size: 0.8em !important;
    margin-right: 0.3rem !important;
}

.vault-offers-[page-name] .addItem__button i {
    font-size: 0.7em !important;
    margin-right: 0.2rem !important;
}
```
- The `max-width: 120px` prevents buttons like "Add Expense" from being too wide
- Icon sizing (0.7em) ensures icons like fa-comment fit properly with text in compact 28px buttons
- Apply to all pages with AddItemList: Expenses, Notes, OffersList, OfferOnline, OpenHouseList, TextMessage, etc.

### Tab Navigation Buttons
- Tab buttons at the top of pages (e.g., "Offers", "Manage Online Offers", "Open House") need vault-offers styling
- **Parent container must pass `isVaultOffers` prop to Tabs component** (example: Offers.js → Tabs)
- **Tabs component must apply `vault-offers-tab-button` class** when `isVaultOffers` is true
- **CSS Rule Required:** Already defined in Tabs.css but ensure it's applied:
```css
div.tabs__option.vault-offers-tab-button {
    font-size: 0.8em !important;
    padding: 6px 8px !important;
    height: auto !important;
    line-height: 1.2 !important;
    width: auto !important;
    min-width: 70px !important;
    margin: 0.3rem !important;
    flex-direction: row !important;
}

div.tabs__option--active.vault-offers-tab-button {
    height: auto !important;
    padding: 6px 8px !important;
}
```
- `height: auto` and `width: auto` allow text to fit without cramping
- `line-height: 1.2` adds spacing for wrapped text (long names like "Manage Online Offers")

### Datain-Style Placeholder Pattern (Floatable Placeholders)
When you encounter form pages with placeholder text inside inputs (like "To", "Subject", "CC" in email forms), apply the datain pattern for vault-offers users:

**Pattern Description:**
- Placeholder text appears INSIDE the input at 0.75em font-size
- When user focuses on input or types data, placeholder floats UP and appears above the input
- Placeholder has white background so it sits nicely over input border
- Creates compact vertical space while keeping clear labeling

**When to Apply:**
- Email/message compose forms with fields like To, CC, BCC, Subject
- Any contact form with placeholder-labeled inputs
- Text input, select, or other form fields that use placeholder labels

**Implementation:**
1. Wrap the Input component with a div: `<div style={{'width': '50%'}} className={`input__wrapper ${isVaultOffers ? 'vault-offers-datain' : ''}`}>`
2. Add the Input component with `placeholder` prop
3. For vault-offers only, add a placeholder div: `{isVaultOffers && <div className="input__placeholder input__placeholder--datain">Label</div>}`
4. Ensure Input has `className="input primaryBorderWithFocus ..."`

**Example:**
```jsx
<div style={{'width': '100%'}} className={`input__wrapper ${isVaultOffers ? 'vault-offers-datain' : ''}`}>
  <Input
    name="to"
    className={`input primaryBorderWithFocus ${isVaultOffers ? 'vault-offers-input' : ''}`}
    style={isVaultOffers ? VAULT_OFFERS_STYLES.inputStyle : {}}
    onChange={this.handleInputChange}
    placeholder='To'
    type='text'
  />
  {isVaultOffers && <div className="input__placeholder input__placeholder--datain">To</div>}
</div>
```

**CSS Rules Required in VaultOffersCommon.css:**
```css
/* Communications inputs with datain-style placeholders for vault-offers */
.communications .input__wrapper.vault-offers-datain {
    height: auto !important;
    margin-bottom: 1px !important;
    padding: 0 1rem !important;
}

.communications .vault-offers-datain .input__placeholder {
    position: absolute;
    transition: all 200ms linear;
    font-weight: 700;
    font-size: 0.75em !important;
    pointer-events: none;
    left: 1.8rem;
    top: 0.6rem !important;
    color: #707070;
    background: white;
    padding: 0 2px;
}

.communications .vault-offers-datain .input:focus + .input__placeholder {
    top: -0.5rem !important;
    color: #2c80b8;
}

.communications .vault-offers-datain .input:not(:placeholder-shown) + .input__placeholder {
    top: -0.5rem !important;
}
```

## Filter Modal Styling Pattern

Pages with search bars often have filter icons that open modals for filtering. When adding vault-offers styling to a new page, check for filter modals and apply vault-offers styling.

### Finding Filter Modals

**Search for `fa-filter` in the component file** — This is the Font Awesome icon class used for filter buttons across the app:
```bash
grep -r "fa-filter" src/
```

This will show all components with filter modals. Look for patterns like:
```jsx
<button onClick={openFilter}>
  <i className="fa fa-filter"></i>
</button>
```

### Filter Modal Component Pattern

Filter modals typically render with a Modal component that wraps filter form controls:

```jsx
const isVaultOffers = useSelector(state => 
  state.myprofile?.features?.whitelabel_offers_only
);

return (
  <>
    {/* Filter button */}
    <button onClick={() => setShowFilter(true)} className={isVaultOffers ? 'vault-offers-button' : ''}>
      <i className="fa fa-filter"></i> Filter
    </button>

    {/* Filter modal */}
    <Modal 
      show={showFilter} 
      onHide={closeFilter}
      className={isVaultOffers ? 'vault-offers-filter-modal' : ''}
    >
      <Modal.Header closeButton>
        <Modal.Title>Filter</Modal.Title>
      </Modal.Header>
      <Modal.Body>
        {/* Filter form inputs */}
        <Input
          placeholder="Search term"
          className={isVaultOffers ? 'vault-offers-input' : ''}
        />
        <select className={isVaultOffers ? 'vault-offers-input' : ''}>
          <option>Option 1</option>
        </select>
      </Modal.Body>
      <Modal.Footer>
        <Button 
          className={isVaultOffers ? 'vault-offers-button' : ''}
          onClick={applyFilter}
        >
          FILTER
        </Button>
      </Modal.Footer>
    </Modal>
  </>
);
```

### Filter Modal Styling Includes

**CSS Rule Required in VaultOffersCommon.css:**

```css
/* Filter modal - compact layout */
.vault-offers-filter-modal .modal-header {
    padding: 4px 8px !important;
    font-size: 0.9em !important;
}

.vault-offers-filter-modal .modal-body {
    padding: 4px 8px !important;
}

.vault-offers-filter-modal .modal-footer {
    padding: 4px 8px !important;
    display: flex !important;
    gap: 4px !important;
    justify-content: flex-end !important;
}

/* Filter modal inputs */
.vault-offers-filter-modal .vault-offers-input {
    font-size: 0.8em !important;
    height: 22px !important;
    padding: 2px 4px !important;
}

.vault-offers-filter-modal select {
    font-size: 0.8em !important;
    height: 22px !important;
    padding: 0 4px !important;
}

/* Filter modal buttons */
.vault-offers-filter-modal .vault-offers-button {
    font-size: 0.85em !important;
    height: 24px !important;
    padding: 4px 8px !important;
    min-height: 24px !important;
    line-height: 1 !important;
}
```

### Pages with Filter Modals (Already Styled)

The following pages have filter modals that have been styled for vault-offers:

1. **PropertyList.js** - Property list filter (filters by Transaction Type and other fields)
2. **Tasks.js** - Task filter modal (Due in 2 days toggle, Clear Filters button)
3. **PropertyAttributes.js** - Property attributes filter modal
4. **ContactList.js** - CRM contact filter modal (select dropdown)
5. **Communications.js** - Email/communications filter modal
6. **HOA.js** - HOA filter modal
7. **Users.js** - Users search filter modal

All filter modals use the pattern:
- Apply `vault-offers-filter-modal` class to the Modal component
- Apply `vault-offers-input` class to all Input components inside the modal
- Apply `vault-offers-button` class to Filter/Close buttons
- Add CSS rules in VaultOffersCommon.css for modal padding and button sizing

## CSS Rules Template for New Pages

When adding vault-offers styling to a new page, add custom CSS rules to `VaultOffersCommon.css` following this pattern. **IMPORTANT: You need BOTH datain and non-datain rules**, as they control different placeholder behaviors:

- **Datain rules** (`.input__placeholder--datain`) — for placeholders that float UP when focused or have data
- **Non-datain rules** (`.input__placeholder`) — for placeholders that stay in normal position or are completely hidden

### CSS Variable Setup
CRITICAL: All pages with Input components must set the placeholder positioning CSS variable:
```css
.vault-offers-[page-name] {
    --input-placeholder-top: 1.9rem;
}
```
This controls the default vertical space allocated for floating placeholders in Input components.

### Datain-Style CSS Rules
If the page has any inputs with floating placeholder labels (text inside input, floats above on focus):
```css
/* Page name vault-offers styling - datain placeholders (floatable) */
.vault-offers-[page-name] .input__placeholder--datain {
    top: 15px !important;
    left: 30px !important;
    font-size: 0.9em !important;
}
```

### Focus Placeholder Positioning Rules
CRITICAL: All pages with Input components must include focus selectors for BOTH `.input` and `.inputLG` classes:
```css
/* Page name vault-offers styling - focus placeholder positioning */
.vault-offers-[page-name] .input:focus + .input__placeholder,
.vault-offers-[page-name] .inputLG:focus + .input__placeholder {
    top: 15px !important;
}
```
**Why both classes:** Regular text inputs use `.input` class while file uploads and textareas use `.inputLG` class. Both need the focus placeholder positioning rule to work correctly.

### Non-Datain CSS Rules
For regular placeholder text that doesn't float (stays at normal position):
```css
/* Page name vault-offers styling - non-datain placeholders */
.vault-offers-[page-name] .input__placeholder {
    font-size: 0.9em !important;
    margin-bottom: 1px !important;
}

/* Input and select font sizing with proper line-height and vertical alignment */
.vault-offers-[page-name] input,
.vault-offers-[page-name] select {
    font-size: 0.8em !important;
    height: 22px !important;
    padding: 0px 4px !important;
    line-height: 22px !important;
    vertical-align: top !important;
}

/* Page-specific section header sizing (if needed) */
.vault-offers-[page-name] .sectionHeader {
    font-size: 1rem !important;
    height: 40px !important;
    line-height: 40px !important;
}
```

These rules ensure:
- Datain placeholders position correctly inside compact inputs and float on focus
- Non-datain placeholders maintain proper sizing and spacing
- Select dropdowns match input sizing (not oversized)
- Section headers maintain compact proportions
- Different placeholder behaviors don't interfere with each other

## Pages Already Implemented

### Task Module (Original)
1. **DetailsTab.js** - Property Details tabs (Overview, Occupancy, etc.)
   - Uses `<Tabs>` component to render tab buttons
   - Passes `isVaultOffers` flag to Tabs component
   - Tabs receive `vault-offers-tab-button` class for small sizing
   - Only Overview and Occupancy tabs shown for vault-offers users
   - Tabs.css overrides base tab styling for vault-offers buttons (font-size 0.8em, padding 4px 8px, height 24px)

2. **TaskOverview.js** - Task edit page
   - Uses `useSelector` for feature flag
   - Applies styling throughout form
   - Full vault-offers support

3. **CompleteTask.js** - Task completion page
   - Uses Redux mapStateToProps
   - Complete vault-offers styling
   - WYSIWYG editor integration
   - Task Completion Date placeholder positioned above input (top: 5px)

4. **Tasks.js** - Task list page
   - List item styling with color boxes
   - Reduced item height (33px)
   - Legend styling

5. **AddTask.js** - New task form
   - Mixed Input components and raw inputs
   - Custom `.vault-offers-add-task` wrapper class
   - Requires custom CSS rule for placeholders

6. **Users.js** - User management and profile page
   - All Input components styled including select dropdowns
   - Toggle components for agent/broker and special leads handling
   - WYSIWYG editor for Marketing BIO with reduced size
   - Custom CSS rules for section headers, name display, and select sizing

### Document Module (May 2026)
7. **Documents.js** - Document list/filter view
   - Feature flag already present as `profilefeatures`
   - Vault-offers wrapper class: `vault-offers-documents`
   - Action buttons styled: Document, Combine PDF's, Checklist
   - Module header and searchbar sizing reduced

8. **Document.js** - Individual document card component
   - Already had `profilefeatures` from Redux
   - Edit/Remove buttons styled with `vault-offers-button`
   - Status zone inputs and textarea styled
   - Document title and date text reduced font

9. **AddDocument.js** - Document upload modal form (functional component)
   - Uses hooks: `useSelector(state => state.myprofile)`
   - All Input components (title select, category, type, file upload) styled
   - Page wrapper class: `vault-offers-add-document`

10. **IconCounters.js** - Filter counter bar (shared component)
    - Uses hooks: `useSelector(state => state.myprofile)` 
    - Horizontal layout for vault-offers: icon + name + count on same row
    - All elements centered in 40px height container
    - Icon: 1.2em, Name: 0.9em, Count: 1em

### Expenses Module (May 2026)
11. **Expenses.js** - Expense list view
    - Added `myprofile` to mapStateToProps
    - Vault-offers wrapper class: `vault-offers-expenses`
    - AddItemList with 17 Input components styled
    - Add button styled

12. **ExpenseOverview.js** - Expense detail/edit panel
    - Added `myprofile` to mapStateToProps  
    - All 17 Input components and Save button styled
    - Section labels reduced font

### Notes Module (May 2026)
13. **Notes.js** - Notes list view
    - Added `myprofile` to mapStateToProps
    - Vault-offers wrapper class: `vault-offers-notes`
    - Toggle, Subject Input, WYSIWYG, File Inputs, email list all styled
    - Passes `isVaultOffers` prop to NotesOverview child

14. **NotesOverview.js** - Note detail/edit panel
    - Accepts `isVaultOffers` prop from parent (not Redux connected)
    - Subject Input, WYSIWYG, Save button styled

### Offers Module (May 2026)
15. **OffersList.js** - Offer add form
    - Added `myprofile` to mapStateToProps
    - All 9 Input components in add form styled (Amount, Buyer, Agent details, Status, Deadline, Document)
    - Add button styled

16. **OfferOnline.js** - Manage Online Offers page (functional component with hooks)
    - Uses hooks: `useSelector(state => state.myprofile)`
    - Vault-offers wrapper class: `vault-offers-online-offers`
    - All Toggle, Input, and bare input elements styled
    - Save Document and Extend buttons styled

17. **OpenHouseList.js** - Open House list view
    - Added `myprofile` to mapStateToProps
    - Vault-offers wrapper class: `vault-offers-open-house`
    - Date/time inputs, Add button, column headers, data rows all styled
    - Height: 40px for compact display

18. **OpenHouseEditForm.js** - Open House edit form
    - Added `myprofile` to mapStateToProps
    - Date/time inputs and Edit button styled

### Photos Module (May 2026)
19. **Photos.js** - Photo list/album view
    - Added full `myprofile` to mapStateToProps
    - Upload Photos button, modal inputs, Toggle, Add Photo button all styled
    - Supports Multiple Upload Display

20. **Album.js** - Album container (functional component with hooks)
    - Already had `isVaultOffers` via useSelector
    - Mode buttons (Delete, Select All, Unselect All) styled
    - Addendum/Zip mode panels with inputs and buttons styled
    - Album name text reduced font

### Property History Module (May 2026)
21. **PropertyHistoryList.js** - Historical data table view
    - Added `myprofile` to mapStateToProps
    - Vault-offers wrapper class: `vault-offers-history`
    - Section headers, column headers, data rows all styled with reduced font
    - Searchbars styled with reduced margin

## Known Issues to Address (May 2026)

### Property Details Overview/Occupancy Tabs
1. **Category Label Spacing** ✅ FIXED (March 2026)
   - Property-field-header now has 45px margin-top for spacing between sections
   - First header in each section has 0px margin-top to avoid wasted space
   - Lockbox toggle has 38px margin-top to prevent overlap with inputs above

2. **Document/Expense/Notes/Offer/History Pages - Styling Issues**
   - Multiple pages styled May 2026 but require testing/refinement
   - See user issues logged in current session for specifics
   - May include: input sizing discrepancies, button visibility, spacing issues, layout problems

## Testing Checklist

When adding vault-offers styling to a new page:
- [ ] Import CSS and VAULT_OFFERS_STYLES
- [ ] Get feature flag from Redux state
- [ ] Apply conditional classes/styles to all form inputs
- [ ] Test with vault-offers user (whitelabel_offers_only = true)
- [ ] Test with regular user (feature flag false/missing)
- [ ] Verify no scrollbars appear where not intended
- [ ] Check placeholder text positioning and sizing
- [ ] Ensure buttons are properly sized and text is visible
- [ ] Verify list items display at correct size if applicable
- [ ] Check that inputs don't stack when they should be side-by-side

## Common Issues to Fix When Applying Vault-Offers Styling

When styling a new page, ALWAYS check and fix these items (multiple prompts usually needed for these):

### **MODALS — Common Fixes (Multiple Prompts Usually Needed)**
If your page has a modal with Input components or buttons, you WILL need to fix:
1. **Modal header/body/footer padding** — Reduce to 4px 8px
2. **Modal footer button layout** — Add `display: flex`, `gap: 4px`, `justify-content: flex-end` to keep buttons side-by-side
3. **Regular input wrappers** — Add CSS for `.input__wrapper { height: auto }` and `.input__wrapper input { font-size: 0.65em, height: 18px }`
4. **Button text alignment** — Use `line-height: 1` on buttons to prevent text appearing below the button

**See "Modal Input Wrappers" and "Modal Buttons Layout" sections below for complete examples.**

---

### Navigation & Back Arrows
- **Back arrows / Navigation icons** — Font-size MUST be `1.2em` (not 0.8em). This is consistent across all pages with navigation
- **CSS Rule Required:** `.vault-offers-[page-name] .fa-arrow-left { font-size: 1.2em !important; }`
- **Example:** `.vault-offers-text-message .communications-backarrow-container { font-size: 1.2em !important; }`

### Page Headers & Titles (mobileHeader Pattern)
- **SubHeader/mobileHeader styling** — Follow the pattern from Property History page
- **CSS Rule Required:** 
```css
.vault-offers-[page-name] .mobileHeader {
    font-size: 1rem !important;
    font-weight: bold !important;
    height: 30px !important;
    line-height: 30px !important;
}
```
- **Example:** `.vault-offers-text-message .mobileHeader { font-size: 1rem !important; font-weight: bold !important; height: 30px !important; line-height: 30px !important; }`
- **Important:** SubHeader components often render as mobileHeader elements, so the CSS rule targets `.mobileHeader` not `.SubHeader`
- **DO NOT apply `vault-offers-text-small` class** to SubHeader components that render as mobileHeader - let the CSS rule handle the styling

### Buttons
- **Add/Create/Send buttons** — Apply `.vault-offers-button` class to ALL action buttons
- **CSS Rule Already Defined:** `.vault-offers-button { font-size: 0.85em !important; height: 28px !important; padding: 6px 12px !important; line-height: 28px !important; }`
- **DropDownForm Buttons** — CRITICAL: The button inside DropDownForm must have `.vault-offers-button` class for proper sizing
- **React Implementation:** `className={`button__success ${isVaultOffers ? 'vault-offers-button' : ''}`}`

### Searchbar (Search Inputs with Icons)
- **Searchbar Container** — Add `position: relative` to parent wrapper for absolute positioning of icon
- **Icon (Magnifying Glass)** — Use absolute positioning with centering:
  - `position: absolute`
  - `left: 8px`
  - `top: 50%`
  - `transform: translateY(-50%)`
  - Font-size should match input (0.8em is fine; icon is already appropriately sized when centered)
- **Input Padding** — Ensure `padding-left: 2.5rem` so placeholder text starts to the right of the icon
- **CSS Rule Required:**
```css
.vault-offers-[page-name] .searchbar-wrapper {
    position: relative;
}

.vault-offers-[page-name] .searchbar-icon {
    position: absolute;
    left: 8px;
    top: 50%;
    transform: translateY(-50%);
}

.vault-offers-[page-name] input[type="search"],
.vault-offers-[page-name] .searchbar-input {
    padding-left: 2.5rem !important;
}
```
- **Example:** TextMessage page uses Searchbar component with these centering rules in VaultOffersCommon.css

### Grid & Table Text
- **Grid/Table text** — Reduce font-size to `0.65rem` (not 0.75em or larger) for grid cells and table data
- **Grid Column Headers** — Same `0.65rem` font-size for header row consistency
- **CSS Rule Required:**
```css
.vault-offers-[page-name] .grid-cell,
.vault-offers-[page-name] .table-cell,
.vault-offers-[page-name] .data-row {
    font-size: 0.65rem !important;
}

.vault-offers-[page-name] .header-row {
    font-size: 0.65rem !important;
}
```
- **React-Virtualized Grid:** If page uses react-virtualized Grid component, may need to adjust rowHeight parameter:
  - Default (non-vault-offers): 66px-70px
  - Vault-offers: 45px-50px (depends on font size and padding)
  - **Implementation:** `rowHeight={isVaultOffers ? 45 : 66}`

### Form Elements with Vault-Offers Styling
- **Input elements** — Apply `.vault-offers-input` class to ALL text, date, select inputs
- **Textarea** — Apply `.vault-offers-input` class
- **Select/dropdown** — Apply `.vault-offers-input` class and add CSS rule for select font-size

### Spacing Between Elements
- **Vertical spacing** — Reduce margins and padding (1px-2px instead of 1rem)
- **Wrapper margins** — Input wrapper margins should be 1px, not 1rem
- **Section spacing** — Space between form sections should be minimal

### Inline Styles
- **Hardcoded font-size values** — Make conditional based on isVaultOffers flag
- **Text elements** — Check for `style={{fontSize: '1rem'}}` and make it conditional: `style={{fontSize: isVaultOffers ? '0.8em' : '1rem'}}`

## Text Message History Page Example (Full Implementation)

The Text Message History page demonstrates the complete pattern for pages with navigation, headers, inputs, buttons, and search:

### React Component Changes (TextMessage.js, TextMessageSend.js, TextMessageList.js):
1. Import CSS and feature flag detection
2. Back arrow: Add `className="vault-offers-back-arrow"` (styling handled by CSS)
3. SubHeader (page title): Add `className={isVaultOffers ? 'vault-offers-text-small' : ''}` for font-size reduction
4. Input elements: Add `className={isVaultOffers ? 'vault-offers-input' : ''}`
5. Send button: Add `.vault-offers-button` to `Button` className
6. Searchbar: Ensure wrapper has `position: relative` and icon is absolutely positioned

### CSS Rules in VaultOffersCommon.css:
```css
/* Text Message History - Navigation back arrow */
.vault-offers-text-message .communications-backarrow-container {
    font-size: 1.2em !important;
}

/* Text Message History - Page header */
.vault-offers-text-message .subheader {
    font-size: 1.1em !important;
    height: 2rem !important;
    line-height: 2rem !important;
}

/* Text Message History - Input elements */
.vault-offers-text-message .vault-offers-input {
    font-size: 0.8em !important;
    height: 22px !important;
    padding: 2px 4px !important;
}

/* Text Message History - Button styling */
.vault-offers-text-message .vault-offers-button {
    font-size: 0.85em !important;
    height: 28px !important;
    padding: 6px 12px !important;
    line-height: 28px !important;
}

/* Text Message History - Grid/Table text */
.vault-offers-text-message .textmessagelist_headers,
.vault-offers-text-message .textmessagelist_grid > div {
    font-size: 0.65rem !important;
}

/* Text Message History - Searchbar icon centering */
.vault-offers-text-message .searchbar-wrapper {
    position: relative;
}

.vault-offers-text-message .searchbar-icon {
    position: absolute;
    left: 8px;
    top: 50%;
    transform: translateY(-50%);
}

.vault-offers-text-message .searchbar-input {
    padding-left: 2.5rem !important;
}
```

## Complete Checklist for New Pages

When adding vault-offers styling to a new page, go through this checklist systematically:

**CRITICAL - Import and Feature Flag (Do This First!):**
- [ ] **IMPORT: Add `import '../VaultOffers/VaultOffersCommon.css';` to the component** (most commonly forgotten!)
- [ ] Get feature flag from Redux (class component) or useSelector (functional component)
  - Class: Add `myprofile: state.myprofile` to mapStateToProps
  - Functional: `const myprofile = useSelector(state => state.myprofile);`
- [ ] Create feature flag variable: `const isVaultOffers = myprofile && myprofile.features && myprofile.features.whitelabel_offers_only;`
- [ ] Add wrapper class: `className={isVaultOffers ? 'vault-offers-[page-name]' : ''}`

**Navigation & Headers:**
- [ ] Back arrow (if present): font-size 1.2em
- [ ] Page title/SubHeader: Use mobileHeader pattern (1rem font-size, bold, 30px height)
- [ ] Do NOT apply `vault-offers-text-small` class to SubHeader components; use CSS to target `.mobileHeader` instead

**Form Elements:**
- [ ] All text inputs: Add `vault-offers-input` class
- [ ] All select/dropdown: Add `vault-offers-input` class AND add CSS rule for select font-size
- [ ] All date inputs: Add `vault-offers-input` class
- [ ] All textarea: Add `vault-offers-input` class

**Toggle Components:**
- [ ] Any Toggle components: Add `isVaultOffers={isVaultOffers}` prop
- [ ] Adjust wrapper margin: `margin: isVaultOffers ? '0.5rem' : '1rem'`

**Buttons:**
- [ ] All action buttons (Create, Send, Save, etc.): Add `vault-offers-button` class
- [ ] AddItemList buttons: Already handled by global rule (height 28px, font-size 0.8em)
- [ ] Button icons (fa-comment, etc.): May need font-size adjustment (typically 0.85em)

**Search/Filter:**
- [ ] Searchbar container: Add `position: relative` wrapper
- [ ] Searchbar icon: Absolute positioning with left: 8px, top: 50%, transform: translateY(-50%)
- [ ] Input padding-left: 3rem to accommodate icon
- [ ] Placeholder text visible and not overlapped by icon

**Modals/Dialog Components:**
- [ ] Modal has conditional className: `className={isVaultOffers ? 'vault-offers-[modal-name]' : ''}`
- [ ] Modal CSS variables set: `--input-placeholder-top: 1.9rem` and `--input-inputLG-wrapper-height: 1.5rem` (for Input components)
- [ ] Modal header/body/footer padding: 4px 8px (compact spacing)
- [ ] Modal footer layout: Add `display: flex`, `gap: 4px`, `justify-content: flex-end` to keep buttons side-by-side
- [ ] Modal regular inputs (non-inputLG): Add CSS rules for `.input__wrapper` with `height: auto` and `.input__wrapper input` with small font/height
- [ ] Modal buttons: Add `line-height: 1` to prevent text appearing below button (critical for compact buttons)
- [ ] Modal body overflow: `overflow-y: auto` if content scrolls

**Lists/Grids/Tables:**
- [ ] Grid/table text: font-size 0.65rem
- [ ] Column headers: font-size 0.65rem
- [ ] List row height: Conditional (vault-offers ~45px, regular ~66px)
- [ ] Check for floating semicolons or trailing `>;` syntax errors

**Spacing:**
- [ ] Input wrapper margins: 1px (not 1rem)
- [ ] Section spacing: Minimal, condensed layout
- [ ] No excessive padding breaking compact layout
- [ ] Toggle wrapper margins: Conditional (0.5rem for vault-offers, 1rem for regular)

**CSS File Updates:**
- [ ] Add comprehensive CSS rules in VaultOffersCommon.css for the page/component
- [ ] Include rules for inputs, buttons, modals, spacing, text sizing, grid elements
- [ ] Use `!important` flags on all overrides
- [ ] Target both specific components (`.vault-offers-[page] input`) and general elements

**Testing:**
- [ ] Test with vault-offers user (whitelabel_offers_only = true)
- [ ] Test with regular user (feature flag false/missing)
- [ ] Verify styling changes are visible (if not, check VaultOffersCommon.css import!)
- [ ] Verify all text is readable at reduced sizes
- [ ] Verify icons are properly centered and sized
- [ ] Verify buttons are clickable and properly styled
- [ ] Verify no overlapping elements or floating semicolons
- [ ] Verify modal layout doesn't break with compact styling
