← Back to app

User Guide & Privacy Everything you need to know about using Roastfolio and how your data is protected.

Getting Started

Creating an account

  1. Click Sign Up on the login page and enter your e-mail address and a password (minimum 6 characters).
  2. Check your inbox for a verification code from Roastfolio and enter it when prompted.
  3. Choose a display name (nickname) — this is the only personal detail stored beyond your e-mail.
  4. You are now logged in. Your account and all data are tied to your e-mail address.

Password recovery: If you forget your password, click Forgot password? on the login page. A reset code will be sent to your verified e-mail address.

Demo Account: You can quickly demo the app using email roastfolio@app and password roastfolio to explore a pre-populated 5-year portfolio history with active holdings, trades, and achievements.

Creating your first wallet

After logging in, open the Wallets tab. This is your main portfolio management screen. To add a wallet:

Name wallets after the brokerage or account they represent (e.g. IKE, IKZE, XTB, Binance). Each wallet tracks one account independently.

Summary is always the first entry and is computed automatically as the aggregate of all your wallets. It is read-only — you cannot add transactions to it directly.

Dashboard & Control Room

The Dashboard provides a high-level overview of your entire portfolio. The top section features the Control Room, where you can see the aggregated value, daily returns, and performance of each individual wallet at a glance.

📊 Today's Movers & Time-Adjusted Volume (RVOL)

In addition to intraday price changes, the Today's Movers table displays a Time-Adjusted Relative Volume (RVOL %) badge for each equity holding. Rather than comparing intraday volume against 100% of a full day's average, Roastfolio dynamically scales expected volume to the current trading session progress:

Holdings

Holdings are created automatically when you record a BUY transaction. There is no separate "add holding" form. Each BUY transaction adds to (or creates) the matching position in your wallet.

The holdings table shows each position with live price data, current value, today's change in PLN and %, and allocation percentage. On mobile, holdings display as stacked cards. On desktop, they appear in a table with sortable columns.

To edit or delete a position, tap the ✏️ or 🗑️ icons on the holding row. To record a trade against an existing holding directly, use the Buy or Sell chip buttons on the holding card.

Cash holding: any holding without a ticker (named e.g. Cash or Konto) is treated as a cash position. Its value is used to calculate available cash for BUY transactions.

Closed Positions & AVCO

Wallet Management has two holdings views: Active Holdings and The Cemetery.

For each asset, Roastfolio calculates return components using an Average Cost Basis (AVCO) model:

In the Active view, a Past Realized (AVCO) badge appears when a holding has non-trivial realized history. In The Cemetery, each row shows:

The Cemetery table also includes power tools:

Summary wallet behavior: Summary remains read-only for trading, but The Cemetery is available there too. It is aggregated across all wallets by asset and shows combined AVCO returns for active and closed positions.

Recording transactions

Transactions are recorded in a slide-up panel (bottom sheet) that opens without leaving the holdings view. To open it:

Inside the transaction panel, select the type using the buttons at the top:

TypeWhat it does
BuyAdds units to an existing holding or creates a new one. Decreases cash balance.
SellRemoves units from a holding. Increases cash balance.
DepositAdds cash to the wallet without buying anything. Increases cash balance. Counts toward the monthly contribution streak.
WithdrawalRemoves cash from the wallet. Decreases cash balance. Breaks the withdrawal-free streak.

For Buy and Sell, start by searching for the asset. Two sources are supported:

Foreign currencies: Tickers natively traded in foreign currencies (e.g., BTC-USD, ETH-USD, AAPL) are automatically mapped and evaluated in their native market currency (USD, EUR, etc.) during historical recalculations. This guarantees accurate historical valuation regardless of the currency selected in your transactions.

Enter the quantity (number of units) and trade value (total cash impact in PLN). Commission and a free-text comment are optional under Advanced options. A live review summary appears before you submit.

The panel has two tabs — Trade (new transaction) and History (past transactions and daily value snapshots for the selected wallet). On mobile, swipe down from the handle at the top to dismiss the panel.

Auto-add cash: if a BUY transaction would exceed your available cash balance, you can enable Automatically add missing cash before a buy. This records a DEPOSIT for the shortfall automatically before applying the buy.

Managing existing transactions

History & Benchmarks

The History screen visualizes your portfolio over time. You can inspect the combined Summary of all wallets or switch to an individual wallet using the wallet selector. The section is split into three tabs to make the story clearer:

Across the History screen, the app also keeps the benchmark comparison logic aligned with a clean portfolio return model:

Statistics

The Statistics screen summarizes long-term performance using snapshots and transaction-adjusted return logic.

Monthly Performance Heatmap

The heatmap visualizes seasonality by showing monthly performance in a matrix (month rows × year columns):

How to read it: Use the heatmap to spot recurring strong/weak months and compare whether a pattern persists in percentage terms or only in absolute PLN.

Underwater Lakes

The Underwater Lakes module shows how long and how deep your portfolio stayed below its running high-water mark.

Two summary cards are shown next to the charts:

All-Time High (ATH) management

Roastfolio tracks the All-Time High (ATH) portfolio value for each wallet and for the overall portfolio. ATH is used on the dashboard gauge to show how close you are to your peak. By default, ATH is computed automatically from your daily value snapshots.

To view or edit ATH for a wallet, open the Wallets tab and select the wallet from the list. In the wallet overview bar you will see an All-Time High (ATH) row showing the current peak value, its date, and whether it was set automatically or manually.

Tap the ✏️ icon to expand the ATH editor:

Auto mode: click Auto (reset from history) to discard any manual override and let the system recalculate ATH from your historical daily snapshots. Auto mode is the default for all new wallets.

Manual ATH does not permanently disable automatic updates — if a new daily snapshot exceeds the stored ATH, the system will still update it automatically. Manual ATH only sets the current floor.

Summary wallet — selecting Summary in the wallet list shows and lets you edit the ATH for the aggregated total portfolio value.

Asset Analysis

The Analysis screen provides deep-dive research tools for any stock, ETF, or crypto asset. Use it to explore detailed price history, financial statements, and earnings data before making investment decisions.

Opening the Analysis screen

There are multiple ways to access the Analysis screen:

Quick tip: Cash holdings are not clickable as they have no market data.

Search and selection

At the top of the Analysis screen is a search bar where you can enter any ticker symbol or company name (e.g. AAPL, CDR.WA, Meta, BTC-USD). Results appear instantly from Yahoo Finance's global database. Holdings you already own are marked with a ✓ Owned badge.

Use arrow keys to navigate the dropdown and press Enter to select an asset. The analysis loads automatically with a smooth animated loader.

Price history chart

The main chart shows the asset's price history with the following features:

Fundamental properties

Below the chart, a grid displays key fundamental metrics fetched from Yahoo Finance:

MetricDescription
Sector & IndustryBusiness classification (e.g. Technology / Software)
Market CapTotal market capitalization (formatted as B/M/T)
P/E RatioTrailing and forward price-to-earnings ratios
Dividend YieldAnnual dividend as percentage of current price
52-Week High/LowPeak and bottom prices over the last year

All metrics display "—" when data is unavailable (common for small-cap stocks, crypto, or newly listed assets).

Cash Flow Statement

For companies with available financial data, the Analysis screen shows a detailed Cash Flow Statement covering the last 5 years. This section includes:

Cash flow data is particularly useful for evaluating a company's ability to generate cash, fund operations, and pay dividends.

Income Statement

The Income Statement section displays profit-and-loss data for the same 5-year period:

This data helps assess profitability, revenue growth, and operational efficiency over time.

Data availability: Financial statements are pulled from Yahoo Finance. Large-cap stocks typically have complete historical data. Small-cap stocks, ETFs, crypto, and international assets may have limited or missing financial data. If no data is available, the Cash Flow and Income Statement sections will be hidden automatically.

Best practices for analysis

Coping Diary (Investment Hypothesis Notebook)

The Coping Diary is a dedicated behavioral layer for documenting your thesis and auditing it over time.

What you can do

Hypothesis Checkpoint Board

The Focus Sheet includes a checkpoint board with status states:

Audit reminders

When a HYPOTHESIS_AUDIT reminder appears, clicking it opens a guided Fact-Check Your Bias confirmation flow in Coping Diary.

Monthly Recap & Audit

Roastfolio automatically calculates a comprehensive monthly audit summarizing your performance, comparing it against benchmarks, and highlighting key portfolio drivers.

Automated Email Reports

At the close of each month, if enabled in your settings, you will receive an elegant email summarizing your month's progress. Features include:

Interactive Audit View

Inside the app, you can view past monthly audits under the History screen. Selecting a month opens an immersive, full-screen interactive view that mirrors your email report but includes deeper breakdowns and hover interactions for daily data.

Live Month-to-Date (MTD)

In addition to historical audits, the History screen features a Live Month-to-Date report. This report acts exactly like a monthly wrapped audit, but it is generated dynamically using your latest live transactions. It clearly marks itself with a "Live Month-to-Date" badge, keeping you updated on the current month's trajectory in real-time.

Pro Tip:

Holdings in your email reports and UI are intelligently cleaned for better readability (e.g., stripping Polish "S.A." suffixes), focusing on the holding's clean name rather than raw ticker symbols whenever possible.

Privacy & Security

How authentication works

Roastfolio uses AWS Cognito — Amazon's managed identity service — for all authentication. Your password is never stored or even seen by the application code. The login flow uses the industry-standard SRP (Secure Remote Password) protocol: only a cryptographic proof is exchanged, not the plaintext password.

After login, Cognito issues a signed JWT token (JSON Web Token). Every API call includes this token in the Authorization header. The backend Lambda function validates the token's signature against Cognito's public key before processing any request. If the token is invalid, expired, or missing, the request is rejected with HTTP 401.

Token expiry: Access tokens expire after 24 hours. Refresh tokens expire after 30 days. When your session expires you will be redirected to the login page.

Your data — strict per-user isolation

Every item stored in the database (portfolios, holdings, transactions, snapshots) uses your Cognito user ID (sub) as the primary partition key. This is a unique, non-guessable UUID assigned at signup.

The backend code enforces that your token's user ID matches the requested data's partition key on every read and write. It is technically impossible for one logged-in user to access another user's data through the application's API — even if they know the other user's e-mail or ID.

Infrastructure security

🔒
HTTPS everywhere
All traffic between your browser and the app is encrypted with TLS 1.2+. CloudFront enforces HTTPS and redirects plain HTTP requests.
🌐
CloudFront CDN
Static files are served through CloudFront. The underlying S3 bucket is private — it cannot be accessed directly, only via CloudFront.
🗄️
Encrypted at rest
All DynamoDB tables are encrypted at rest using AWS-managed keys (AES-256). The S3 bucket uses server-side encryption.
♻️
Point-in-time recovery
Every DynamoDB table has PITR enabled — data can be restored to any second in the last 35 days in case of accidental deletion or corruption.
🔑
Least-privilege IAM
Each Lambda function has an IAM role granting only the exact DynamoDB actions it needs (e.g. the snapshot function cannot modify user profiles).
🚫
No public S3 access
The S3 bucket has all public-access settings blocked. A bucket policy allows only the CloudFront distribution (via OAC) to read objects.

Developer access policy

As the developer and sole operator of Roastfolio, I have administrative access to the AWS account that hosts your data. This is technically unavoidable for a solo-operated SaaS. Here is how I limit and account for that access:

What I have access toHow it is controlled
DynamoDB tables (read/write) IAM — separate dev and prod accounts; no routine prod access
CloudWatch logs (Lambda logs) Logs contain request metadata, not portfolio values
AWS CloudTrail All API calls to prod DynamoDB are audit-logged with timestamp and identity
Your password Never stored anywhere — handled entirely by AWS Cognito
Your JWT tokens Never logged or stored — they expire and are validated in-memory only

Your data is protected by AWS IAM access controls and all access to the production database is audit-logged via AWS CloudTrail. I do not have routine access to production data. Any access I make for support or maintenance purposes is recorded in the audit log and I commit to not reading, copying, or using your portfolio data for any purpose other than operating the service.

— Michał Bardadyn, developer of Roastfolio

Important transparency note: Roastfolio is not a zero-knowledge application. Because portfolio calculations (live prices, gain/loss, benchmarks) happen on the server, the Lambda function processes your holdings data in plaintext. If you require cryptographic guarantees that no one — including the operator — can ever read your data, a server-side architecture like this cannot provide that. The controls described above are operational and policy-based, not mathematical.

Data encryption

All data is encrypted at rest (DynamoDB server-side encryption, S3 SSE) and in transit (TLS via CloudFront and API Gateway). The encryption keys are AWS-managed (AES-256). As the account owner I have administrative access to these keys, which is consistent with the operational access model described above.

Audit logging

AWS CloudTrail is enabled on the AWS account and records every API call made to DynamoDB, Lambda, and S3, including the identity making the call, the timestamp, and the source IP. These logs are stored in S3 and cannot be altered retroactively without detection. In practice, this means that any access to your data — including by the developer — leaves an immutable record.

Frequently Asked Questions

Can the developer see my portfolio data?

Technically yes — as the AWS account administrator I can query the DynamoDB tables directly. Practically: I do not do this in the normal course of operating the service, and any time I do (e.g. to investigate a bug you reported) it is recorded in CloudTrail. I have committed above not to read or use your data beyond what is necessary to run the service.

If this level of trust is not sufficient for you, I recommend not storing sensitive financial data in any cloud-hosted service without client-side encryption.

How is my data backed up?

All DynamoDB tables have Point-in-Time Recovery (PITR) enabled. This means AWS continuously backs up your data and it can be restored to any point within the last 35 days. In the event of accidental data loss I can restore a table backup to recover your portfolios and transactions.

How do I delete my account?

Go to Settings → Account → Delete account. This will permanently delete your Cognito account, all your portfolios, holdings, transactions, and snapshots from DynamoDB. The deletion is irreversible. Because DynamoDB PITR retains backups for up to 35 days after deletion, residual copies may exist in backups during that window and are then permanently purged.

🏆 Milestones & Achievements

What is this?

Roastfolio tracks your investing habits over time and rewards consistency with streaks, milestones, and badges. The goal is to make the boring middle of long-term investing feel like it's going somewhere — because it is.

Everything is calculated automatically from your transaction history. There is nothing to opt into: the moment you make your first deposit, the system starts tracking. The only things that require manual setup are the monthly deposit goal and retirement plan, which unlock additional streak and milestone types.

Roastfolio's achievement philosophy: badges reward real financial behavior — depositing money, staying invested, avoiding withdrawals — not artificial engagement like logging in every day or watching animations. The tone is sarcastic but the mechanic is sound.

Where to find it

Achievements surface in three places:

Streaks

A streak is a consecutive run of a specific behavior, measured in months or trading days. Streaks reset if you miss a period — but your personal best is always saved and visible in the achievements screen as a "former streak" record.

Streak What it measures Unit Resets when Requires setup?
Deposit streak Consecutive calendar months with at least one DEPOSIT transaction. Buy orders without a new cash deposit do not count. Months Any month passes with no deposit recorded (3-day grace into the next month) No
Active days Total count of distinct calendar days on which any transaction (Buy, Sell, Deposit, Dividend) was recorded. This is a proxy for portfolio engagement — more active portfolio management accumulates faster. Days Does not reset — it is a cumulative total, not a consecutive run No
Withdrawal-free streak Consecutive calendar months without any WITHDRAWAL transaction. Sell orders are not counted — reinvesting proceeds is a valid decision. Months Any WITHDRAWAL transaction is recorded No
Goal streak Consecutive months where total deposits meet or exceed your self-set monthly deposit goal. Changing your goal mid-streak does not reset the counter. Months Any month where deposits fall below the goal Yes — set monthly goal
Green months Consecutive calendar months where your portfolio's market performance is positive — calculated before any new deposits, so it isolates market return from your contributions. Months Any month ends with a negative market return No
Beat benchmark [planned] Consecutive months where your portfolio's total return exceeds your chosen benchmark (WIG20, MSCI World, S&P 500). Requires benchmark data integration — not yet available in the current build. Months Any month your return trails the benchmark Yes — enable benchmark

Why only DEPOSIT for the contribution streak, not BUY? Buying with cash that's already in your portfolio is not new capital entering the system. The streak is designed to reward the habit of adding fresh money each month. Moving existing cash from one holding to another doesn't count.

Milestones

Milestones are one-time achievements. When you cross one, a badge unlocks and a roast fires. They never expire and can only be earned once each. The Achievements screen shows four separate milestone timelines — Portfolio value, Investor journey, Monthly deposit best, and FIRE progress (if a retirement plan is configured). Each timeline shows past milestones with the date reached, the next target with a live progress bar, and future milestones muted below.

Portfolio value

Triggered when your total portfolio value (all portfolios combined) crosses a threshold for the first time. The badge is awarded on first crossing only — if the market dips below and recovers, no second badge. XP from each threshold is awarded cumulatively: a 150 000 PLN portfolio earns XP for all thresholds below it.

Value (PLN)Roastfolio says…
1 000"It begins. Technically you're an investor now."
10 000"Five figures. A threshold that matters."
50 000"Halfway to six figures. The market will try to undo this. Don't let it."
100 000"Six figures. This is the number that changes behavior. Guard it."
250 000"A quarter million. At this point your money has a support group."
500 000"Half a million. The math is doing most of the work now."
1 000 000"One million. You either DCA'd for 30 years or got very lucky."
2 000 000"Two million. The returns alone are someone's annual salary."
5 000 000"Five million. The portfolio manages you more than you manage it."

Investor journey (from first investment date)

Time-based milestones counted from the date of your first ever recorded transaction — not account creation. The clock starts when money moves.

Since first investmentMilestone
3 months"Still here. Initial excitement survived."
6 months"Half a year. One market wobble behind you, probably."
1 year"One full year as an investor. All four seasons of market behavior."
2 years"The 'long term' is no longer hypothetical."
5 years"You're a different investor than when you started."
10 years"A decade. Compounding has had time to become your co-pilot."

Monthly deposit personal best

Unlocked the first time you deposit above a threshold in a single calendar month — rewards your biggest months, not just consistency.

Thresholds: 1 000 / 2 500 / 5 000 / 10 000 / 25 000 / 50 000 / 100 000 PLN in one month.

Retirement progress

Triggered at 10 / 25 / 50 / 75 / 90 / 100% of your FIRE target. Only active if you have a retirement plan configured. See Setup & configuration for details.

Badges & tiers

Every milestone and streak achievement unlocks a badge. Badges come in five tiers — rarity reflects how long or how difficult the achievement is to earn, not whether it's valuable. A Seed badge for your first deposit matters.

TierWhat it representsVisual
Seed Participation and first steps. Nearly everyone earns these early. Gray border, muted glow
Bronze Early consistency — showing up for a few months, hitting initial thresholds. Amber border
Silver Sustained effort — a full year of something, meaningful portfolio thresholds. Steel blue border
Gold Genuine milestones — six-figure portfolio, multi-year streaks, survival through bad markets. Yellow border, slow pulse glow
Diamond Rare, long-term, legendary. Five-year streaks, seven-figure portfolio, full trading year of check-ins. Cyan border, continuous shimmer pulse

In the achievements screen, locked badges appear as silhouettes at reduced opacity. Tapping a locked badge shows exactly what it requires and how close you are. Nothing is hidden — you always know what's next.

Retroactive awards: When the achievements system launches for your account, all badges you've already earned through past transactions are awarded immediately and silently. You'll see a "New" indicator in the achievements drawer and a one-time message: "We went through your history. Turns out you've been building this longer than you realized."

XP & Level Calculation

XP (experience points) are derived entirely from real transaction and portfolio snapshot data. There are no artificial engagement loops — you earn XP for financially meaningful actions only. The engine (xp-engine.js) recomputes automatically every time transaction history or portfolio prices are refreshed.

No manual entry. XP is never entered by hand. If a transaction is deleted, the XP it generated disappears on the next recalculation. The number is always consistent with your actual history.

Storage decision — why XP is not stored in the database. XP, levels, badges, milestones, and streaks are computed client-side on every load from transaction history already fetched from the API. Storing computed values in DynamoDB would create a stale-data sync problem every time calculation rules change. Persisted between sessions: streak personal bests (localStorage — they only ever increase), monthly deposit goal (localStorage key xpe_deposit_goal), and FIRE target (localStorage key xpe_fire_target, refreshed from the retirement plans API). Because computation is deterministic and fast (<10ms), no server-side caching is needed. Existing and new users get a full retroactive recalculation from their complete transaction history automatically on every load.

XP rule table

CategoryActionXP awarded
DepositsPer deposit event+15
Amount ≥ 500 PLN+5 bonus
Amount ≥ 1 000 PLN+15 bonus
Amount ≥ 5 000 PLN+30 bonus
Amount ≥ 10 000 PLN+60 bonus
ConsistencyPer calendar month with ≥1 deposit+20
GoalPer month with total deposits ≥ 1 000 PLN+10 bonus
IncomePer dividend received+15
TradingFirst sell transaction+20
Each additional sell+5
Portfolio milestonesPortfolio ≥ 1 000 PLN+50
Portfolio ≥ 10 000 PLN+100
Portfolio ≥ 50 000 PLN+200
Portfolio ≥ 100 000 PLN+400
Portfolio ≥ 250 000 PLN+600
Portfolio ≥ 500 000 PLN+1 000
Diversification3+ unique holdings bought+30
5+ unique holdings bought+50
10+ unique holdings bought+80
RetirementRetirement plan configured+50
BadgesPer badge unlocked+50

Deposit bonuses are tiered, not cumulative. A 1 200 PLN deposit earns base (+15) plus the ≥1 000 PLN tier (+15) — the +5 (≥500) tier is superseded. Diversification bonuses are cumulative: reaching 10 holdings awards all three tiers (+30 + +50 + +80 = +160 total). Portfolio milestone bonuses are also cumulative — a 150 000 PLN portfolio earns +50 + +100 + +200 + +400 = 750 XP for all four crossed thresholds.

Level thresholds

Level nameXP required (total)
Seed0
Observer100
Participant250
Saver500
Contributor1 000
Operator2 500
Veteran5 000
Institution10 000

Streak calculation

Streaks are computed from transaction history every time data refreshes. Each streak also persists its personal best in localStorage so the all-time high is never lost if a streak resets.

StreakHow it’s calculated
Deposit streak Consecutive calendar months (YYYY-MM) ending at the most recent month that contain at least one deposit. A month with zero deposits breaks the streak.
Active days Total count of distinct calendar days on which any transaction (buy, sell, deposit, dividend) occurred. Used as a proxy for engagement frequency.
Withdrawal-free Number of calendar months between the date after the last withdrawal and today. If no withdrawal has ever been recorded, the streak counts from the first deposit date.
Goal streak Consecutive calendar months (most recent first) where the sum of all deposits equals or exceeds the monthly goal (default: 1 000 PLN across all portfolios).
Green months Consecutive calendar months where the net portfolio return — (end value − start value) − (new capital deposited) — is positive. Requires portfolio snapshot history.

Badge derivation

Each badge is evaluated against a specific condition derived from real data. Below is the full derivation logic for every badge in the system.

BadgeUnlocks when…
Showing UpAt least one deposit exists in transaction history
ReliableDeposit months total ≥ 3 (deposit streak or cumulative)
Eyes OpenDistinct transaction-active days ≥ 7
Hands OffWithdrawal-free streak ≥ 6 months and no withdrawal ever recorded
Four DigitsHistorical peak portfolio value ≥ 1 000 PLN
Getting SeriousHistorical peak portfolio value ≥ 10 000 PLN
Not One BasketUnique tickers bought ≥ 3
Actually DiversifiedUnique tickers bought ≥ 5
Baptism by FirePortfolio saw a ≥10% drawdown from running peak and no withdrawal was ever recorded
FIRE CuriousAt least one retirement plan saved (checked via RetirementPlansClient, cached in localStorage)
Red Day SurvivorPortfolio snapshot history shows a ≥10% drawdown, or snapshot history exists (proxy: you have seen red days)
Sold SomethingAt least one Sell transaction exists
CommittedGoal streak ≥ 3 consecutive months
The Long GameDeposit months ≥ 12
Weekly HabitDistinct active days ≥ 90
UntouchedWithdrawal-free streak ≥ 36 months
On TrackGoal streak ≥ 12 months
Six FiguresHistorical peak portfolio value ≥ 100 000 PLN
Held the LinePortfolio saw a ≥20% drawdown and no withdrawal ever recorded
World CitizenTransactions span ≥3 country/asset-class proxies (Polish .WA tickers, foreign tickers, crypto)
Tax EfficientTransactions exist in both an IKE and an IKZE wallet
InstitutionalizedDeposit months ≥ 36
Comma ClubHistorical peak portfolio value ≥ 1 000 000 PLN

Data required: Most badges only need transaction history. Green months, drawdown badges (Baptism by Fire, Held the Line, Red Day Survivor), and portfolio milestone badges additionally require portfolio snapshot data — available once the app has loaded at least one price update.

Most streaks and milestones require no setup — they're computed automatically. Two features need configuration to unlock their respective achievements:

🎯
Monthly deposit goal
Call XPEngine.setDepositGoal(amount) in the browser console, or set localStorage.xpe_deposit_goal

Set a target amount (in PLN) you want to deposit each month. This activates the Goal streak counter and the monthly goal bonus XP. The goal applies to your total deposits across all portfolios in a calendar month — not per individual portfolio. Default is 1 000 PLN.

Changing your goal at any time does not reset your streak. The system records that you had a goal and hit it; what the goal was is secondary to whether you met it.

🔥
Retirement plan (FIRE target)
Retirement → Configure plan

Set a target portfolio value you want to reach before retirement. This activates the retirement progress milestones (10% / 25% / 50% / 75% / 90% / 100%) and the corresponding badges. The FIRE progress is measured as: total current value of all portfolios divided by your retirement target.

IKE and IKZE utilization tracking is independent of your FIRE target — it looks at deposits into accounts tagged as IKE/IKZE and compares them to the annual statutory limits (updated each year).

Multiple retirement plans — how progress is calculated

Roastfolio allows you to create more than one retirement plan (e.g., a conservative scenario and an aggressive scenario with different target values). Here is how the achievements system handles that:

Design decision

One plan drives the achievement badges at a time. If you have multiple retirement plans, you designate one as your primary plan for achievements. Only this plan contributes to the FIRE progress milestones and retirement badges.

If no primary is designated, the system defaults to the most recently modified plan.

ScenarioHow it's handled
Single retirement plan Used automatically. No action needed.
Multiple plans, one marked primary The primary plan drives all retirement badges and the FIRE progress bar.
Multiple plans, none marked primary The most recently modified plan is used. A soft prompt suggests marking one as primary.
IKE / IKZE utilization badges Always calculated from actual deposits into IKE- and IKZE-tagged accounts — independent of which retirement plan is primary. The annual limit comparison is against the statutory maximum regardless of your personal FIRE target.

The FIRE progress percentage is always calculated as:

/* Total value of ALL portfolios ÷ primary retirement plan target */
FIRE % = (sum of all portfolio values) / (primary plan target) × 100

This means your full wealth counts toward the goal, not just the assets in "retirement-tagged" portfolios. Rationale: when you retire, all your money is relevant — artificially restricting the calculation to specific portfolios would understate your actual progress.

Monthly deposit goal — similar rule applies: The goal streak measures total deposits across all portfolios in a calendar month. If you set a goal of 1 000 PLN/month and deposit 400 PLN into IKE and 700 PLN into XTB, the streak counts it as 1 100 PLN — goal met. The system doesn't care which portfolio received the money.

🏷️ About & Release Numbering

Release Numbering Standard

roastfolio is built and maintained by TOMINEX. To provide full transparency and predictable updates, our releases follow a three-tier semantic versioning structure:

Current Active Release: v14.1.3 — Powered by TOMINEX — View Interactive Release Summary & Changelog →

Every release follows the MAJOR.MINOR.SERVICE pattern (e.g. 11.5.0), with each component signaling a distinct scope of changes:

Tier Type Classification & Trigger
MAJOR (e.g. 12.0.0) New Features Brand-new user-facing features, tools, screens, or asset classes added to Roastfolio (such as Coping Diary, Retirement Planner, Monthly Recaps, or new analytics modules).
MINOR (e.g. 11.5.0) Changes to Existing Features Modifications, redesigns, workflow improvements, or calculation adjustments to features that already exist in the app (e.g. Editorial Bento layout upgrades, benchmark selector refinements, metrics recalculation UX).
SERVICE (e.g. 11.2.2) Bug Fixes & Maintenance Bug fixes, regression repairs, performance improvements, security patches, and reliability hotfixes.

Full architectural details and developer release workflows are documented in docs/RELEASE_NUMBERING.md in the repository. The active release number is always visible in the application footer.

🎨 Design System

This section documents the design decisions that define Roastfolio's visual identity. It is updated whenever a significant UI change is made so the reasoning behind each decision is never lost.

Audience: This section is for ADVANCED users and contributors who want to understand why the app looks and behaves the way it does — not just what it looks like.

Design Philosophy

Roastfolio sits at the intersection of premium fintech and internet humor. Every design decision asks two questions: does this feel like it belongs next to Revolut? and does this feel like it was made by someone who lost money on CDR and laughed about it?

The design language is dark-native (not dark-mode as an afterthought), card-first, and number-obsessed — financial data is the hero, personality is the seasoning.

The tone lives in copy, not chrome. Roastfolio's sarcasm comes from error messages, milestone notifications, and empty states. The UI itself is as premium as Revolut. Users need to trust the app with financial data — humor and visual roughness don't mix well in fintech.

Design System & Use Cases Specification

Roastfolio's components are organized by the core user journeys they support. The system uses a strict set of CSS variables and class structures designed for mobile-first interaction (44px touch targets minimum) with 16px corner radii for large cards and 10px for standard elements.

Use Cases: All components map to specific user workflows. If a component does not fit one of these flows, its inclusion must be re-evaluated.

1. As a user, I want to review my today return and compare it to the benchmark

This is the primary engagement loop. Users want to quickly check how much money they made (or lost) today, relative to the market.

  • Glassmorphic Header Cards: Used at the very top of the Dashboard. These cards (using .glass-card or .hero-stat) display the window.PORTFOLIO_TOTAL_VALUE and Daily Change metrics prominently. The text uses var(--green) or var(--red) to instantly convey direction.
  • Benchmark Carousel: A horizontal scrolling list of mini-cards (e.g. S&P 500, WIG) using .bm-mobile-only and .bm-mobile-list for quick swipeable comparison on mobile. Desktop uses a dedicated grid.
  • Portfolio History Chart (The Journey): An interactive Chart.js canvas (.chart-container) with tension=0.15 lines. Hover states highlight the exact day's return compared to the benchmark.

2. As a user, I want to add a transaction to my wallet

Users need to securely and accurately log their trades. This flow prioritizes clear inputs and immediate visual validation.

  • Bottom Sheets (Mobile) / Modals (Desktop): Uses .bottom-sheet with a drag handle (.drag-handle) on mobile for a native iOS feel. For desktop, it centers as a modal dialog. Contains the transaction form.
  • Input Fields & Toggle Buttons: Standardized inputs with var(--surface2) backgrounds and 10px borders. Type toggles (BUY/SELL/DEPOSIT) use .wig-type-btn pill groups to easily switch modes.
  • Toast Notifications (Snackbar): Upon successful entry, a non-blocking toast (.snackbar) appears to confirm the transaction was recorded without disrupting the flow.

3. As a user, I want to see when I made transactions and how big the turnover was

Users analyzing their trading behavior need to see aggregate volume and chronological lists of trades.

  • Monthly Audit (History Screen): Employs .monthly-audit-shell and .ma-card structures to group data into logical blocks.
  • Movers / Turnover Table: A responsive data table (.holdings-table) with alternating row highlights. On mobile, it collapses into a two-column layout (.two-col-mobile) where each row becomes a self-contained card for readability.
  • Bar Charts (Turnover/Deposits): Uses Chart.js with solid bars for positive inflows and distinct colors for outflows, allowing quick visual scanning of high-activity periods.

4. As a user, I want to analyze my asset allocation and risks

Advanced users need to see how their portfolio is distributed across currencies, sectors, and individual assets.

  • Doughnut Charts: Used in the Analysis tab for asset and currency allocation. Interactive segments with custom tooltips provide exact percentages.
  • Heatmaps: The .heatmap-cell components visualize monthly returns across years. Cells scale their opacity based on the magnitude of the return (using var(--green) and var(--red) scales), offering instant pattern recognition.
  • Underwater Lakes (Drawdowns): Visualizes the depth and duration of portfolio drawdowns using distinct visual blocks in the Statistics view to indicate recovery periods.

5. As a user, I want to review my long-term gamification and achievements

Encouraging long-term investing behavior through gamified XP and badges.

  • Level & XP Progress Bars: Employs a gradient progress track (.reading-progress-bar style) and prominent tier badges (e.g. Bronze, Silver, Gold).
  • Achievement Grid: Uses .security-grid layout to display unlocked milestones (e.g. 1 Year Streak, 100k PLN invested) with locked achievements rendered with lower opacity.

Core CSS Tokens Specification

All UI components in Roastfolio MUST rely on these core CSS tokens for consistency, avoiding hardcoded values.

var(--bg)
Dark: #0f1117 / Light: #eaf6ff
The absolute lowest layer. Full-screen backgrounds.
var(--surface)
Dark: #1a1d27 / Light: rgba(255, 255, 255, 0.94)
The primary card background. Elements sitting directly on the background.
var(--surface2)
Dark: #22263a / Light: rgba(226, 246, 255, 0.92)
Elevated surface. Used for inputs, nested cards, and hover states.
var(--accent)
#4a9fd4
Primary brand color. Links, primary buttons, active states.
var(--green)
#34c97a
Semantic success. Positive returns, deposits, checkmarks.
var(--red)
#f05656
Semantic danger. Negative returns, withdrawals, errors.

roastfolio v14.1.3 · Powered by TOMINEX · Release Summary · © 2026 TOMINEX. All rights reserved.