Repository navigation
SPEC 022 Interface Design Navigation
| Status | Draft |
| PRD source | F11 (FR-12.1–12.36) |
| Depends on | SPEC-001, SPEC-002, SPEC-004, SPEC-005, SPEC-010, SPEC-011, SPEC-016, SPEC-018, SPEC-020 |
| Required by | — |
| Milestone | M10 |
The first twenty-one specs each owned their own screens, and M0–M9 built them one at a time. #33 gave those screens shared tokens, primitives and patterns (docs/guidelines/DESIGN.md). Three things were never decided anywhere, though:
- the brand colour. DESIGN.md DL-08 left a placeholder hue.
- how a destination organises more than one task.
- where each thing lives.
A walkthrough of the personal instance on 2026-10-09 showed what that cost:
- The interface reads as black with white text.
- Carteiras and Importar stack every task on one long page, and Importar's history pushes the export guide off the screen. Relatórios uses tabs instead.
- Pages start at different left edges.
- Field instructions break the alignment of a row of fields, and select controls clip their own text.
- There is no way to sign out, although BR-001-07 specifies what sign-out must do.
- The theme switch is buried in Preferências.
The constraint that shapes the navigation is current state versus performance over time.
- "What do I hold now" covers values at the latest quote, composition, how holdings spread across wallets, and progress towards goals.
- "How did it perform over a period" covers growth, return against indexes, and earnings.
Only the second question takes a period. The navigation follows that line: Portfólio answers the first, Relatórios the second. The data draws the same line. The first question reads current positions and the latest quote. The second reads DailyValuationSnapshot over a range (SPEC-011, BR-011-13). The owner's reference tool, Status Invest, makes the same distinction.
Setup moves away from figures. Creating wallets and assigning assets, importing extracts and defining watch rules move to Configurações. Settings that belong to the person rather than to a feature move to an account menu: account, preferences, privacy, theme and sign-out.
Boundary with DESIGN.md.
- This spec owns what the interface must do: the destinations, the obligations every page meets, how value masking behaves, and how themes behave.
- DESIGN.md owns how: the tokens, the components and the
DS-rules. It is amended in the same PRs that implement this spec. - A visual prototype, approved by the owner, comes before any screen migrates (DL-022-01).
| ID | Rule |
|---|---|
| BR-022-01 | Primary navigation lists exactly five destinations, in this order: Dashboard, Portfólio, Relatórios, Transações, Configurações. (Amended 2026-10-12 — see DL-022-16.) |
| BR-022-02 |
Portfólio shows the current state of holdings, valued at the latest quote, and takes no period. Its tabs are: • Patrimônio: the current total, broken down by class and by asset. • Composição: SPEC-015, current composition. • Carteiras: how holdings spread across wallets, wallet comparison by value, and balancing (SPEC-010, SPEC-017). • Metas: SPEC-019. |
| BR-022-03 | Relatórios shows performance over a period, and every tab takes one (BR-011-01). Its tabs are Evolução patrimonial (SPEC-013), Rentabilidade (SPEC-012) and Proventos (SPEC-014). Composition drift over time (BR-015-04) is shown in Evolução patrimonial, as the series stacked by grouping (BR-013-05). It is not shown in Portfólio, which takes no period. |
| BR-022-04 | Transações remains a destination of its own. The ledger is the source every figure derives from, and it is where manual entries are made (SPEC-006). |
| BR-022-05 |
Configurações holds setup and never shows a portfolio figure. Its sections are: • Carteiras: create, edit, delete, assign assets, standing rules (SPEC-010). • Importar: SPEC-005. • Observar preços: the rules (SPEC-018). |
| BR-022-06 | In the pt-BR interface the whole portfolio is called Portfólio, and the purpose groups are called Carteiras. "Carteira" never names the whole portfolio. The domain model is unchanged. |
| BR-022-07 |
Dashboard summarises and links to the detail; it owns no detail of its own. Each card links to the destination that owns its detail. It carries: • the headline figures with their freshness (BR-005-27); • the reconciliation status (BR-005-26); • "Precisa da sua atenção" (BR-010-12, BR-020-15); • a card listing held assets currently in a buy or sell state (SPEC-018), each linking to its rule. |
| BR-022-08 | Every URL that existed before this spec keeps working. A moved screen's old path redirects permanently to its new one. E-mails already sent link to the old paths, as do bookmarks. Those e-mails include SPEC-018 notifications and SPEC-005 reminders. |
| ID | Rule |
|---|---|
| BR-022-09 | Every authenticated screen has a top bar holding a breadcrumb, the masking toggle (BR-022-24) and an account menu. The menu shows the user's name, e-mail and picture as Google supplies them (BR-001-05). The breadcrumb, at the start of the bar, names where the page sits: the destination, then its tab or Configurações' section, then the section's task, as deep as the page goes, e.g. “Dashboard”, “Portfólio › Composição”, “Configurações › Importar › Histórico”. Each earlier crumb links to its level; the last is the current page. A page that is not a task (one wallet, one import batch, “Nova carteira”) ends at the task it belongs to. Below the md breakpoint it is hidden, where the brand and the menu button hold that slot. (Amended 2026-10-18 — see DL-022-27.)
|
| BR-022-10 | The account menu holds everything that belongs to the person rather than to a feature: Conta, Preferências, Privacidade, the onboarding guide's help entry (BR-020-13), the theme switch (BR-022-30) and Sair. |
| BR-022-11 | Sair is one menu action away from every authenticated screen. It invalidates the session server-side (BR-001-07) and lands on the sign-in page. It is a form submission, never a link that a prefetch could trigger. |
| BR-022-12 | Conta shows the profile read-only, exactly as Google supplies it, and links to Privacidade for export and deletion. It never duplicates SPEC-004's controls (BR-004-09). |
| BR-022-13 | Preferências holds only personal preferences: theme, reminders and display defaults (report grouping, benchmarks). A registry key that tunes a feature with a Configurações section is rendered in that section instead: import windows and staleness under Importar, drift tolerance under Carteiras, the opportunity e-mail cooldown under Observar preços. A feature with no Configurações section keeps its keys in Preferências: the report thresholds stay there (DL-022-14). The split is derived from the registry, so both screens stay generated (SPEC-002; DESIGN.md DS-30). |
| ID | Rule |
|---|---|
| BR-022-14 | Every destination renders in one page frame: a header, then the content. The header carries the title, the primary actions on the right and, where it applies, the scope selector (BR-022-17). Every destination shares the same left edge and maximum width; a page never chooses its own. |
| BR-022-15 | A destination with more than one task presents them as tabs: one task per tab, each tab with its own URL. A page never stacks unrelated tasks vertically. |
| BR-022-16 | Configurações uses two rows of tabs: its sections — Carteiras, Importar, Observar preços — as the same main tabs every destination uses, and each section's tasks as smaller pill tabs beneath them. No destination uses a vertical sub-navigation. (Amended 2026-10-12 — see DL-022-18.) Each section's tasks: Importar has three: Enviar, where the upload sits beside the B3 export guide (SPEC-020) so both are visible together, Histórico, and Parâmetros, which holds its registry keys (BR-022-13). |
| BR-022-17 | Portfólio and Relatórios share one scope selector in the page header: all wallets, or a single wallet (BR-011-02). The selection is carried in the URL, so switching tabs keeps it (BR-011-11). It replaces each report's own scope field. |
| BR-022-18 | A collection of records renders as a table: • sortable columns; • pagination with a selectable page size (10, 25, 50, kept in the URL) for every table whose rows grow with the portfolio — only tables of a few fixed rows (the value decomposition, the benchmarks) are unpaginated; • a search or filter bar when the collection can exceed one page; • an empty state (BR-011-16); • text, dates and badges aligned left, quantities, amounts and percentages aligned right, each header aligned like its column; • a width per column set by the table definition, never by its content, so hiding values (BR-022-24) never moves a column; • text that does not fit ends in an ellipsis, and the full text opens on hover, keyboard focus and tap; a number is never truncated. A list never grows a page without bound. Narrow screens keep the card rendering (DESIGN.md DS-28). (Amended 2026-10-12 — see DL-022-17.) |
| BR-022-36 | Every block of content sits in a panel: a bordered surface with a header holding its title and actions, and an optional footer for pagination, a link or actions. Only the page title, its description and the tabs sit outside panels. Panels use an 8 px corner radius; fields, buttons and menus 6 px. (Added 2026-10-12 — see DL-022-24.) |
| BR-022-19 | Desktop is the design target. Widths down to 360px keep working (BR-016-19), without dedicated layouts. |
| ID | Rule |
|---|---|
| BR-022-20 | A field's instructions render as an info icon beside its label. The icon opens on hover, on keyboard focus and on tap, and the instructions stay in the field's accessible description. Instructions never change a field's height, so fields in a row stay aligned. |
| BR-022-21 | Validation errors are never hidden behind the icon. They render inline, under the field. |
| BR-022-22 | No control clips its own text. A select shows its full selected value at its default size. |
| BR-022-37 | Every create or edit form follows one layout: a panel with a title; fields in a two-column grid with labels above them, a short field taking one column and a long one spanning both; a footer with Cancelar, then the primary action, at the right, and a destructive action alone at the left. Narrow screens stack to one column. (Added 2026-10-12 — see DL-022-21.) |
| BR-022-23 | Every visible string is pt-BR, including native control chrome: a file field shows Portuguese text, never the browser's "Choose Files" (BR-016-17). Every date is dd/mm/yyyy, including period labels (BR-016-18). |
| ID | Rule |
|---|---|
| BR-022-24 | An eye toggle in the top bar masks every money amount, and the value labels and tooltips of value charts, on every authenticated screen. Quantities, percentages and chart shapes stay visible. |
| BR-022-25 | The masking state is a user-level preference (ui.hide_values, SPEC-002) and is applied when the server renders the page. An unmasked amount is therefore never painted, not even before hydration, and the state follows the user to another device. |
| BR-022-26 | A masked amount renders as a fixed-width placeholder (R$ ••••••), whatever its magnitude, so the number of digits does not leak. Its accessible name says the value is hidden. |
| BR-022-27 | Masking affects display only. CSV exports (BR-011-12) and data-rights exports (SPEC-004) are explicit requests for the data, and are never masked. |
| ID | Rule |
|---|---|
| BR-022-28 | The brand colour is a navy blue, used for actions, navigation state and focus, never for a figure. Gains stay green and losses red, always with a sign or an arrow (DESIGN.md DS-09). The in-progress status colour never shares the brand's hue, so a badge never reads as a button. The brand stays distinguishable from the gain green, the loss red and the in-progress status under protanopia and deuteranopia, verified by simulation. |
| BR-022-29 | Light and dark are both first-class themes. Every token is defined in both, and both meet WCAG 2.1 AA (BR-016-15). The dark theme separates page, card and raised surfaces by lightness, never as one black plane. |
| BR-022-30 | The theme switch offers Claro, Escuro and Sistema. It lives in the account menu, applies without a reload, and persists on the account (ui.theme, DESIGN.md DS-29). New accounts default to Sistema. |
| BR-022-31 | Status badges use semantic colours: success, in progress, warning, danger and neutral. A warning, such as an open divergence, never uses the loss colour or the destructive-action colour (DESIGN.md DS-05). |
| BR-022-32 | Each concept has one wording across all screens, and a label sits beside the figure it qualifies. Estimates are two concepts with two labels: Valor estimado beside a value priced from a contracted indexer rather than a market (SPEC-009 BR-009-11), and Custo estimado beside a cost or preço médio that includes an acquisition B3 states no price for (SPEC-007 BR-007-06). Each label carries an info icon that opens its explanation on hover, focus and tap (BR-022-20) — never only the browser's native title. (Amended 2026-10-12 — see DL-022-19.) |
| BR-022-38 |
A money chart shows reais. Its value axis reads in abbreviated reais — “R$ 250 mil”, “R$ 1,2 mi”, whole reais below one thousand. Its tooltip shows the date and the exact amount with centavos, formatted on the server from the decimal value (ARCHITECTURE AR-09), never from the number the chart plots. Masked, both read R$ •••••• (BR-022-24). (Added 2026-10-12 — see DL-022-23.)
|
| BR-022-42 | A chart's date axis reads pt-BR months, never an ISO date. A daily series ticks as month and year — “nov/25”, “jan/26”; a monthly series as the month alone — “nov”, “jan”, “set”. The tooltip keeps the full date or month (BR-022-38). BR-016-18 applies to chart axes too. (Added 2026-10-17 — see DL-022-26.) |
| BR-022-33 | The active navigation item looks the same on every destination, and looks different from the keyboard focus ring. |
| ID | Rule |
|---|---|
| BR-022-34 | A total is never summed across rows of different units. A quantity total appears only where every row is the same asset. Wallet comparisons and grouped reports show value, cost, return and share of portfolio instead. Today Reserva de Oportunidade reads 30.500.000, a count of R$ 0,01 CDB units, and a report total reads 30.520.243,4. |
| BR-022-39 | Two invested figures, two names. The cost of what is held now — quantity × preço médio — is Valor aplicado, on the Dashboard and in Portfólio. The money put in minus the money taken out — SPEC-013's total invested (BR-013-04/08) — is Aportes líquidos, in Relatórios. Each carries an info icon saying what it measures and why the two differ: profits from sales reinvested, and bonificações, raise the cost without new money. (Added 2026-10-12 — see DL-022-20.) |
| BR-022-40 | Transações fits the page width without horizontal scrolling: the broker sits under the asset, status and origin share one cell, and row actions sit in a “⋯” menu, with BR-022-18's fixed widths and truncation. (Added 2026-10-12 — see DL-022-22.) |
| BR-022-41 | Every wide table fits the page width at 1280 px without horizontal scrolling, by merging columns rather than squeezing figures (BR-022-18): Portfólio's holdings carry the class, sector and watch state under the asset and the share under the value; Evolução patrimonial's composition is one row per date and class (Data, Classe, Valor, Participação); Carteiras' balancing carries the quantity under the value and the count of cotas under the distance in R$; Observar preços' rule actions sit in a “⋯” menu. A column sized below its kind's default says why. (Added 2026-10-13 — see DL-022-25.) |
| BR-022-35 | Every item in "Precisa da sua atenção" names the asset or assets and the movement type involved, and what resolves it: a re-import, a decision by the user, or a fix not yet shipped. An item never consists only of an import date and a row count (BR-020-18). The per-row decision is SPEC-005 BR-005-20f. |
- The owner has approved a visual prototype, recorded in the Decision log with the prototype's link and date. It covers both themes, the component set, the frame with its navigation, and three pages: Painel, Portfólio › Patrimônio and Configurações › Carteiras.
- The sidebar lists exactly Dashboard, Portfólio, Relatórios, Transações and Configurações, in that order. No other primary destination exists.
- No Portfólio tab renders a period control. Every Relatórios tab does.
- Wallet comparison, balancing and goals are reachable under Portfólio. Creating, editing and deleting a wallet are reachable only under Configurações › Carteiras, and so are standing rules and the full assignment queue. Assigning assets is also offered where SPEC-010 BR-010-09/15 place it (DL-022-15).
- No pt-BR string uses "Carteira" to mean the whole portfolio.
- Every pre-M10 route answers with a permanent redirect to its new location, and a link from an existing notification e-mail lands on the right screen.
- Sair works from every authenticated screen. Afterwards, the old session cookie is refused by the server, and a GET request alone never signs the user out.
- The account menu shows the Google name, e-mail and picture, and holds Conta, Preferências, Privacidade, the onboarding guide, the theme switch and Sair.
- Preferências shows no import, wallet or watch parameter; each of those renders in its feature's Configurações section. Adding a new registry key needs no screen change.
- Every destination's content starts at the same left edge and has the same maximum width, checked by a structural test, not by eye.
- No page stacks two unrelated tasks; each tab has its own URL, and reloading a tab keeps it selected.
- Choosing a wallet in the scope selector and switching between Portfólio and Relatórios tabs keeps that wallet. The scope survives a reload through the URL.
- The import history, the transaction list and every other collection paginate. With 300 imports, the Importar › Enviar tab still shows the export guide without scrolling past the history.
- A field with instructions has the same height as its neighbours. The instructions open on hover, on focus and on tap, and are read by a screen reader with the field.
- A validation error is visible without opening any icon.
- Every select shows its full selected value: Período, Escopo and Agrupar por on Relatórios, and every other select, checked in both themes.
- No English browser chrome is visible, and no date renders as
yyyy-mm-dd. - With masking on, no money amount and no value-chart label or tooltip appears in the rendered HTML of any authenticated page, and the toggle state persists across devices.
- A masked amount has the same rendered width whatever its value.
- A CSV export taken with masking on contains the real figures.
- Both themes pass axe colour-contrast on every destination, and the brand navy is distinguishable from the gain green, the loss red and the in-progress status under simulated protanopia and deuteranopia.
- The theme switch in the account menu changes the theme without a reload, and the choice persists on the account.
- An open divergence renders as a warning badge, never in the loss or destructive colour.
- Estimates read “Valor estimado” beside a value and “Custo estimado” beside a cost, each with an info icon whose explanation opens on hover, focus and tap; no other estimate wording exists in the pt-BR catalogue.
- The active navigation item renders identically on every destination, whether or not it has keyboard focus.
- No grouped view or wallet comparison shows a quantity total across different assets.
- Every "Precisa da sua atenção" item names its asset(s), its movement type and what resolves it.
- The Dashboard lists held assets currently in a buy or sell state, each linking to its rule.
- Every screen built after 2026-10-12 matches its frame on SPEC-022-Prototype › Ajustes, in both themes.
- Configurações shows its sections as main tabs and each section's tasks as pill tabs; no destination renders a vertical sub-navigation.
- Every block of content below the tabs sits in a panel; no panel or card uses a corner radius above 8 px.
- Every table whose rows grow with the portfolio paginates; text columns align left and figure columns right, headers included; toggling hidden values changes no column's width (measured, not eyeballed).
- A truncated cell ends in an ellipsis and shows its full text on hover, focus and tap; no number is truncated.
- Every create and edit form uses the two-column panel layout, with Cancelar and the primary action at the bottom right and any destructive action at the bottom left.
- Every money chart's axis reads in abbreviated reais and its tooltip shows the exact amount with centavos, matching the figure in the table beside it.
- No chart axis shows an ISO date: daily series tick as “nov/25”, monthly series as “nov”.
- Portfólio and the Dashboard say “Valor aplicado”, Relatórios says “Aportes líquidos”, and each explains itself through an info icon.
- Transações renders without horizontal scrolling at 1280 px with 10 000 transactions.
- From
mdup, every authenticated page shows a breadcrumb in the top bar that matches the current sidebar item, tab and task, and updates on a client-side tab switch.
- New report content. The tabs regroup existing reports. The only new figure is the Painel's watch-state card, and it reads SPEC-018's existing evaluation.
- Asset logos. The reference tool shows them, but this project has no licensed source for them.
- A global asset search bar.
- Dedicated mobile layouts or a native app (BR-022-19).
- Changing the gain and loss colours. DESIGN.md DL-05 stands.
- A webfont. DESIGN.md DS-12 stands, unless the approved prototype says otherwise, in which case the decision is recorded here.
- Moving account deletion out of Privacidade (SPEC-004).
- Any change to a calculation. The data defects found during the same walkthrough have their own issues: #197, #198, #199 and #200.
| # | Decision | Alternatives considered | Rationale |
|---|---|---|---|
| DL-022-01 | A visual prototype is approved before any screen migrates. | Implement tokens and components directly, and review the result screen by screen in PRs | When a redesign is reviewed one PR at a time, every later screen copies whatever the first PR happened to do. Approving the palette, the frame and three pages up front gives every later PR a fixed target. It costs one review instead of one per page. |
| DL-022-02 | Navigation splits current state (Portfólio) from performance over time (Relatórios). | Keep wallet analysis on the wallets page (status quo); move all wallet analysis into Relatórios (the owner's first answer, superseded after the reference walkthrough) | Only views over time take a period. Mixing the two puts a period control on views it does not affect. The split also follows the data: positions plus the latest quote, versus snapshots over a range (BR-011-13). It matches the owner's reference tool. |
| DL-022-03 | "Portfólio" for the whole, "Carteiras" for the purpose groups. | "Carteira" and "Subcarteiras", as Status Invest does; "Minha carteira" and "Carteiras" | Owner's choice. Carteiras is the product's own concept, used across five specs and in the interface since M3. Renaming it would churn every wallet screen and e-mail. "Portfólio" is unambiguous. "Minha carteira" would leave the same word naming two things. |
| DL-022-04 | Transações remains its own destination. | A tab inside Portfólio, as Status Invest does | The ledger is neither current state nor a report: it is the source both derive from (SPEC-006), and the one place where manual entries are made. |
| DL-022-05 | Navy brand on near-neutral graphite surfaces; gains stay green. Amended 2026-10-09 during the #202 prototype review; the decision was first a teal. | A teal (the first choice, superseded: in the prototype it read as Status Invest, at any lightness or chroma); plum, mauve, cobalt, slate, graphite ink and wine (prototype rounds 1–3); a green brand with gains recoloured; neutral figures that rely on signs alone | Owner's choice after three prototype rounds. The product needs an identity of its own, and plum and mauve did not suit a financial administration tool. Outside blue, every hue left collides with gain, loss or warning under colour-vision simulation, except graphite and wine. Graphite surfaces, instead of blue-grey ones, make the dark theme graphite rather than navy and leave the brand as the screen's dominant blue. The in-progress status moves to violet so it never matches a button. Recolouring gains breaks the broker convention in DESIGN.md DL-05. Neutral figures discard a cue every Brazilian investor reads. Keeping the brand off figures entirely means it never sits where a gain is expected. |
| DL-022-06 | Masking is persisted on the account and applied by the server. | Per device in browser storage; always start visible; always start hidden | Browser storage is read only after the first paint, so every amount would flash before hiding, which defeats the purpose in exactly the situation the feature is for. An account-level key follows the user across devices, the same way ui.theme does. |
| DL-022-07 | Masking covers money amounts and value-chart labels, not quantities or percentages. | Also mask quantities; also mask percentages | Owner's choice. Percentages reveal performance, not wealth. Known limit: a determined viewer can multiply a quantity by a public price. Masking defends against a glance at the screen, not against inspection, and does not claim to. |
| DL-022-08 | Field instructions sit behind an info icon that opens on hover, focus and tap; errors stay inline. | Inline hint text (status quo); hover only | Inline hints change a field's height, which misaligns the row (Configurações › Carteiras' "Objetivo"). Hover-only content is unreachable by keyboard and touch (WCAG 2.1.1, 1.4.13). An error hidden behind an icon is an error nobody reads. |
| DL-022-09 | One scope selector in the page header. | A scope field in each report (status quo) | Per-report fields lose the scope on every tab switch. A single selector carried in the URL is BR-011-11 applied across tabs. |
| DL-022-10 | Preferências is split by kind: personal preferences in the account menu, feature parameters next to their feature. | Move the whole page to the account menu; keep the whole page under Configurações | A drift tolerance belongs next to the wallets it tunes. Deriving the split from the registry keeps both screens generated (DESIGN.md DS-30). |
| DL-022-11 | Desktop first. | Full mobile parity; desktop only | The instance is loopback-only on a laptop (SPEC-021). Dropping narrow widths entirely would break BR-016-19, so they keep working, but without dedicated design effort. |
| DL-022-12 | Importar uses three tabs: Enviar (upload beside the guide), Histórico and Parâmetros. | One page with the guide beside the upload and the history last; two tabs with the parameter form under the upload | It applies BR-022-15 consistently. A single page still grows with the history, and a parameter form under the upload stacks two unrelated tasks. Parâmetros follows Carteiras' tab (#210 Decision log #1). Amended from two tabs in #211 (Decision log #1); acknowledged by the owner on 2026-10-11. |
| DL-022-13 | The visual prototype is approved (2026-10-09): rendered on the SPEC-022-Prototype page; source https://claude.ai/artifact/P2aaV4bdgs48CUKSYFzxC6 — the palette with its contrast table and colour-vision simulation, the component sheet, the frame with the account menu open, and Painel, Portfólio › Patrimônio and Configurações › Carteiras, each in both themes. Every later M10 PR is measured against it (DL-022-01). | — | Owner's approval after one review of the whole prototype and three rounds on the brand colour (DL-022-05). The approved token values are in Approved tokens, and the approved screens are rendered on SPEC-022-Prototype, so the implementation does not depend on access to the prototype, which is private to the owner. Process record: #202. |
| DL-022-14 |
Report thresholds stay in Preferências — the concentration limit (reports.concentration_threshold_pct) and the TWR/XIRR divergence threshold (reports.twr_xirr_divergence_points). The AC reads "no import, wallet or watch parameter". |
A Configurações › Relatórios section for the two keys | BR-022-05 gives Relatórios no Configurações section, and BR-022-13 moves a key only to a feature that has one. Both thresholds change only what a report displays, never stored data — a display default, like grouping and benchmarks. The earlier AC wording ("no … report-threshold parameter") contradicted both rules. Acknowledged by the owner on 2026-10-10 (#207 Decision log #3). |
| DL-022-15 | Assignment is not exclusive to Configurações › Carteiras. Creating, editing and deleting a wallet, standing rules and the full queue live only there; the post-import summary and Transações' bulk "Atribuir à carteira" keep their assign actions. | The AC as first written: assigning assets reachable only under Configurações › Carteiras | SPEC-010 BR-010-09 offers assignment from the holdings screen, the wallet screen and the post-import reconciliation screen, and BR-010-15 makes every pending purchase "resolvable there". The original AC contradicted both. Found in the #210 review; acknowledged by the owner on 2026-10-11. |
| DL-022-16 | “Dashboard” replaces “Painel” as the label of the landing destination. (2026-10-12.) | Keep “Painel” | Owner's choice. The address was already /dashboard, and the owner's reference tool uses the same word. BR-016-17's market vocabulary (proventos, preço médio, patrimônio, rentabilidade) is about financial terms, not navigation labels. |
| DL-022-17 | Text left, numbers right; columns sized by the table, not the content; long text truncated with its full text on hover, focus and tap. (2026-10-12.) | Everything left-aligned (the owner's first request); auto-sized columns (status quo) | Right-aligned figures in tabular digits put units under units, so a column of reais compares at a glance — the convention of every broker statement and spreadsheet; the owner chose it over all-left once that trade-off was put to them. Auto-sized columns move whenever the masked placeholder replaces a figure, which was the reported defect. Truncation keeps a fixed width honest without hiding information. |
| DL-022-18 | Configurações uses two rows of tabs instead of a vertical sub-navigation. (2026-10-12; supersedes BR-022-16's sub-navigation.) | One flat row of about eight tabs; the vertical sub-navigation (status quo) | Owner's request: the sub-navigation made Configurações the one destination out of pattern. A flat row loses the grouping by section. Sections become main tabs like every other destination's, and tasks become pill tabs beneath them. |
| DL-022-19 | Two estimate labels — “Valor estimado” and “Custo estimado” — each with an explaining info icon. (2026-10-12; amends BR-022-32's single wording.) | One label “Estimado” with an icon whose text names the case | The owner could not tell what “Estimado” meant, and it meant two different facts: an accrued fixed-income value (SPEC-009) and a cost that includes an unpriced subscription (SPEC-007). One word for two facts is the ambiguity BR-022-32 exists to prevent. The explanation moves from the native title, which touch and keyboard users never see, to the info-icon pattern. |
| DL-022-20 | Keep both invested figures and name them apart: “Valor aplicado” (cost of current holdings) and “Aportes líquidos” (net money put in). (2026-10-12.) | Show only the cost of holdings everywhere; show only net contributions everywhere | Reported as a divergence — Portfólio's Valor aplicado against Relatórios' Total investido, R$ 49 mil apart on the owner's instance — and found to be two correct, different measures, not a defect: realised profits reinvested and bonificações raise cost without new money. Each answers a real question (what did my holdings cost; how much did I put in), so neither is dropped; distinct names and an explanation end the apparent contradiction. No calculation changes. |
| DL-022-21 | One form layout: a panel, two columns, labels above, Cancelar and the primary action at the bottom right, destructive at the bottom left. (2026-10-12.) | Settings style (group title left, fields right); a single fixed-width column | Three layouts coexisted (a four-column grid with right-aligned buttons, stacked fixed widths with left-aligned buttons, inline forms). Two columns keep the longest form (Nova transação, 13 fields) short; the settings style wastes width on a laptop for short forms. |
| DL-022-22 | Transações fits by merging columns — broker under the asset, status with origin, actions in a “⋯” menu — with fixed widths and truncation. (2026-10-12.) | A column picker; horizontal scroll inside the panel | Owner's choice, adding the fixed-width truncation. Eleven never-wrapping columns overflowed the panel. A column picker hides information by default; scrolling keeps the defect, only contained. |
| DL-022-23 | Money axes in abbreviated reais; tooltips with the exact amount, formatted from the decimal on the server. (2026-10-12.) | Full amounts on the axis | Owner's choice. The charts printed the raw plotting coordinate — no currency and float formatting — because a formatter existed only for the masked state. Full amounts widen the axis and crowd the plot. Formatting the tooltip from the coordinate would put a float-derived figure in front of the user (ARCHITECTURE AR-06/AR-09), so the exact amount travels with each point as a server-formatted string. |
| DL-022-24 | The adjustment frames are approved (2026-10-12): rendered on SPEC-022-Prototype › Ajustes; source https://claude.ai/artifact/PxC7sxodnp7rrsRQwhBcLT — Dashboard, Transações, the standard form, the four Configurações tabs, and the table, panel, chart and label standards, in both themes. Every adjustment PR is measured against them, as DL-022-01 does for the prototype. | — | The owner reviewed the UI after #203–#214 and found thirteen gaps; frames remove the guessing that let screens diverge. Owner's approval of the light frames; the dark versions are the same source rendered with the approved dark tokens. Every block in a panel and the 8 px radius are part of what was approved. |
| DL-022-25 | The remaining wide tables fit by merging columns — holdings 10 → 6, Carteiras' balancing 8 → 6, the composition history long-format, rule actions in a “⋯” menu — and holdings' figures sized to what they hold: a price 13ch (R$ 9.999.999,99), a holding's value and gain 16ch (±R$ 999.999.999,99). (2026-10-13.) | Horizontal scroll inside the panel; for the composition history, a class selector or shares in % only; for the rules, Último e-mail under the state | Owner's approval of the proposal in #245. Four 19ch money columns alone take ~670 px of the ~944 px panel, so no seven-column holdings table fits. Sorting by class, sector and watch state (holdings) and by quantity and count of cotas (balancing) is dropped; the share loses no sort, since it orders as the value does. The long format fits for any number of classes and keeps every figure in reais. The rules table fits once Configurações loses its side sub-navigation (BR-022-16, #241). |
| DL-022-26 | Chart date axes read pt-BR months — “nov/25” for a daily series, “nov” for a monthly one — as drawn in the approved chart frame (DL-022-24). (2026-10-17.) | Leave it to the frame alone; full dd/mm/yyyy ticks |
Owner's choice. Every chart printed its raw key (2026-09-30, 2026-09) because no XAxis had a formatter, which BR-016-18 already forbids. The frame showed the target but no rule stated it, so no review could hold a chart to it. Full dates crowd the axis, and the tooltip already carries the exact date. Implemented in #251. |
| DL-022-27 |
The top bar carries a breadcrumb (BR-022-09 amended): destination › tab or section › task; earlier crumbs are links, the last is the current page; a page that is not a task ends at its task; hidden below md. (2026-10-18.)
|
Leave it to the frames alone; end the crumb at a detail page's own name (a wallet's, a batch's); show it on phones too | Owner's request. Every frame since the #202 prototype draws it, but no rule did, so #205 built the top bar without it and #241 could not hold Configurações to it (#241 Decision log #7). Ending at the task keeps the crumb a function of the path alone: the top bar is rendered by the layout, which would otherwise load a wallet or a batch to name it. On a phone the brand and the menu button already fill the bar's start. Implemented in #254. |
The token values approved with the prototype (DL-022-13). #203 implements them in src/app/globals.css and DESIGN.md; from then on DESIGN.md holds the living values, and this table records what the owner approved.
Brand D · Marinho: a navy on near-neutral graphite surfaces (DL-022-05, amended).
| Token | Light | Dark | Note |
|---|---|---|---|
| Brand, navigation, focus | |||
--primary |
oklch(0.4 0.12 258) |
oklch(0.78 0.08 258) |
navy |
--primary-hover |
oklch(0.34 0.1 258) |
oklch(0.84 0.065 258) |
new |
--primary-foreground |
oklch(0.99 0 0) |
oklch(0.19 0.025 258) |
|
--ring |
oklch(0.4 0.12 258) |
oklch(0.78 0.08 258) |
tracks --primary (DS-06) |
--nav-active |
oklch(0.94 0.022 258) |
oklch(0.3 0.04 258) |
new — active nav fill, never the focus ring (BR-022-33) |
--nav-active-foreground |
oklch(0.36 0.1 258) |
oklch(0.88 0.05 258) |
new |
| Surfaces — near-neutral graphite | |||
--background |
oklch(0.975 0.0012 260) |
oklch(0.17 0.0036 260) |
page |
--card |
oklch(1 0 0) |
oklch(0.215 0.0042 260) |
card layer |
--popover |
oklch(1 0 0) |
oklch(0.265 0.0048 260) |
raised layer |
--muted |
oklch(0.955 0.0018 260) |
oklch(0.245 0.0042 260) |
--secondary keeps tracking it |
--accent |
oklch(0.95 0.0018 260) |
oklch(0.275 0.0048 260) |
hover surface |
--sidebar |
oklch(0.985 0.0009 260) |
oklch(0.195 0.0039 260) |
|
| Text and lines | |||
--foreground |
oklch(0.22 0.0045 260) |
oklch(0.96 0.0012 260) |
also every *-foreground of a surface |
--muted-foreground |
oklch(0.5 0.0048 260) |
oklch(0.73 0.0045 260) |
|
--border |
oklch(0.91 0.0018 260) |
oklch(0.32 0.0042 260) |
|
--input |
oklch(0.64 0.0036 260) |
oklch(0.52 0.0045 260) |
darker than today: 3:1 field boundary (WCAG 1.4.11) |
| Gain, loss, destructive — unchanged (DL-05) | |||
--positive |
oklch(0.5 0.14 150) |
oklch(0.72 0.16 150) |
|
--negative |
oklch(0.53 0.19 25) |
oklch(0.7 0.18 25) |
|
--destructive |
oklch(0.53 0.19 25) |
oklch(0.7 0.18 25) |
|
--destructive-foreground |
oklch(0.99 0 0) |
oklch(0.17 0.0036 260) |
|
Status — text on its -surface (BR-022-31) |
|||
--success / --success-surface
|
oklch(0.46 0.12 150) / oklch(0.95 0.04 150)
|
oklch(0.78 0.14 150) / oklch(0.3 0.05 150)
|
new |
--progress / --progress-surface
|
oklch(0.45 0.15 300) / oklch(0.95 0.025 300)
|
oklch(0.85 0.085 300) / oklch(0.3 0.05 300)
|
new — violet, never the brand hue |
--warning / --warning-surface
|
oklch(0.5 0.11 65) / oklch(0.965 0.04 90)
|
oklch(0.84 0.12 85) / oklch(0.32 0.05 75)
|
new |
--danger / --danger-surface
|
oklch(0.51 0.18 25) / oklch(0.955 0.02 25)
|
oklch(0.76 0.14 25) / oklch(0.31 0.06 25)
|
new |
--neutral / --neutral-surface
|
oklch(0.46 0.0045 260) / oklch(0.94 0.0018 260)
|
oklch(0.8 0.0036 260) / oklch(0.31 0.0036 260)
|
new |
--opportunity-*, --chart-1…--chart-8
|
unchanged | unchanged | DS-10, SPEC-018 |
--shadow-raised |
0 1px 2px oklch(0.22 0.0045 260 / 0.06), 0 8px 24px oklch(0.22 0.0045 260 / 0.1) |
0 1px 2px oklch(0 0 0 / 0.3), 0 12px 32px oklch(0 0 0 / 0.45) |
new — popovers and menus |
--radius |
0.625rem |
0.625rem |
prototype value (today 0.5rem) |
--sidebar-primary, -primary-foreground, -accent, -accent-foreground, -border, -ring
|
→ primary, primary-foreground, nav-active, nav-active-foreground, border, ring
|
same | shadcn sidebar aliases |
Measured on the final sRGB, both themes: every text pair ≥ 4.5:1 (button 9.06 / 9.23:1, link on card 9.33 / 8.76:1, active nav 9.20 / 9.51:1, lowest text pair danger on danger-surface 5.50:1), --input on card and page 3.13–3.47:1. Colour-vision separation of --primary — Machado, Oliveira & Fernandes (2009) matrices at severity 1.0 in linear RGB, ΔE in OKLab — minimum over protanopia and deuteranopia and both themes: gain 0.160, loss 0.165, in-progress 0.035.