Yuvomi
Self-hosted family planner for tasks, calendar, shopping, meals, and budget
Alternative to: cozi, familywall, skylight

v2.67.0
2026-09-16Added
-
The cycle tab grows into a full tracker: visible flow strength, feelings, more fertility signals, hard-private intimacy logging, PMS patterns, and a “today” insight bubble. The day log gains cervical mucus, LH and pregnancy tests, multi-select feelings (replacing the single mood), and intimacy - cervical mucus, the two test results and intimacy are never shown to anyone but yourself, even on days shared with the family, enforced by the server. On
POST /api/v1/health/cycle/logs,mood(kept for older clients) andfeelingsnow both accept only the fixed feelings list - an out-of-list value is a 400 instead of being stored as free text. Saving a day log through the app always sends the current feelings selection, so an older free-text mood value is cleared the next time that day is edited in the app; only a save that omits both fields entirely (outside the app’s own form) leaves it as-is. Flow strength finally shows up everywhere it matters: a four-step dot scale on the calendar, a heaviest-flow chip per period in the history, a per-cycle flow intensity chart, and a calm hint when recent periods run repeatedly heavy or over a week. A bubble at the top answers the daily question at a glance - cycle day and phase, plus whichever of these applies: period expected today (start it right there), symptoms likely today, a PMS window approaching, or the fertile window. Predictions got more honest along the way: a temperature-confirmed ovulation now also moves the month calendar (ring and calendar can no longer disagree), implausible gaps from overlapping or future-dated periods no longer poison the averages (the period dialog warns about both), the BBT chart spaces its points by real dates and breaks across logging gaps, and the likelihood overlay projects into the next cycle instead of only backwards. New per-person settings: contraception (hormonal methods pause the fertile-window prediction, with the reason shown instead of an empty tile), a perimenopause mode that predicts a date range rather than a false-precision single day, a PMS-window toggle, and an opt-in partner reminder that shares only the predicted date - never any log content. Period history can be imported from CSV (German date and separator formats included), the Health overview shows the next period at a glance, and the trends section was restructured around one expander per symptom with an added feelings-by-phase view and a pain summary. -
New optional module: Waste collection (#1063). Define your household’s waste types (recycling, organic, general, or your own, each with an icon and color) and a weekly or fixed-day-of-month pickup schedule for each. A single calculated pickup can be moved to a different date or skipped without touching the rest of the schedule, and moving one origin never hides another - a manual one-off pickup recorded on the same day a schedule occurrence moved away from still shows. One-off pickups cover irregular or special collections that are not part of any recurring schedule. A type with schedules or pickups cannot be deleted (archive it instead), so a season’s history is never lost by accident. Off by default; a household turns it on in Settings → Modules. A municipality’s ICS calendar file can also be imported: preview its pickups, map each label to a waste type (or create one on the spot, or ignore it), and commit - the file is re-parsed on commit so nothing is trusted from the preview alone, and re-importing next year’s file diffs cleanly into additions/changes/removals without duplicating or losing manual data. A source with no future mapped pickup is flagged for a refresh. An optional Dashboard widget shows the next pickup per active type, soonest first, and carries the same “needs a refresh” flag as the module page; hidden by default, like the module itself. A device-local Calendar layer, off by default, shows every type’s pickups in month, week, day, and agenda view; a pickup carries its type’s icon and color and opens the module directly, never the ordinary event editor. Beyond a one-time file import, a source can also subscribe to an ICS URL: it refreshes itself automatically on a configurable schedule (hourly to monthly), applying an update only once every label already has a confirmed mapping - unrecognized content is flagged for review instead of guessed at, and a manual “check now” is always available alongside the automatic schedule. Each household member can also opt into their own pickup reminders per waste type, choosing how many days ahead and what time of day (household-local) to be notified - personal, so a reminder never goes to someone who didn’t ask for it. A monthly schedule can now also follow an ordinal weekday - “the second Monday” or “the last Friday” of every month - alongside the existing weekly and fixed-day-of-month rhythms; the underlying shared recurrence engine gained this once and every existing recurring feature (Tasks, Calendar, CalDAV/ICS import) benefits from it, not just Waste. A revocable, personal read-only ICS feed of upcoming pickups is now available too (Settings → Feeds), with an optional per-type selection; a source’s label-to-type mapping decisions can be exported as a portable profile and re-applied to another source or household, without the app ever shipping a municipal/provider catalog. Waste types are now searchable from the global search bar, and the Calendar layer’s filter sheet gained a per-type visibility list nested under the one Waste toggle, so a rare collection is never silently hidden while a noisy one can be tucked away.
-
Waste page UX: labelled add-type entry point, unified row actions, curated type colors (#1146). The page now leads with a labelled “Add waste type” button rather than hiding all four actions behind one unlabelled menu, both empty states offer the step their own text describes, and the pickup button no longer dead-ends on a fresh install - without a type it now opens the type dialog instead of only saying that one is missing. Waste type, schedule, and source rows carry the same single overflow menu with named entries that the pickup rows already used, so a destructive action is no longer one stray tap away and an action whose meaning changes with the source finally says which one it is; every one of those menus now sits at the trailing edge of its row, and every row puts its icon beside the name instead of above it, so all four row types read the same way. A paused schedule is now visually distinct from an archived type instead of wearing the same badge. A type’s color comes from a curated palette instead of a free color picker, which had happily accepted a white or black icon that then disappeared against the light or dark background - an existing color outside the palette is kept, not silently overwritten.
-
A fasting journal records timers and past fasts in Health (Refs #1173). Start now or earlier, record completed intervals, and edit or undo changes with conflict protection. Elapsed/remaining clocks, personal goals and an optional educational dial preserve the recorded time zone. History loads ten records at a time; date filters and CSV cover the complete visible history. Family members can read shared records; personal settings stay private. Fasting is available to every member by default and an admin can switch it off per family role or person. Yuvomi records fasting and does not provide medical advice.
-
A calendar’s default assignee can now be applied to the events it already imported (#1154). Until now the mapping only reached events that arrived after it was set, so the first thing anyone saw after mapping a calendar was a list of unassigned events. Settings → Sync gains a one-off “Apply to existing appointments” action for admins: it runs over the calendars of all accounts that have a default assignee, names how many events it will touch, and fills only events that are not assigned to anyone yet. An assignment made by hand is left alone. ICS subscriptions are not included.
-
The Housekeeping Reports tab can step through past months (#1137). Until now it only ever showed the current month, and older reports were reachable only through a single worker in the Staff tab. A previous/next stepper with a jump back to the current month now sits next to the title, in the same order as Budget. The chosen month stays put while you work in it: marking a visit paid or editing one reloads that month instead of jumping back, and an empty month says which month it is.
-
A shopping list can be duplicated (#1103). “Duplicate” sits in the list menu next to rename/delete and copies every item into a new list, with category assignment and the manual per-category order always carried over - that is the point of duplicating, not a switch. Three flags control the rest: reset checked state, keep quantities, and keep notes & links, all on by default.
A duplicated item is a new, local item: CalDAV sync fields, the originating meal, any recorded price or shop, and tags are never copied. The first three each name something true of the original item only (a synced remote object, a specific meal, a price actually paid in a specific shop), never of a fresh copy - and tags are mirrored VTODO categories, so they follow the same rule as the sync fields they belong to.
-
A shopping suggestion carries its category and quantity (#1113, from discussion #1103). Picking a suggestion while adding an item now also fills in that item’s most recently used category and quantity, instead of only its name - without the category, every picked suggestion landed back in the fallback category and the aisle order had to be re-sorted on the next trip. Suggestions are also now ordered by most recently used first, instead of alphabetically - a household buys the same handful of things again and again, and the ones bought last stood out less behind everything the alphabet puts first. For API users this is a contract change on
GET /api/v1/shopping/suggestions: the response items are now objects{ name, category, quantity }ordered by recency, where they used to be plain name strings. -
A shopping list follows what the rest of the household does, while it is open (#1108). Two people in the same shop used to see two different lists: what one ticked off stayed unticked on the other’s phone until that page was reloaded. The open list now hears about changes within about ten seconds and redraws the affected rows in place - the same gesture as your own tap, no jump, no animation - and rebuilds only when an item was added, removed, renamed or moved.
The server keeps a change counter per list, maintained by database triggers rather than by the routes: shopping items are written from six modules (the list itself, meal-plan and recipe imports, the housekeeping module, MCP, the CalDAV to-do sync), and a counter that every writer has to remember is a counter one of them forgets. The counter also moves when a list is renamed, and its row goes with the list, so a list someone else deletes disappears from your screen too. The open page asks
GET /api/v1/shopping/versionsevery ten seconds while the tab is visible, and at once when it becomes visible or gets focus - the moment somebody looks at the phone. It reloads only a list whose number moved, through the same request it used to open it, so there is still one read path. Deliberately a poll and not an open stream: it works through any reverse proxy, holds no connection, and can grow into a stream on the same counter later. Your own taps do not cost a reload: the write routes answer with the counter before and after, and the page skips the reload when nothing else moved in between. -
BIND_ADDRESSsets the address the server listens on. Unset, nothing changes: the app listens on all interfaces, which is exactly what a container needs for its published port to reach it, so Docker, Podman, Unraid, TrueNAS and Umbrel installations leave it alone. When Node runs directly on a machine behind a reverse proxy on that same machine,127.0.0.1keeps the app itself off the network. The built-in MCP bridge follows the setting when it calls the API back. It is not the same asOIKOS_HTTP_BIND, which decides where the container engine publishes the port.
Changed
- Housekeeping staff and shared-expense guests no longer appear where you pick or list household members (#1207). The pickers for task assignees, calendar attendees, budget responsibles, schedule owners, medication owners, synced-calendar assignees and the Outlook account owner, the family list, the calendar’s person filter, mentions, the reward standings and enrolment and the Overview’s member cards now show household members only, and the household size counts them the same way - a household of one person and a cleaner is a household of one for what the app shows. Visibility, locking and document sharing stay available as long as anyone else can read the module, a cleaner with access included, so a new entry can still be kept private. Splitting an expense still offers the guests of that group, and guests can still be added to a group; housekeeping staff cannot. Nothing is taken away: a task, event, budget entry, schedule, synced calendar or document share that already names a staff member or guest keeps them, still shows them in its editor and can still be saved, and an event’s visibility stays as it was. Existing group memberships stay as well and still show in the group editor, so they can be ended. An old reward enrolment of a staff member or guest stays on record, but it no longer earns points, redeems or receives a bonus. Schedule rows on the dashboard keep their names; only choosing a staff member or guest anew is refused. User administration and permissions still list every account, API tokens every account except shared-expense guests as before, and the two-factor overview for admins now shows every account, housekeeping staff and guests included.
- The README is shorter between the introduction and the install steps (#1212). Each module gets one line in the module table, with the detail left to the spec, and “Before you commit” - what happens if the project stops, how to take your data elsewhere, what it costs - now comes before the first command instead of after it. The install section opens with the three ways in, lists the encryption key and the blocking of addresses on your own network as facts that apply to every path, and names the logs command for both Docker and Podman.
Fixed
-
A request with an API token is judged by the token’s own role, even when an admin session comes along. If the same client also sent the session cookie of a signed-in administrator, a request made with a member’s API token could still pass as an administrator in several places: calendar subscriptions and events, locked tasks, household note categories, documents and DMS connections, recipe providers, the shift schedule and split expenses. Each of them had its own admin check that also looked at the session. They now use the same check as every other route, which looks only at the role of the person the token belongs to. Signing in as an administrator without a token keeps full access, and a request with only a session or only a token behaves as before.
-
Form fields have a clearly visible edge in both themes. Text inputs, selects and text areas drew their resting edge in the same faint shade as card and group outlines, which rendered at 1.2 to 1.5:1 against the surface around them - well below the 3:1 a control boundary needs for people to find the field at all. Fields now have an edge color of their own, at 3.2 to 3.5:1 in the light theme and 3.9 to 5.5:1 in the dark theme on every surface they sit on: the sign-in page, dialogs, settings pages, the search overlay, and the search and quick-add fields above the lists. Card edges and separators keep their quieter shade, and a focused field still takes the accent color.
-
Set-aside cards and rows stay readable. Done and archived tasks (in the list and on the board), archived accounts, paused and completed subscriptions, inactive medications and rewards, archived waste types, paused pickups, and rows that an import has already added all faded out by turning partly transparent. That pulled every text on them below the 4.5:1 normal text needs, status badges and the initials in avatars included: 1.7 to 3.9:1 in the light theme, 2.4 to 4.2:1 in the dark theme. They now recede in one consistent way instead: the card sinks to a slightly deeper surface with a quieter edge, secondary details use the quieter text color, and titles, status badges, priority chips and avatars stay at full strength. They keep that look when the pointer rests on them, instead of lighting up like an active card. The amount of an expected budget entry is no longer faded either (3.5:1 and 3.0:1 before); it keeps its income or expense color, and the “expected” badge marks the row. In the birthday import dialog, the “already added” badge had no background at all and its text was practically invisible; it now shows in the module color again.
-
Checked-off shopping items look the same with reduced motion, and stay readable. A checked item was meant to fade as a whole, but that only happened for people who had reduced motion turned on, and for them its name and quantity dropped to 2.0:1 (light) and 2.5:1 (dark). Everyone else saw the item unfaded, because the fade-in animation of the list left a setting behind that overrode it. The animation now cleans up after itself, and a checked item recedes through quieter text colors instead of transparency: the name struck through in the secondary text color, details and tags in the tertiary one, at 5.4:1 or more in both themes. Its tags no longer fade on their own either (2.6:1 and 3.7:1 before). A checked item can still be tapped to reopen it, so it is not exempt the way a disabled control would be. The same leftover setting had also kept a dragged row or board card fully opaque, and stopped note and document cards from lifting slightly when the pointer rests on them; a dragged card now fades while it is being moved, and notes and documents lift on hover again, as intended.
-
An early click on the simple setup no longer overwrites an existing installation. The web installer locks its simple path when it finds an
.env, because that path sets host, port and cookie security itself. The lock only took effect once the installer had finished checking for the file, so a click in the moment before could still start the simple path and write over, for example, a setup running behind a reverse proxy. The simple path now waits for that check and continues in the advanced setup, where each of these values is visible, and its save step refuses to write over an existing file. The check itself no longer waits indefinitely for a container engine that does not answer: after a few seconds the installer carries on and treats the container as not running. -
The web installer shows an existing configuration as a warning, not as a hint. When the installer finds an
.env, the setup says that the current file will be backed up before saving - a setup that works is about to be replaced. That line was tinted like a plain hint; it now carries the same amber warning style and icon as the installer’s backup reminders. -
On the project page, the module list on phones folds away again, and the jump menu marks the right section after a language switch. On a phone, “Show all modules” opened the full list and then disappeared, so the list could not be shortened again; the button now stays and switches between all and fewer modules. The jump menu remembered where each section starts and measured again only when the window changed size, so after switching to the longer German page it highlighted the next section too early. It now measures again whenever the language changes or the module list opens or closes. The calendar screenshot also tells screen readers what it shows, instead of just “Calendar”.
-
A Google Calendar change made while the connection is down now reaches Google once it is back. Before pushing an edit or moving an event to another calendar, Yuvomi asks Google for that calendar’s details. When that request failed for a passing reason, such as no network, a token refresh or a rate limit, the change was handled like one for a read-only calendar and dropped: it never reached Google, and nothing said so. It now waits for the next sync and is only given up after the usual five attempts, or when Google reports the calendar as gone. A different calendar picked while a move is still under way is also no longer discarded when Google rejects that move.
-
The website and both READMEs now say what reaches out once you use a feature (#1212). Out of the box the only outbound request is still the update check against the GitHub releases API. The pages said that weather, calendar sync and cloud backup stay off until you enter credentials, but weather needs only a location, and once a country is set, holidays are fetched from openholidaysapi.org - except the public holidays of Australia, Brazil, Canada, New Zealand, the United Kingdom and the United States, which Yuvomi works out itself without a request. Opening the calendar settings loads the list of holiday countries from openholidaysapi.org as well, whether or not a country is set. Looking up a logo for a subscription contacts the service’s website, and push goes through your browser’s push service. The outbound line now names all of them.
-
A WebDAV backup URL made of whitespace no longer locks the backup settings. A space or line break in
WEBDAV_BACKUP_URL, for example from${WEBDAV_BACKUP_URL:- }in a compose file, was ignored as a URL but still marked the backup fields as set by the environment, so they could not be edited in Settings. Both now use the same check: only a value that is not blank comes from the environment. -
A modules folder set through
MODULES_DIRin.envis found again.docker-compose.yml,podman-compose.ymland the Podman Quadlet hand the.envto the container, and the app readsMODULES_DIRthere as its own folder: an absolute host path in it pointed the app at a folder nobody had mounted, so dropped-in modules never appeared. The three descriptors now pin it to/app/modulesinside the container; with Compose the.envvalue only moves the mount source, and the Quadlet keeps its host folder in the unit file. It reaches an existing install once its compose file or Quadlet unit is updated. -
The Unraid template no longer takes email, backup and document-storage settings out of the app’s hands. Seven of its variables shipped a value, and a value there wins over the matching setting in Settings, locking the email and document-storage fields. New containers leave them empty. A container created from the older template keeps what it was created with; clearing the variable on its Edit page hands the setting back to the app (see the Unraid section of the installation guide).
-
Belgian school holidays can be narrowed to one language community. OpenHolidays lists Belgium without any regions but splits its school holidays between the Flemish, French and German-speaking Communities, so the calendar settings had nothing to choose from and the calendar showed all three side by side. A country without regions now offers its school-holiday groups directly under Settings > Modules > Calendar, and the hint there no longer speaks only of Swiss cantons.
-
Housekeeping only offers visit actions you are allowed to take (#1135). A paid visit is settled, and only an admin can change or delete it - but the Staff log and the recent visits on the Overview showed edit and delete on every visit, so a member found out at save. The server now sends per visit whether the current user may edit or delete it. Where that is not allowed, the row offers the visit report instead and says that only an admin can change it. A calendar link to such a visit opens the report rather than a form that cannot be saved.
-
An item added without a category lands in the misc category again (#548). The item route had drifted to defaulting to the first category (“Fruit & vegetables” in aisle order). It now prefers the misc category by name as long as the household still has it, and only falls back to the last category in aisle order once it has been renamed or removed - “last” alone would have meant whatever category was added most recently, since new categories append at the end. The pantry import follows the same rule, so the two stay in step. In the same corner, quick-add’s category selector resets to the default after every item added, instead of staying on whatever a previous suggestion or manual pick set it to - an unrelated item typed right after could quietly land in the wrong aisle.
-
Household members and guests created as contacts now show the translated “Other” category instead of the German “Sonstiges” (#1140). The contact that is mirrored when a household member or a split-expenses guest is created carried the raw German word instead of the category key, so every non-German household saw it untranslated on the contacts page. New contacts get the proper key, and existing ones are corrected when the app updates.
-
Opening Housekeeping with a broken visit deep link now says so (#1139). Tapping a housekeeping visit in the calendar opens Housekeeping through an
?editVisit=<id>link; when that visit has been deleted or the link is malformed, it used to fail silently and land on the ordinary dashboard, with nothing to tell a stale link apart from a working one. It now shows a localized message - a missing or invalid visit says so without a retry, while a server error, a network problem or rate limiting offers to try again. The broken link is cleared from the address bar right away - only that parameter, the rest of the URL stays - so a reload or going back does not repeat the failed request. -
A full audit of the Schedule module, fixed in one sweep. The override editor no longer destroys typed input when its “fill the whole range?” confirmation is cancelled - the confirm now parks and resumes the open form instead of force-closing it, and the same holds if the confirmed save itself then fails: the form stays parked until the write actually succeeds, instead of closing on confirmation and leaving a failure toast over an already-empty page. A member with read-only access to the module sees an honest page: the banner was always there, but every create/edit/delete control rendered anyway and failed only on save; they are now gone, matching what the API has always enforced. Statistics and Overview refetch when the page is revisited (previously they re-labelled another user’s cached numbers as your own after a tab switch), show real loading and error states instead of zeros that looked like data, and rapid week-flipping can no longer let a slow older response overwrite a newer one. The dashboard “who’s working today” widget refreshes with the 15-minute cycle instead of showing the morning state all day, and a failed load renders the error tile with a retry button instead of the “create a shift type” onboarding. Shift-start reminders fire at the DST-correct minute around clock changes, enabling them defaults to a 15-minute lead instead of “at shift start”, and a reminder can no longer keep firing for a shift type deleted in the sync’s blind window. On the server, a pattern save is capped at 500 cycle-day rows (each stored row is re-emitted on every resolved read - an uncapped save was stored read amplification any member could create), deleting a pattern or a user no longer leaks its custom-field values, duplicate field ids in one payload are rejected instead of half-committing and answering 500, and omitting
field_valuesfrom an override save now preserves stored values, as the extras route always did. The statistics hint text in all 24 languages finally describes the rolling 7-day-window rule the overtime flag actually applies, the printed statistics sheet no longer leads with the personal reminder settings card, and a member with no schedule access no longer gets a dead “Schedule” calendar layer plus a guaranteed-403 request on every calendar load. -
A second pass on the Schedule module, this time on comprehension and everyday polish. Deleting a shift type now asks first, naming what it removes, like every other destructive action in the module already did. Two raw server strings that used to reach the toast (“shift_type_id must be a positive number.”, “cycle_length cannot exclude existing pattern days.”) are now plain sentences that say what to do next, and an Extra with no shift types yet shows a hint instead of an empty, submittable dropdown. Editing a pattern’s cycle days and leaving the tab (or the card) without saving now prompts to discard, matching the confirm every other unsaved-changes flow in the app already has; merely switching the Add-entry modal’s Pattern/Override/Extra segment no longer counts as a change worth asking about. Each cycle-day position shows the actual next date it falls on, with a one-line explanation of the repeating cycle; creating or reactivating a pattern that overlaps another one now asks first and names the consequence, and the pattern currently in effect carries a small marker. A household with no shift types yet opens on that tab instead of the planning tab it would immediately dead-end on. Every schedule tab now has its own address (
/schedule/patterns,/schedule/statistics, …), so reloading keeps the tab, the back button walks between tabs instead of leaving the page, and the dashboard widget and a shift reminder both link straight to the relevant tab instead of the bare module. Clicking a shift anywhere it appears (the Today card, the Compare view, a week/day calendar block) now opens a small read-only detail view instead of doing nothing; week/day calendar chips show the full time range instead of just the start; and the “Free today” hero and the per-member status row on the dashboard no longer contradict a schedule entry sitting right next to them. The Statistics owner picker is self-only for non-admin members now - statistics remain a read-only summary of data everyone can already see via the Today card and calendar, but the convenience of pulling up someone else’s totals was never meant to be open to everyone. Shift-type presets are grouped by template (Work/School/University) instead of one flat list of fifteen, the reminder lead time accepts any custom value up to the server’s own 24-hour cap instead of the seven fixed presets, and an expanded shift-type card spans the full row instead of leaving a gap beside it. Tracking overtime at all is now its own switch next to the weekly-hours target, instead of that number being the only way to affect whether the Statistics tab flags anything - turning it off removes the overtime card entirely rather than requiring a number nobody’s schedule will ever cross. All of the above is translated into all 24 languages. -
Schedule: a stable “Today” card and one clear way to add an entry. The Today card used to be the first block of the Planning/Shift-types tabs only, so switching to Statistics or Compare made it vanish and everything below it jump up to fill the gap; it now renders once, above the per-tab content, and simply stays in place across every tab (still hidden entirely for a household that hasn’t used the module yet). The Planning tab offered up to four “add” affordances at once - the page’s own FAB, an always-visible “Create override” button, an always-visible “Add extra shift” button, and each section’s empty-state CTA underneath its own always-visible twin; a household with nothing entered yet saw two identical buttons stacked in both the Overrides and Extras sections. The FAB (which already opens the same form, pre-selecting the right mode) is now the one durable way in; the section headers no longer carry their own button, and each empty-state CTA remains as the contextual nudge for first-time setup, matching how the Patterns section already worked. The three quick-start template buttons on the Shift-types tab looked like a segmented toggle even though picking one is a one-shot action with no “selected” state to show - they’re plain buttons now, and the household’s own hidden-template setting still filters which ones appear. The Compare tab’s day headers scrolled away with the hours beneath them; they now stay pinned to the top of the scroll area while the day’s shifts scroll past, so a block halfway down a long day is never orphaned from the day it belongs to.
-
The calendar keeps keyboard focus when a deletion is committed (#1083). A deleted event disappears at once and is removed for good once the Undo notice runs out, and the view then draws itself once more. Whatever you had moved on to in the meantime, for example the next row in the agenda, lost focus at that moment, so the next Tab started again at the top of the page. That element now keeps focus across the redraw. Pressing Undo from the keyboard lost focus the same way, because the notice removes its button before the event comes back; focus now lands on the restored event.
-
A dialog no longer moves keyboard focus into its first field after you have already moved on (#1156). Opening a form puts focus into its first field a moment later. On a slow or busy device that moment could arrive after you had already acted, for example after answering a save confirmation, which hands focus back to the Save button: focus then jumped to the first field instead, and nothing brought it back. The same could pull focus out of an open date picker. The first field now stays out of the way once focus has moved inside the dialog or into something on top of it, such as a date picker; focus that lands on the page behind the dialog still moves in.
-
The warning about a password login that is still open now names the administrator condition (#1194).
AUTH_ALLOW_PASSWORD_LOGIN=falseonly takes effect once an administrator account is linked to the OIDC provider; a member signing in through SSO does not arm it, so that an administrator without a linked account cannot be locked out of the administration. The startup warning said that no account was linked, so an operator whose member had already signed in through SSO read the switch as armed while the login form was still open. It now says administrator. In the same pass the Portainer compose file stopped defaultingOPENWEATHER_LANGtode, where the code,.env.example, the Unraid template and the installation guide all useen. -
Shared expenses embedded in Budget no longer skip a heading level (#1190). The embedded tab title is a level-2 heading, which left the group name beside it at the same level and its Balances, Recent expenses and Activity cards directly under the title instead of under the group. The group name is now a level-3 heading and those cards level 4, so the outline a screen reader announces reads Budget, then Shared expenses, then the group, then the section. Nothing moves visually: size, weight, line height, margin and color are unchanged.