# Changelog — Hartling owner portals

Newest first. One entry per change; the running app shows its version in the footer.

## 0.28.0 — 2026-08-28
- **Fixed: the walkthrough's spotlight now genuinely clears its target.** The
  dimming layer used to cover the highlighted element too, so the outlined
  area was as dark as everything else.
- **Staff-only surfaces now say so.** A small "Staff only" tag sits on the
  uploader, the board tools, the add-owner box, the Owners and Trash pages,
  and the staff section of the menu — so nobody demos the site thinking
  owners can upload documents. The walkthrough says it on every relevant
  step as well.
- **The sign-in scene grew to 23 photographs** (7–8 per property), all from
  full-resolution originals — one upscaled frame that could look pixelated
  was replaced — and the order is shuffled on every visit.
- On wide screens the document library's browse panel now extends to the
  window edge, with its labels aligned to the logo above.

## 0.27.0 — 2026-08-28
- **The staff walkthrough is live.** New staff members get it automatically on
  their first visit — "Welcome, Joan!" — and it walks through what staff can
  do, the owner-view switch, browsing, uploading, editing, the board, and
  managing owners, across the real pages. Close it any time; finish or skip
  and it never auto-opens again. Rerun it from "Site walkthrough" under the
  profile icon.
- Owners never see any of it, and it stays out of the way while a staff
  member is demoing in owner view.
- Sign-in scene: frames change a little more often and the sweep is half
  again slower; the photography now drifts continuously, so the movement
  never comes to a stop between transitions.

## 0.26.0 — 2026-08-28
- **The sign-in page is a full-screen scene** of the property's own
  photography, drifting from frame to frame on a soft diagonal sweep. The
  masthead is gone from this page; the logo and "Owners' portal" sit at the
  top of the sign-in card itself, on the brand's dark band.
- The redundant heading and instructions are gone, and the reset link now
  reads "Reset your password".
- Owners running with reduced motion get a single still frame.

## 0.25.0 — 2026-08-28
- Owners: the list filters as you type; generating a password opens a dialog
  beside the row instead of jumping to the top; the add-owner box stays
  collapsed after a successful add and reopens only on an error.
- Buttons renamed: "Email a password reset" and "Generate new password".
- A brand-new owner now receives a proper invitation — subject "You have been
  invited to <portal>", body "You've been invited… Click here to set your
  password." The reset email is unchanged.
- The owners table no longer breaks its lines on narrow windows: long emails
  stop wrapping mid-word, and below 760px the table becomes stacked cards.
- Fixed two imported titles that displayed "&amp;" instead of "&", and the
  importer now un-escapes titles so a re-import cannot bring them back.
- The board portrait matte now carries the property's texture, matching the
  document library's browse panel.

## 0.24.0 — 2026-08-28
- **The board page is rebuilt around one uniform card** — nobody is featured
  larger. A photo takes the left third, shown whole on a quiet matte; the
  biography fills the two-thirds beside it to about the portrait's height,
  with "Read the full profile" expanding it in place. A member without a
  photo simply gets the full width for their text — no initials circle, no
  placeholder of any kind. Each card carries the property's accent as a left
  rule.
- The pop-up profile dialog is gone; bios read inline. A bio short enough to
  fit gets no expand button at all.
- Cleaned two imported biographies that opened by repeating the member's
  role or name as a stray first line.

## 0.23.1 — 2026-08-28
- The category pill on a document now appears only in the Flat view. Anywhere
  grouped it repeated what the page already said — the section heading, or the
  collection picked in the browse panel.
- Fixed: on phones in dark mode the Browse strip (and the browse panel) kept
  the light paper shade under light text — white on cream. The panel now has
  its own dark-mode shade, a step above the page.

## 0.23.0 — 2026-08-28
- **The phone masthead is one line** — hamburger, logo centered, account —
  with the navigation dropping down from the bar instead of wrapping under
  the logo.
- **Browse is no longer a rounded button**: a full-width strip in the panel's
  own shade, edge to edge, with a chevron pointing the way the drawer slides
  in. One hamburger on screen, and it belongs to the masthead.

## 0.22.0 — 2026-08-28
- **The footer now mirrors the masthead** — the same dark field and brand rule,
  with the property's logo centered and the version number small and faint.
- **An Owner-view switch for staff**, in the footer beside the version. Flip it
  and every page renders exactly as an owner sees it — no uploader, no edit or
  trash controls, no staff menu — until you flip it back. It changes what is
  shown, never what you are allowed to do.

## 0.21.2 — 2026-08-28
- The browse panel's textures now match how the resorts themselves use them: at
  native size (the upscaling was what caused the pixelation) and at a fraction
  of the previous contrast — a quiet surface texture rather than a pattern
  competing with the labels.

## 0.21.0 — 2026-08-27
- **The Shore Club now uses its own display face**, self-hosted from the resort
  site with the owner's go-ahead.
- **The Palms takes its real brand** — Cinzel and Didact Gothic, its own blue,
  and its own paper — replacing the colours that had been guesses.
- **The browse panel carries each resort's own background texture** instead of
  a photograph: The Palms' wave, The Shore Club's tile pattern. Both are small
  repeating files from their own sites, held to the same tonal limit as before
  so nothing gets harder to read.

## 0.20.0 — 2026-08-27
- **Each property now uses its own resort's typefaces.** The Sands takes EB
  Garamond and Source Sans 3; The Shore Club takes Open Sans with a display
  face standing in for its licensed one.
- **The masthead carries the resort's full-strength colour** — The Sands' aqua
  and The Shore Club's orange, both taken from their sites' own footers — as a
  rule along the header and on the active link. They are too light to sit
  behind white text, so the bar itself stays dark and the colour sits on it.
- The Shore Club's masthead went a shade deeper so its own orange reads on it.

## 0.19.0 — 2026-08-27
- **The browse panel is barely tinted now** — near enough the page's own paper,
  with a hairline rule doing the separating rather than weight.
- **The resort photograph is a proper watermark**: unblurred and recognisable,
  filling the whole panel, with its tones squeezed into a narrow band so it can
  only lighten the paper by a little. You can tell what it is without it
  pulling the eye off the documents.
- **Fixed: "All documents" showed the wrong number.** With a collection open it
  reported that collection's size instead of the library's — so the top of the
  rail could read 9 while Minutes read 36.
- Fixed: in the by-year view the count sat against the year ("2026 1") instead
  of at the right-hand edge.

## 0.18.3 — 2026-08-27
- **The browse panel is light again** — the page's own paper taken one step
  down, rather than a dark block. The site reads far lighter for it.
- The resort photograph is now an **emboss**: blurred past legibility, reduced
  to a relief and blended into the panel colour, so it gives the surface a
  little texture and an undertone of the place instead of being a picture
  sitting behind the type.
- The rail's text moved a step stronger to suit the darker panel — the muted
  ink that works on the page has no headroom left on it.

## 0.18.2 — 2026-08-27
- The browse panel is flush to the edge of the window and runs the full height
  of the page, rather than floating as a rounded card inset from the corner.
  Its contents stay put under the masthead as the documents scroll past.

## 0.18.1 — 2026-08-27
- **The browse panel is now a dark panel carrying a photograph of the
  property** — Grace Bay, Long Bay, the Palms pool — sat well behind the type.
  It separates the browser from the documents at a glance and gives owners a
  glimpse of their own resort without competing with the list.
- How much photograph shows is capped by legibility rather than taste: the
  overlay sits at the lightest setting where the faintest label still clears
  4.5:1 against a blown-out white pixel of the picture. A test holds that
  floor, so the panel cannot be prettied into being unreadable.
- The photograph is per-property configuration, like the logo. A property
  without one gets the flat colour and nothing breaks.

## 0.18.0 — 2026-08-27
- **The document library is rebuilt around a standing rail.** Collections and
  years sit beside the documents and never scroll away; picking one narrows the
  list without the page rearranging itself. On a phone the rail becomes a
  drawer, opened from Browse.
- Every feature came with it — expandable groups, the uploader, search, the
  staff edit and trash controls, colour-coded categories, "show more", and the
  flat view (now a Grouped/Flat switch beside the search box).
- Fixed: the counts beside a category counted rows, not documents, so a
  collection of three showed as one. The rail and the section heading now agree.
- Fixed: category counts included trashed and unpublished documents, so an
  emptied category still showed a tally.
- The masthead no longer wraps raggedly on a narrow phone.

## 0.17.1 — 2026-08-27
- **Muted text is now readable.** The grey used for every date, subtitle and
  meta line sat at 3.2:1 on all three brand grounds — under the 4.5:1 minimum
  for text that size, and these readers skew older. Darkened to pass on every
  ground. Two accents were a hair under on their own paper and were deepened
  slightly; the hues are unchanged.
- A test now measures every text colour against every ground the app renders
  on, in both themes, and fails below 4.5:1. Checking against white alone
  would have missed all three of these.

## 0.17.0 — 2026-08-27
- **Each property now wears its own identity.** A dark masthead carries the
  resort's own logo, and the accent, paper tint and masthead depth are set per
  site. One codebase, three looks — none of it is a code fork.
- The masthead is dark because all three logos are white-only; there is no dark
  variant of any of them, so a pale header had nothing to show.
- Branding now supplies raw brand values and the stylesheet decides how each
  mode uses them, so a property keeps its colour in dark mode instead of every
  portal collapsing to one shared accent.
- Logo height is set per property — the marks are drawn to different
  proportions, and one height made the stacked mark read at half the size.
- Fixed: four colours referred to a token that was never defined, so they
  quietly inherited instead. A test now fails on any undefined custom property.

## 0.16.2 — 2026-08-26
- Board roles written across a line break are no longer lost. A `<br>` was
  being removed rather than treated as a break, welding the role to the line
  under it into one run too long to be recognised as a role — so the member
  showed none at all.
- Sands: Wes Stearns is shown as Candidate for Board of Directors, and Tom
  McKeown has his photo.

## 0.16.1 — 2026-08-26
- **The importer no longer lets two accounts share an email address.** An
  address is also a way to sign in, and the login refuses to guess between two
  accounts holding one — so a duplicate silently stopped email sign-in working
  for whoever was already there. The later account is now imported without the
  contested address, and the import report says which and why.

## 0.16.0 — 2026-08-26
- **Fixed: board portraits were attached to the wrong people.** The pages float
  each photo beside the text, and whether it sits above or below its name
  varies by site — so taking the image between two headings gave several
  directors another director's face. Photos are now matched on the filename,
  and an image that matches nobody is dropped rather than given to whoever is
  nearest. Corrected on all three sites.
- **An account menu replaces the Sign out link** — your initials in the header,
  opening onto your profile, a password change, and sign out.
- **Your profile**: edit your name and email address yourself. An address
  already used by another account is refused, because sign-in accepts an email
  and a duplicate would lock out both people.
- **Change your password** without the reset email, using your current one.

## 0.15.0 — 2026-08-26
- **Removed the Activity page.** Sign-ins and downloads are still recorded, so
  the history is there if it is ever wanted — there is simply no screen showing
  it. (The download log is also what the per-user download rate limit counts,
  so it could not have been dropped anyway.)
- **The owner list has five views:** All current, Owners, Staff, Active
  (signed in within the last year) and Deleted, each showing how many.
- **Deleting an owner is now reversible.** It deactivates the account and moves
  it to Deleted, where it can be put back with its password intact. Erasing
  someone for good is a separate action inside that view.
- Fixed: a single document in the library had no space beneath it, so it sat
  flush against the next entry. Folders had spacing; lone documents did not.

## 0.14.1 — 2026-08-26
- The group editor no longer shows a category field at all. It had been set to
  hide, but `hidden` was losing to the field's own layout rule — so the fix is
  in the stylesheet, where it also restores the group-only date checkbox to
  hiding on document edits.
- Removed the note explaining where categories live; the absent field says it.
- **Fixed: the library's staff markup was emitted twice.** Every element had a
  duplicate id, so each button was wired up twice and saving sent the change
  twice. A test now counts the dialogs.

## 0.14.0 — 2026-08-26
- **Fixed: the delete button opened the edit dialog.** The trash button shared
  the edit button's CSS class, so the edit handler fired on it. Trash controls
  now have their own class and the handler only binds to buttons that carry
  `data-kind`.
- **A group no longer has a category.** A batch holds several kinds of
  document, and in the category view the same group appears under each of them
  — so "apply this category to the group" could never say honestly which
  documents it meant. Categories live on the document; the uploader still
  suggests one for the whole batch and applies it to each file, where it can be
  corrected individually. The group editor keeps name and date only.
- **One styled confirmation for the whole app**, replacing every browser
  dialog — board removal, trashing, emptying the trash, deleting an owner.
- Form fields tidied: date inputs join the shared input styling (they had been
  missing from the rule, which is why the border looked wrong), and selects get
  a themed chevron with room around it.

## 0.13.0 — 2026-08-26
- **Trash for documents and groups.** A bin icon on any row or group header
  moves it out of the library; a **Trash** page lists everything removed, with
  Restore, and an Empty the trash that deletes for good. Files stay on disk
  until then. Trashing a group takes its documents; restoring brings back
  exactly those that went in with it.
- **Edit dialog tidied**: no more horizontal scrollbar, fields sized to the
  panel, and the date input styled to match everything else — consistent
  height, tabular figures, and a calendar button tinted to the theme rather
  than the browser's default.

## 0.12.0 — 2026-08-26
- **Documents are now filed by what is inside them**, not just their titles.
  `reorganise` reads PDFs, Word files, spreadsheets and slides, and proposes
  categories, better group names, title corrections and batches to ungroup.
- **A batch can span categories.** In the category view a group appears under
  each category its documents belong to, holding only those documents and
  saying "3 of 12 in this batch". An AGM's minutes, financials and proxy form
  are one event but three kinds of document.
- **Catch-up batches are ungrouped** — several years of paperwork uploaded on
  one day were never a single event.
- Placeholder group names ("Documents added March 2024") are replaced with
  descriptive ones; groups that already had a real name are left alone.

## 0.11.1 — 2026-08-26
- The category view now defaults to **All time**. A past-year default left the
  quieter properties showing two documents out of a hundred; showing everything
  makes the landing view an overview of every category instead.

## 0.11.0 — 2026-08-26
- **Group by moved above the search box**, and reordered: Category (now the
  default), Date, Everything.
- **A second filter that changes with the grouping.** By category it is a time
  range — Past year (default), this year, last year, all time. By date or
  everything it is the category chips, as before.
- In the category view a section collapses to two entries **only when the view
  holds more than eight items**; a short view is shown whole. The per-document
  category pill is hidden there, since the section heading already says it.
- **The guided tour is switched off.** The engine, steps and per-user progress
  are left in place to be rewritten later rather than rebuilt.

## 0.10.0 — 2026-08-26
- **Group the library by date, category, or everything.** Grouped by category,
  each shows its two most recent entries with the rest behind a "show more".
- **Colour-coded categories.** Each gets a distinct colour, carried through
  chips, tags, folder icons and section headings. Staff can set an exact hex;
  otherwise one is chosen and stays stable.
- **Board redesigned**: larger cards with a portrait, name, role, a preview of
  the bio, and a Contact link. "Read profile" opens the full biography.
- **Staff manage the board in place**: Add member and Reorder at the top; Edit
  and Remove on each card. Bios have basic formatting (bold, italic, lists),
  filtered through an allowlist so stored HTML can't carry script.
  Removal is reversible — members go to a "Removed members" list.

## 0.9.1 — 2026-08-26
- **Fixed**: dropping files on the page opened the uploader empty. The browser
  empties `dataTransfer` the moment the drop handler returns, so the files are
  now copied out synchronously instead of being read back after a timeout.
- The "Add documents" button is now a dashed **drop area** headed *Add
  Documents*, so it's obvious files can be dragged straight onto the page.
  Clicking it opens the file picker and then the organising sheet.

## 0.9.0 — 2026-08-26
- **The library is now the one place staff work.** "Add documents" opens the
  uploader in a sheet, or drop files anywhere on the page and it opens with them
  already loaded. The separate Upload menu is gone; its URL redirects here.
- **Everything is editable in place.** A pencil on every group and every
  document opens a small dialog for name, date and category. Changing a
  **group's** date (and category) offers to move its documents with it;
  a **document's** own date never moves the group — the same rule the uploader
  follows.
- Old `/staff/upload/` redirects to the library with the uploader open, so
  bookmarks and the guided tour keep working.

## 0.8.0 — 2026-08-26
- **Guided tour for staff.** A welcome panel on first sign-in, then spotlit
  coach-marks that walk across pages — library, uploader, owners, activity —
  and resume after each navigation. Replayable any time from **Tour** in the
  menu. Keyboard (arrows/Escape), reduced-motion and small-screen handling;
  no dependencies.
- Progress is per user (`tour_seen_version`); bumping `TOUR_VERSION` re-offers
  the tour to everyone, which is what we want while the back office is changing.
- Steps are declared as data in `templates/_tour.html`, so they use real URLs
  and are cheap to rewrite; a test asserts every step's page still loads.

## 0.7.0 — 2026-08-26
- **Uploader rebuilt to the batch model.** Files land as small cards in a grid
  under the dropzone — icon, editable name, date, size. More than one file and
  they arrive already inside a **group** with a rename-me name ("May 13
  uploads") and a date.
- **Dates**: read out of filenames (ISO, d/m/y, "May 2024", bare year), falling
  back to the file's own modified date. Changing the **group** date cascades to
  every file; changing a **file** date does not touch the group.
- **Category suggestion** learns from the site's own filing history, weighting
  words by how distinctive they are — "strata" appears everywhere and decides
  nothing, "minutes" decides a lot. 7/8 correct on real Palms data (was 3/8),
  and it reports low confidence where history is thin.
- **Selection and drag-and-drop**: all files selected by default, click to
  toggle, drag the selection onto a category chip or onto one of the three most
  recent groups (or search for an older one). Per-file overrides beat the group.

## 0.6.0 — 2026-08-26
- **Sign in with a username OR an email address** (case-insensitive). Owners
  were migrated with WordPress usernames they never chose; the email is what
  they know. Refuses rather than guesses if two accounts share an address.
- **Staff back office** at `/staff/`, replacing Django's admin for daily work:
  - **Uploader** — drag-and-drop or pick, many files at once, titles proposed
    from filenames (and PDF metadata when it isn't junk), edit inline, then file
    the whole batch into a category/date and optionally a new collection.
    Document types only: html/svg/js/php are refused.
  - **Owners** — search and filter, add a person (email them a set-up link or
    generate a password to copy), send a reset link, generate a new password,
    deactivate, delete. Guards: no self-delete, no deleting the last admin.
- **Board page redesigned**: photo (or initials), name, role and contact email,
  expanding to the full profile. Emails show to signed-in owners only.
- `import_board` reads the real WordPress pages — detects the heading level each
  site used, skips bio section labels, and can take the roster from a contact
  table when a site's bio page is out of date.
- `X_FRAME_OPTIONS` DENY -> SAMEORIGIN so the same-origin PDF preview renders.

## 0.5.0 — 2026-08-26
- **Collections** replace the legacy primary/secondary file pair. Documents
  arrive in batches (one AGM's papers, a year's insurance renewal) and are now
  grouped that way; the 20 hidden second files became real documents.
- **Tags** for cross-cutting facts a category can't express (year, AGM, bio).
- **`organise_documents`** command: builds collections from same-day batches,
  refiles documents whose title disagrees with their category, and folds each
  site's legacy category names into one standard set. Dry-run by default.
- **Document browser**: collections as folders inside year sections, instant
  in-browser search, category chips, inline PDF preview, sibling documents on
  the detail page.

## 0.4.0 — 2026-08-26
- Full visual design pass on the owner-facing app: Newsreader/Public Sans type
  pairing, warm-slate neutral palette, sticky translucent header, card-based
  document rows with file-type badges, category chips replacing the dropdown,
  designed empty states, refined tables, and **dark mode**.
- Nav highlights the current section; document detail and board pages restyled.

## 0.3.0 — 2026-08-26
- Staff **Activity** page: who signed in and when (successes and failures), plus
  recent document downloads. The feature the client explicitly asked for.
- Record every sign-in attempt (`LoginEvent`) via Django's auth signals.
- **Password reset by email** end-to-end, with styled templates.
- Library: **pagination**, result counts, clearer empty state — 166 documents on
  one page was unusable.
- Document **detail page**; downloads reachable from list or detail.
- Version stamp surfaced in the footer.

## 0.2.0 — 2026-08-25
- Three instances from one codebase (Shore Club / Sands / Palms), each with its
  own database, document store and signing key; per-instance branding.
- WordPress importer (`extract_wordpress.py` + `import_wordpress`), idempotent,
  with a dry-run reconciliation report; `--protected-root` for files a
  protection plugin moved out of `uploads/`.
- Owner-facing library, board page, branded login.

## 0.1.0 — 2026-08-25
- Django skeleton, custom user model.
- WordPress password verifiers (phpass, WP 6.8 `$wp$`, bcrypt) with
  rehash-on-login, tested against real WordPress output.
- Private document storage + authenticated streaming download with noindex
  headers, download logging and rate limiting.
