# ComplianceCalendar

> Filing deadlines by jurisdiction, with the owner and the date penalties start.

Source: https://lopifi.com/components/compliance-calendar
Part of: Lopifi — US GAAP books on autopilot, checked by a CPA (https://lopifi.com)

---

- **Family:** Tax & compliance — The obligations around the books: what is due to whom, who has been verified, and which controls held.
- **Status:** Implemented
- **Spec:** https://lopifi.com/docs/catalog/14-tax-compliance

## Install

```bash
npx shadcn@latest add @lopifi/theme
npx shadcn@latest add @lopifi/compliance-calendar
```

## Specification

Every filing the entity owes: obligation, form, jurisdiction and agency, the period covered, the due date, the owner, the status, and **the date penalties start**. Two views: `upcoming` puts open filings soonest first, so past-due ones sit at the top and filed ones go last, and `month` groups every filing under the month its governing date falls in.

```
Filing calendar                         Northwind Ltd · as of 18 Oct 2026
1 past due · 1 due soon · 1 without an owner
─ Open ───────────────────────────────────────────────────── 5 filings
15 Oct   Payroll tax deposit                                  [Late]
3 days   Federal · IRS · September 2026 · A. Whitfield   Penalties from 16 Oct 2026
past due
```

**Status is supplied, not derived.** `upcoming | due-soon | filed | late | extended`. Whether a return is "due soon" depends on business days, holidays and the team's own lead time, and the consumer knows those; the component does not. It does compute the day count from `asOf`, by calendar date, so a clock time never makes a return late.

**An extension moves the filing date, and only that.** The row then shows the extended date, the original date beneath it, and, when the consumer supplies a separate `paymentDueDate`, the payment date too, because an extension to file isn't always an extension to pay.

**Refuses to render:** a penalty date nobody stated as "no penalty". A `null` penalty date prints "Penalty date not stated". A `null` owner prints "Unassigned" in the warning tone and is counted in the header. It's an action, not a blank.

**Edge cases:** no obligations at all says so and asks whether the registrations behind it are complete, because an empty calendar is a claim. A filing with no form name shows the obligation alone. A filed row shows the filing date and the agency's confirmation number.

**Accessibility:** each group is a labeled `section` holding an ordered list. Status is an icon plus a word. The past-due day count carries weight as well as color, so it reads in grayscale.

## Rules this component obeys

Money is minor units, never floats. `null` is not `0` and neither is redacted. Negatives render in accounting parentheses with the parenthesis column reserved on both sides. Debit and credit are two columns. Per-currency decimal places. Polarity is explicit — up is not always good. Every figure states its period, entity, currency, basis and as-of.
