v0.22.0 — One rating for everyone (categories removed)
Changed
- No more S1/S2/S3 categories. Every driver now shares one ladder. There's no category to pick at sign-up, no category badge, and no "request a category change" — your number speaks for itself. Everyone starts from the same rating (1350 ELO), and your results move you up or down from there.
- Races can still count differently. Organizers can still make some races matter more than others (e.g. a top final worth more rating than a lower one) — that per-race weighting is unchanged. What's gone is the old idea of bucketing drivers into skill classes.
- Your "rank" is now your tier. Where a category badge used to be, you'll see your rating tier (Rookie → Profesional) — worked out automatically from where your ELO sits versus everyone else. Nothing to apply for; it updates itself as you race.
- Standings tabs still work. The S1/S2/S3-looking tabs on championship and meeting standings actually group races (Heats, Finals, etc.), so they're unchanged.
Behind the scenes
- The automatic "AI evaluation" that used to reset your rating around your 10th race has been retired — ratings are now purely your results, fully reproducible and auditable. All existing ratings were recomputed from race history against the single starting value.
Unreleased — UX refinement
See what's new, in the app
- There's now a "Novedades" page, linked from the footer. It lists everything on this page — new features, improvements and fixes — with a search box so you can find a specific change quickly.
Download the championship standings as a PDF
- New "Exportar clasificación (PDF)" button on the championship Clasificación tab. You get the same clean, printable sheet as the meeting results export — RWR letterhead, gold/silver/bronze top three — but for the whole season.
- One column per meeting, so you can see where each driver's points came from at a glance: the points scored, the position they finished the meeting in, and any bonus-event award. A key under the table tells you which meeting M1, M2, M3… was, with its date.
- Dropped meetings are shown, not hidden. If your championship discards each driver's worst rounds, those appear in brackets and greyed out — so anyone reading the sheet can check the maths.
- If you have a category selected, the PDF exports that category's standings; the file is named after it. The sheet comes out in whatever language the site is set to.
A tidier championship page
- The header got a clean-up. The logo, status and club now share one line instead of stacking, the start/end dates, circuits and driver count sit in proper cards, and the background banner no longer washes out the description text.
- Dates read properly in Spanish. They were showing as
3/1/2026; now they read 1 mar 2026. The status badge and the circuit list are translated too.
- You can get back to the combined standings. Picking a category used to be one-way — there's now an "All" button next to the category chips.
- On a phone, the "Create meeting" button says what it does instead of showing a bare
+.
A stray "0" on the standings tab
- Championships that don't drop any meetings were showing a lone 0 floating above the standings table. Gone.
Prices and costs accept commas now
- Typing 12,50 works. Money fields used to quietly empty themselves when you typed a comma instead of a dot — so a price you thought you had entered simply vanished. The same happened if you pasted an amount copied from the app itself, like 1.234,56. Both work now, as does 45.50 if you prefer dots.
You get a warning before results are recalculated
- Changing the points on a meeting that already has results now asks first. It tells you exactly how many results would change, in which races, with examples — "Sprint 1 · Alice: 50 → 35" — so you can see the effect before agreeing. Cancel and nothing is saved at all.
- This matters most on older meetings where the points were adjusted after results went in: previously, editing something unrelated like a start time could quietly restate a finished meeting's standings.
Points are consistent everywhere now
- One set of rules. Points were worked out in four different places — when you upload results, on the standings, on the race page, and when you edit a meeting — and they did not always agree. They now all use the same calculation: points for your finishing position, plus a pole bonus, plus a fastest-lap bonus, with a DNF scoring nothing.
- Editing an older meeting no longer changes its results. On meetings set up before the pole and fastest-lap switches existed, opening the meeting and saving any small change could quietly remove those bonus points from finished races. It now reads what the meeting actually awards and keeps it.
Fixes
- The running order comes out right. The timetable was listing every race of group A, then every race of group B, instead of round by round — R1A, R1B, R1C, then R2A, R2B, R2C. It happened whenever you added groups after starting the form, which is most of the time.
- Uploading rules can no longer lose your meeting. If the PDF failed to upload, the whole meeting you had just built was thrown away. Now the meeting is created and you are told to attach the rules from the edit screen.
- Rules PDFs upload again. A permissions setting on our side was blocking them.
Fixes
- Creating a meeting is much faster. Saving used to sit on "Saving" for several seconds on bigger meetings, because every race was written to the database one after another. They now go in one go. If something fails, you no longer end up with a half-created meeting either.
- Money fields handle decimals properly. Typing or pasting an amount with a comma — 12,50 — or a grouped figure like 1.234,56 now reads as the number you meant instead of quietly becoming something else. There is also a sensible upper limit, so a slipped keypress can't turn an entry fee into 115 billion.
Fixes to the meeting form
-
Switching from EUR to USD now actually changes what you see. The change was being saved on the meeting, but the Finance tab kept showing the old symbol because it held its own stale copy. The currency you pick beside the entry price is now the one that counts everywhere.
-
Meetings with no currency set show euros. Older meetings created before the currency field existed no longer show a bare code.
-
Choosing a currency actually sticks now. If your meeting had no entry price — a free club day, say — the currency you picked was thrown away when you saved. It's kept regardless now, which matters because the Finance tab uses it for training fees and costs too.
-
Dropdowns look like dropdowns again. Seven of them across the create and edit forms had lost their little arrow, so they read as plain boxes you might not realise you could click. The currency box was also stretching to the full width of the row.
-
The toggles all match. The cascade-ELO switch was a different size and sat on the opposite side from the points switches right above it. Everything is one style now.
Las etapas especiales, explicadas
- Ahora la guía explica qué es esa etiqueta verde. Si un meeting incluye una etapa especial que no es una carrera propia (por ejemplo un "Stage2" dentro de la final), sus puntos cuentan para la clasificación del meeting como los de cualquier carrera y pueden decidir quién gana el día: 168 en pista + 5 de etapa = 173, por delante de quien hizo 171. Si alguien te adelanta con menos puntos de carrera, la etiqueta verde es la explicación.
- El comportamiento no cambia — sigue siendo el de siempre. Lo que cambia es que ahora está escrito, y protegido por tests para que no se altere sin querer.
A proper guide, at /guide
- Everything the platform does, written down. A new Guía section (the book icon in the top bar, or the link in the footer) with 46 pages split by who you are: one track for pilotos, one for organizadores, plus shared first steps and a reference section.
- Pick who you are, and the guide changes. A centred Todo / Pilotos / Organizadores switch at the top. Choose Organizadores and the driver half disappears from the sidebar, the index and the search — you only see what applies to you. The count on each tab tells you up front how many pages you are setting aside, and your choice is remembered.
- For drivers: how to find and enter a meeting, what every profile field means and why the weight one matters, reading the timetable and your kart on race day, booking training and how the waitlist works, how to read results and how ties are broken, and a full explanation of why your ELO moves the way it does — including why winning does not always gain much.
- For organizers: the whole path from creating your club to publishing standings. The 7-step meeting wizard gets a page per step, listing every field, what values it accepts, what it defaults to and what it changes downstream. Plus the kart draw, uploading and importing results, cascading finals, and a "when something goes wrong" page for fixing a bad result or a bad draw.
- Cuando algo no es cosa tuya, lo dice. Reclamaciones de ghost, altas de circuitos y perfiles duplicados se resuelven desde la administración del sitio: la guía te dice a quién escribir y con qué datos, en vez de dejarte buscando un botón que no existe.
- Race day, properly documented. The Manage tab and the results editor now have pages of their own: how to add a driver who was not in the draw, how to remove one who did not race, and how to replace a no-show with a reserve. And the thing that stops people fixing mistakes: re-saving a race undoes the old ELO before applying the new one, so correcting a result twice does not count it twice.
- Explained, not just pointed at. The deep pages carry worked examples with real numbers: what the same race does to a 1350-rated driver and a 1700-rated one, why finishing mid-pack can cost you rating, four real meeting formats built out group by group, three points curves and what each does to a championship, a tie-break resolved step by step, and the kart-pool arithmetic behind "couldn't avoid repeating karts".
- Every screen is shown, not described. 21 screenshots and 6 short videos, all captured from the live app: the meeting page, the timetable, the kart draw with its controls open, every step of the create-meeting wizard with a real meeting filled in, the results importer, the rankings, the garage.
- The videos are captioned and silent. Registering on a phone, finding your kart on race day, booking a training slot, the seven wizard steps end to end, generating and validating a draw, and uploading results. They loop, they need no sound, and the captions are on screen.
- Reference tables for race types, ELO weights, point systems, every status badge, and who is allowed to do what.
- In both languages. The guide follows the same ES/EN toggle as the rest of the app — there is no separate English site to fall out of date.
- Search it with ⌘K. Type anywhere in the guide and jump straight to the page you want; it matches on titles, headings and field names in either language.
- "Take the tour" actually takes you there now. Launching a tour from the guide (or from the help menu on an unrelated page) used to activate it without moving, so the overlay described the home page while you were still looking at a documentation article, and the organizer tour highlighted form fields that were not on screen. Both now navigate first — the organizer tour opens the create-meeting form — and only start once you have arrived.
- Release notes moved to the footer. The top bar now carries the guide; "what changed this week" is a link at the bottom of the page, where it belongs. /docs is unchanged — that is still these patch notes.
Copying a previous meeting is much easier to use
- The list is grouped by organization now — meetings used to appear in one long undifferentiated run, so if you organize for more than one club you couldn't tell whose was whose. Each organization gets its own heading with a count, and within it your most recent meetings come first, each showing its date, track and number of races.
- Search it. Once you have a handful of past meetings, a search box appears — type any part of the meeting name, the organization or the circuit and the list narrows instantly.
Fairer ratings when you run tiered finals
- The last driver in Final A no longer loses rating to the winner of Final B. If your finals are tiers (Final A, Final B, Final C) rather than parallel groups, rating them separately was unfair: winning the B final beat a weaker field but still counted as a win, while finishing last in A counted as a loss — even though the A driver placed higher overall. Turn on "Also rate ELO across the whole cascade" (next to cascading-finals scoring) and all the finals are rated as one grid, in the cascade's real order.
- You see exactly what changes before anything happens. From the meeting's Manage tab, the panel shows every driver's rating side by side — what they got rating the finals separately, what they'd get combined, and the difference — and only writes when you confirm. It waits until every final has results, and running it twice is harmless: it recalculates rather than stacking.
Todo en español
- El formulario de creación de meetings está ahora completamente traducido. Los siete pasos, el resumen lateral, las finanzas, el ELO en cascada, la ayuda y todos los mensajes están en español y en inglés — cambia el idioma desde la cabecera y todo el formulario cambia contigo.
- Usamos el vocabulario de siempre: meeting, heat, superheat, final. El formulario traducía meeting como "prueba" y heat como "serie" o "manga" — palabras que no son las que usa nadie en el paddock, y que además no coincidían con lo que ya pone la propia página del meeting. Ahora el formulario dice exactamente lo mismo que el resto de la app. ("Ronda" sí se mantiene, porque es justo lo que es: una ronda de carreras.)
- Los días del horario también están traducidos. Las pestañas y los selectores del horario ponían "Day 1 · Sat 10/10" aunque tuvieras la app en español; ahora ponen "Día 1 · sáb 10/10".
- The whole meeting form is now available in Spanish as well as English — every step, the summary panel, finances, cascade ELO and the help screens. Switch language from the header and the form follows.
New meeting options
- Decide how your meeting is won. Two choices, right at the top of the Points step. Either add up the points across the rounds you pick, or let the final decide — whoever wins the top final wins the meeting, whatever the points say. With tiered finals, everyone in Final A places ahead of everyone in Final B, as they should.
- Points can reset after the heats. Untick the heats and their points stop counting toward the meeting result — the classic "the heats only decide the grid" format. The heats still run, still record results, still count toward your rating, and still seed the superheats and finals exactly as before. Nothing about the draw changes.
- The entry price is now on the first screen. It used to hide inside a collapsed section. It's in plain sight, drivers see it on the meeting page, and the Finance tab now just uses that number instead of asking you for it a second time — so the price you advertise and the price your profit is calculated from can't drift apart.
- Say if the event is streamed live. Tick the box when creating or editing a meeting, and add the channel link whenever you have it. Drivers see a live marker on the meeting page, and a Watch live link once you've added the URL.
Fixes
- Points still show when the final decides the meeting. Choosing "the final decides" briefly made every driver's points read 0. The order was right, the numbers weren't — your points are still there, they just aren't what decides that day.
- The currency picker in Finance works again, and it now lives next to the entry price where you set it, instead of asking a second time.
- Editing a meeting's price now updates its finances. Changing the entry price used to leave the Finance tab calculating from the old figure.
- Boxes line up again when a title needs two lines. In the format presets, the points options and the finance figures, a longer label used to shove everything under it down a notch, so a row of otherwise identical boxes looked staggered. Everything in a row now lines up regardless of how long the wording is — which mostly showed up in Spanish, where the labels are longer.
- Buttons are easier to hit on a phone. A lot of the smaller controls in the schedule, training, points and ELO screens were sized for a mouse. They're now full-size on phones and stay compact on desktop.
- "Restore your draft?" now actually shows up. The prompt was being drawn underneath the meeting form, so it looked like drafts were never offered back. It was there the whole time — just hidden behind the page. Same for the "discard your changes?" prompt.
- Your draft can't be lost by a mis-click any more. Clicking just outside that prompt used to count as "no thanks" and delete the draft. Now you have to actually pick Restore or Cancel.
- "1 carreras" reads "1 carrera". Counts throughout the form now use the singular when there's only one of something.
The timetable and the points editor got a clean-up
- Timetable rows don't overlap any more. With everything squeezed onto one line, the labels ran into each other and the time boxes cut off their own clock icon — worst in Spanish, where the words are longer. Each entry is now two lines: the name across the top, and underneath it the day, pre-grid, start, duration and comment, each with room to breathe. Narrow screens wrap instead of squashing.
- Setting up points is much more direct. It now asks one question first — "How do you want to award points?" — and gives you three ways to answer: pick a preset (F1, MotoGP, linear, top-10…), build a curve (say the winner's score, how much each place drops, and how many places score — it's generated as you type), or set every position by hand. You only see the controls for the way you picked, and a small bar chart of the resulting curve, plus the total points on the table, stays visible the whole time. Nothing was removed — pasting a list of values still works, it's just no longer hidden two clicks deep.
Know what a meeting will make you (new, private)
- A Finance tab, just for organizers. Put in what you charge per driver, what the circuit charges you, the price and cost of a training slot, and your fixed costs (trophies, timing, marshals). The page then tells you the thing that actually matters: how many drivers you need to break even, what you make with a full grid, and what happens on a quiet day. If the meeting can't turn a profit even when it sells out, it says so plainly.
- IVA is handled properly. Set your rate and say whether your prices and the circuit's quote already include tax. Every figure is then worked out on the money you actually keep — the VAT you collect is shown separately as money owed to the tax office, never counted as profit, along with what you can reclaim on costs.
- It is genuinely private. None of it is stored on the public meeting page, and drivers never see it — only you and your organization's organizers can open the Finance tab.
Creating a meeting is now a guided flow
- Five clear steps instead of one long page. Creating a meeting now walks you through Basics → Format → Points & ELO → Schedule → Review. Each step asks one thing and explains it in plain language, and a panel on the right always shows what you're about to create — how many groups, how many races, which rounds score points, how many training places. If something's missing, the step tells you exactly what, instead of just refusing to continue. You can jump back to any step you've already passed.
- Groups and rounds explained properly. A group is who's on track together; a round is when they race. The form now says so, shows you that races are created as rounds × groups, and previews every race name before you commit (3 heats with 2 groups → R1A, R1B, R2A, R2B, R3A, R3B). Four one-click starting points — Club day, Two groups, Heats → Superheats → Finals, and Endurance — get you a sensible setup in one press.
- "ELO categories" is gone; there's now an ELO impact grid. That panel was confusing because it wasn't about drivers at all — it set how much each race moves ratings, but asked you to type names that had to match your race names exactly, and quietly did nothing when they didn't. Now it's a simple grid: one row per round, one column per group. Set one weight for the whole round, or different weights per group when your finals are tiers (Final A ×1.0, Final B ×0.6). There's a No ELO option too. Underneath, it lists every race with the exact multiplier it will get, so there's nothing left to guess. Your existing meetings are untouched — their weights keep working exactly as they do today.
- Points are no longer buried. Enabling championship points used to be hidden two levels down, which is why most people couldn't find it. Each round now has its own card with a big "awards points" switch, ready-made curves (F1, MotoGP, Superpole, linear…), and a live preview of the whole table. Turning points off for a round is now a proper choice — the round still runs and still counts for your rating, it just doesn't add to the standings. Most meetings only score the finals, and that's now easy to express.
- Qualifying finally makes sense. There were two things called "qualifying" sitting next to each other. Now there's one obvious option — Pole bonus, extra points for whoever was quickest inside a heat or final — right on that round's points card. A genuine standalone qualifying session (its own slot on the timetable, ranked by lap time) is still available under Advanced formats, where the difference is spelled out. If your meeting already uses one, nothing changes.
Multi-day meetings and training sessions
- Multi-day meetings actually work when creating. Tick "runs over more than one day" and every race, break and training session gets its own day, with day tabs across the timetable. Auto-fill restarts the clock each morning instead of running day two through the night. (Editing a meeting already did this; creating one didn't — everything silently landed on day one.)
- Training sessions now have their own step in the form, instead of being tucked under the schedule. Both Training and Finance are marked optional, so you can skip straight past them.
- Create a whole block of training sessions at once. Instead of adding sessions one by one, describe what you want — 6 sessions of 20 minutes from 10:00, 5 minutes apart, alternating Normal and Reverse — and they're all created. Every session stays editable afterwards. Label patterns include Normal/Reverse, Normal ×2/Reverse ×2, Track A/Track B, or anything you type, with a preview of the badges you'll get. Re-apply labels and Re-time let you adjust the pattern without losing edits you've made, and sessions people have already booked into are protected.
- A review screen before anything is created. The last step shows the full running order, the training block and a summary of every decision, with links back to change anything — and tells you exactly how many races are about to be created.
Behind the scenes
- Security update to the web framework. Updated Next.js and the image-processing library to their latest patched versions, closing a set of published vulnerabilities — including ones that could have exposed internal server endpoints or been used to overload the site. No visible changes; everything works exactly as before.
- Security checks rebuilt on free open-source tools. The paid GitHub security add-on was retired; every pull request is still automatically screened for vulnerable code patterns (Semgrep), leaked secrets across the entire project history (gitleaks), newly-introduced vulnerable dependencies (Google OSV-Scanner) and licence problems — at no cost and with the same protection as before.
New
- Create a meeting straight from the organization page. Admins and an organization's organizers now have a Create Meeting button on the org page that opens the meeting form with that organization already selected — no need to go to the meetings page and pick it manually.
- Merge profiles is easier to find, and now finds mistyped duplicates. The Fusionar Perfiles / Merge Profiles tool now sits right next to Users in the admin panel (it was tucked away under System). It still auto-detects same-name/same-email duplicates, and now also has a search box to find and merge any two profiles — useful when a driver misspelled their name on a second account, so the names don't match exactly. Search by any part of the name, email, or driver ID, mark one to keep and one to merge, and confirm.
- Admins can merge duplicate driver profiles. A new Merge Profiles tool in the admin panel finds people who registered twice (same name or same email) and lets an admin merge them into one, choosing which email to keep. All of the merged profile's races, results, championship points, challenges, team role and history move onto the kept profile; the duplicate profile and its login are removed and ratings are recalculated automatically. Every merge shows a preview of exactly what will change first, is blocked if the two profiles somehow raced in the same race, and needs an explicit typed confirmation — so it's safe and reversible-by-review before anything happens.
New
- You can now add or change a meeting's rules after it's been created. Previously the rules document could only be attached while creating a meeting — once it existed, there was no way to add, replace or remove them. Edit Meeting now has a Rules section with the same three options as the create form: no rules, a link to an external document, or a PDF upload. If rules are already attached you get a link to view the current file, and choosing a new one replaces it.
Fixed
- Uploading a rules PDF no longer fails with a confusing "unauthorized" error. Some perfectly valid PDFs were rejected because of how the browser reported the file's type — which looked like a permissions problem and sent people checking their organizer role. The upload now identifies the file correctly regardless of what the browser says.
- A failed rules upload no longer throws away the whole meeting. If the PDF failed to upload while creating a meeting, the meeting silently wasn't created and the error didn't mention the PDF at all. You now get a clear message saying exactly what went wrong, that the meeting was not created, and that rules can be added later from Edit Meeting.
- Rules PDFs over 10MB are rejected immediately, with the file's actual size in the message, instead of failing after a long upload.
- Drivers you add to a meeting no longer disappear. When an organizer registered a driver by hand, the driver would show up for a second and then vanish from the list — as if they'd been deleted. The registration was actually saved every time; the page was just re-reading a copy of the event roster that was up to 30 seconds old and painting over the driver you'd just added. The page now refreshes from live data straight after each change, so what you see is what's saved.
- Some registered drivers couldn't be found in the "Add Driver" search at all. Roughly one in eight driver profiles were missing from the picker entirely, so searching for them came up empty and the only way forward was to create a duplicate "ghost" for someone who already had an account. Every registered driver now shows up in the search.
- You now get told when adding a driver fails. Previously a failed registration looked identical to a successful one that vanished. Errors now show a clear message, and the driver is added to the event and all of its races in a single all-or-nothing save, so the event roster and the race line-ups can never drift apart. The search box also stays open between adds, so registering a full grid is much quicker.
- Merging a ghost driver into a real account no longer leaves blanks in draws and standings. When an unregistered "ghost" driver was linked to a real account, their entries in the group draw grid and in saved meeting standings were left pointing at the old, now-deleted ghost — so they showed up as blank or unknown rows. All of those references now move across with the rest of the driver's history.
- Bulk "Inscribe drivers" in the admin panel could wipe out earlier registrations. If anyone had registered drivers after the admin page was opened, the bulk inscribe would overwrite them out of the event. It now only ever adds, and it also registers the drivers into the event's races (previously it didn't, so they never appeared in the group draw).
- "You do not have permission to create meetings" is fixed for good. New organizers were being given the role in a way that looked complete but wasn't: they'd see the Create Meeting button, fill in the whole form, and get a permission error at the very end. The cause was that the role could be switched on for a person without actually adding them to any organization's Organizer Team — and the Organizer Team is what really grants access. Now:
- Granting the organizer role asks which organization it's for and adds the person to that team properly, so it works immediately (no logout/login needed).
- The Create Meeting and Create Championship buttons only appear if you can genuinely create one, and the organization list only shows organizations you actually manage — auto-selected when there's just one.
- If something is still missing, you're told before you fill in the form, and the message says exactly what to ask for ("ask an admin or an existing organizer to add you to the organization's Team") instead of a generic error.
- Assigning someone to an organization now offers to make them an organizer of it too — ticked by default for people already marked as organizers. Previously "assign to organization" only set their home club and Driver ID, which looked like it granted access but didn't; if it's left unticked for an organizer, you're now warned that they still can't create meetings.
- Admins can now see at a glance in the user list which organizations each organizer manages, and a warning badge on anyone whose role was left half-configured.
- The two affected accounts (Kartódromo Valencia and Ariza Racing Circuit) have been fixed and can create meetings now.
- Point system "Positions" generator accepts any number again. In the Custom Generator, the Positions box was stuck at 4 — typing any number snapped back to 4. You can now type any value (e.g. 10, 20, 32); it's kept within the allowed 4–60 range when you finish or press Generate.
- "Create Meeting" button is readable on every championship theme. On championships whose brand color is very dark, the "Create Meeting" button showed dark text on a dark background (nearly invisible). The button now automatically uses white or dark text based on the brand color for guaranteed contrast.
- A "Manage" button was added to each meeting in a championship's Meetings tab (visible to admins and organizers) for quick access to managing that meeting.
- Searching the rankings shows your real position again. When you searched a driver by name, the top matches were shown on the 1st/2nd/3rd podium — so someone ranked #107 looked like they were #1. Now a name search lists every match with its true ranking position (no podium); the podium still appears when you filter by country or region.
New
- Admins can hand a new organization to the right owner. When an admin creates an organization on behalf of a club, they can now search for the owner by email and assign them as the organizer — so that person gets full control of their org straight away. Before, the admin was silently set as the only organizer and the real owner had no access. (One existing organization affected by this has been corrected.)
- Download the standings as a PDF. On any meeting's Clasificación tab, click "Exportar resultados (PDF)" to get a clean A4 document with the full classification: every driver, their points per round (H1–H4, SH, F), finishing positions, pole/FL badges, ELO, and total. Podium positions are highlighted in gold/silver/bronze. Same look as the draw-groups PDF.
- The Schedule tab is now a proper, tappable agenda — far less scrolling. Up top there's a sticky bar with day tabs (opens on today when the event is live), filter chips to show only Races / Training / Other, and a "Now" button that jumps you to what's happening right now. Each day shows a quick summary ("16 heats · 4 semis · 4 finals · doors 07:00") and can be collapsed. Everything is tuned for phones and still one tap through to any race.
- Two-day (and longer) meetings now read clearly. The Schedule tab groups everything under a header for each day — so a Friday practice day and a Saturday race day are cleanly separated instead of piled into one long list. When you edit a multi-day meeting, each race or slot has a small day picker so you can put it on the right day; what you set is kept exactly (before, saving pushed everything back to the first day). Race cards in the schedule remain tappable straight through to that race.
- Cascade final points now match everywhere — no more "Recalculate" needed. When you open a cascade final to enter results, the points are already correct (before, they loaded stale and only fixed themselves after clicking Recalculate). And the race results page now shows the same cascade points as the standings and the manage screen — previously it showed the flat per-race points (e.g. 150 instead of 115). Saving a final always writes the correct points, which the championship table reads.
- Long meeting descriptions are tidier on your phone. A meeting's description now shows the first few lines with a Show more link on mobile, so a long intro no longer buries the schedule and standings — tap to expand, tap again to collapse. Paragraph breaks in the text are kept intact.
- Cascade finals now score correctly — and guide you through uploading them. In a cascade (A/B/C/D finals scored on one overall table), the winner of each final now gets that final's true overall points — the top final's winner takes the top score, and each lower final steps down from there (the last driver of Final A always scores just above the first driver of Final B, and so on). Before, a lower final uploaded first could wrongly hand its winner the grand-final score. You can now upload finals in any order — including running the grand final last, as usual — and the points come out right; the same fix applies when you turn on cascade finals by editing an already-created meeting. When you score a cascade final, a panel now spells out exactly what to do: which tier it is, that you enter positions 1–N for that final only, the overall positions and points it maps to, and a live check that the order is preserved — plus a heads-up if a final still needs drawing.
- Smarter draw ordering + richer PDF. Heat lists are alphabetical (easy to find a driver), while superheats and finals now keep their real seeded grid order. The exported draw PDF also shows each driver's ELO and each group's SOF (average ELO). And if you're about to re-draw a tier that already has uploaded results, a clear warning now appears before you generate/apply — not just at the last step.
- Re-drawing groups now clears old results and undoes their rating impact. If you apply a new group draw, any results already uploaded for those races are wiped (since the groups changed) and the ELO/stats they gave each driver are rolled back automatically — no leftover phantom ratings, no manual recalculation needed. You'll get a heads-up warning before it happens. Draw lists are now sorted alphabetically by driver name (with the kart still shown) in the Races tab, the draw preview, and the PDF, so drivers are easier to find.
- Tap a driver in the race draw to open their profile. In a meeting's Races tab, the drivers in each group now show their profile photo and are tappable links to their profile — so you can jump straight from the draw to a driver's page. Guests (unregistered drivers) stay as plain entries.
- Your full name is required — and no duplicate profiles. When you set up or edit your profile, you now need to enter your first name and at least one surname (single-word names aren't accepted). And if a driver with your name already exists on the site (a registered driver or a "guest"/ghost profile), the app will stop you from creating a duplicate and ask you to contact the organizer to link your existing profile instead — so your history stays in one place.
- See group strength (SOF) and each driver's rating. The Races tab now shows a SOF badge (average ELO) on every group and each driver's ELO, and the participant list no longer scrolls — it lays out in neat columns so you see the whole group at once. The draw preview shows each group's SOF too, so you can balance groups by strength as you go.
- Superheats & Finals use the same kart per starting slot. In the superheat/final draw, the driver on grid slot 1 gets the same kart in every group (and every superheat), slot 2 the same, and so on — the physical karts are simply reused by position. Heats still rotate karts so nobody repeats one during the heats.
- Scoring a drawn race shows each driver's kart. When you enter results by hand for a race you've drawn, the grid already lists just that race's drivers (drag or type to reorder, search to add a walk-in) — and now each driver shows their kart number so they're easy to pick out.
- Export your group draw as a PDF (organizers). From a meeting's Manage tab or the Races tab you can now download a clean, print-ready PDF of the draw — with the RWR logo, each group's karts and drivers (sorted by kart number so it's easy to check off), the session times you set, and your own race names. Filter by a driver to get just their personal schedule. Works for heats, superheats and finals, and it downloads straight to your device.
- Find your races fast (Races tab). There's now a search box on a meeting's Races tab — type a name to see just that driver's races, group, kart and time, and tap any race to see everyone in it.
- Change a meeting's race structure after creating it (organizers). The Edit screen now has a Race Structure section, just like when you create a meeting: add or remove groups, rename them, or change how many heats/superheats/finals there are. Renaming a group keeps all its results. Adding rounds or groups creates the new races for you; reducing them removes races — except a race that already has results, which is protected: you'll be asked to clear its results first. After applying, review the schedule and hit Save.
- Draw your groups and karts inside the app (organizers). In a meeting's Manage tab there's now a Group Draw & Karts tool. Pick a tier and it splits your drivers across the groups for you, round by round. Heats: every round puts all your drivers into that round's groups (so 78 drivers across 4 groups ≈ 20 each), evened out by rating so no group is stacked — or fully random — and it reshuffles who's together each round. Superheats: deal the current ranking around the groups one-by-one (1st to group 1, 2nd to group 2, 3rd to group 3, 4th back to group 1…). Finals: cut the ranking into blocks (top group first, then the next, …). It also hands out kart numbers — drawn at random, but it remembers any driver who must always keep the same kart (e.g. an adapted kart) and rotates everyone's kart across rounds so nobody keeps the same one all day when it can be avoided. You always get a preview first, laid out heat by heat: re-roll it, move people between groups, fix a kart by hand, add a last-minute entry or drop a no-show — and only then apply. Nothing is saved until you confirm.
- Share the Top 100 on Instagram in one click (admins). A new "Ranking Images" tool in the admin panel builds 10 polished, ready-to-post images of the current Top-100 ELO ranking — 10 drivers per image, in Instagram's 4:5 size. Pick a backdrop style (Carbon & Lights, Night Circuit, Podium Spotlight or Speed Trails) and the AI paints the artwork, while every driver name, rating, category, flag and photo is drawn exactly — no typos, no wrong faces. Download each card or grab all 10 as a ZIP. Every set you generate is saved automatically, with a history list so you can re-open or re-download past ones.
Fixed
- Export PDF is reliable now. It always reflects the current draw, and if a tier hasn't been drawn yet you get a clear "no draw to export" message instead of a confusing empty PDF.
- Exporting the draw PDF now shows a spinner. Clicking Export PDF used to give no feedback while the file was being prepared, so it felt stuck. The button now spins until the PDF is ready and then downloads — no more wondering if it worked. (The Export button only appears once a tier has an applied draw.)
- Editing your profile works again. Saving profile changes (including your photo) no longer fails with a permission error.
- Meeting pages read better on phones. The meeting tabs (Overview, Schedule, Races, Standings, Participants…) now fit your screen — the tab bar wraps instead of scrolling sideways, and long driver names no longer push the standings off-screen. No more pinch-zooming or side-scrolling to read a meeting.
- Entering results on your phone shows the rating change. The mobile results card now always shows each driver's ELO gain/loss and their new rating (green for a gain, red for a loss) — including for DNFs — updating live as you set positions.
- Draw times match what you typed. The session times in the exported draw PDF now show exactly the times you entered — no timezone surprises, wherever the file is generated.
- Race ELO weights now really count. Organizers can give each race tier a different ELO impact (e.g. Final A counts 100%, Final B only 60%) — but due to a naming-matching bug those weights were silently ignored, so winning a lower final paid out the same rating as winning the top one. The fix applies everywhere ELO is computed, and the results page now shows exactly which weight is being applied to a race before you save — with a clear warning and a manual selector if the system can't match a category on its own. No more silent surprises.
- Your race history is complete again. Some drivers saw fewer races in their profile history than their "Races" stat claimed — races where you were added by the organizer at results time simply never showed up, and editing results could quietly corrupt your race count. All affected profiles have been repaired, and the history list, your garage, and the race counter now always agree. If you spotted races "missing" from your profile, they're back.
- No more duplicate "ghost" of a registered driver. Once a driver claimed their ghost profile (or an admin linked it), the old ghost could still appear as a separate entry in meeting entry lists and elsewhere — so the same person showed up twice. Now, claiming a ghost moves everything over to the real account — every race (past and upcoming) and every meeting entry — and removes the ghost completely, so there's only one of you. All existing claimed ghosts have been cleaned up.
- Profile ELO chart is accurate again. After a behind-the-scenes ratings recalculation, the per-race ELO graph on profiles could show a stale trajectory (ending on a number you no longer had), and some imported drivers had no graph at all. Every recalculation path now rebuilds the race-by-race history to match, so the chart always reflects your real results. (Your rating and ranking position were always correct — only the graph was out of date.)
- Tidier meeting & championship entry lists. Cleaned up stale references left behind by deleted races/meetings and merged drivers: meeting participant lists now reflect everyone who actually raced, deleted races no longer linger in a meeting, championships no longer point at meetings that were removed, and team member counts are accurate.
Improved
- Fairer, predictable meeting tie-breaks — now saved with the results. When two drivers finish a meeting on equal points, the standings settle it by their finishing positions — whoever did better in the latest race wins, then the race before that, and so on (handy as you upload heats one by one). In the rare case two drivers are dead-even in every race, the order is decided by a one-time coin-flip that is then locked in. The resolved order is now stored alongside the meeting in the database every time you upload results, so everyone sees the exact same standings (it's no longer just worked out on-screen).
- Cleaner, more consistent look across the whole app. Replaced scattered off-brand purple/cyan with intentional colors — ghost/guest drivers now read as a calm neutral, AI features get their own accent — so the lime brand color stands out where it matters (your action, your row).
- Your ELO and headings are easier to read. Removed the faded "gradient" text effect from page titles and the big rating number, so the most important figure is always crisp.
- Your category looks the same everywhere. S1/S2/S3 colors now match across rankings, your profile, and your garage.
- Better for keyboard and screen-reader users. Every button and link now shows a clear focus outline when you tab to it.
- Snappier ghost-claim link — opening "claim ghost" goes straight to your garage with no loading spinner flash.
- Friendlier confirmations for organizers — deleting results, championships, or registrations now uses clean in-app dialogs and toast messages instead of the browser's gray pop-ups. Deleting a race's results shows exactly how many drivers' ratings will be rolled back before you confirm.
- No more loading spinners in the admin panel — list tabs now show a tidy skeleton placeholder while they load.
- Enter race results from your phone — the results table now becomes a clean stack of per-driver cards on mobile, with big tappable Pole / Fastest-lap / DNF chips and position controls. No more pinch-zooming a 13-column table at the track.
- Tidier beta notice — the "Beta" banner is now a slim, calm one-line strip that scrolls out of the way, instead of a chunky orange bar parked under the menu.
Still coming as a follow-up: the remaining admin translations and converting the rest of the smaller confirmation pop-ups.
v0.21.0 — June 5, 2026
New
- The results importer now speaks Spanish too — the whole "Import results" flow is bilingual.
- Smarter driver matching on import — when you import results, drivers who already raced in earlier sessions of the same meeting are suggested first, so more rows link automatically.
- Create a meeting straight from a championship — admins/organizers now have a "Create meeting" button on the championship page that opens the form with that championship already selected.
Fixed
- Uploaded results show up right away — after importing/saving, the meeting page no longer needs a manual refresh to show the new results.
- Fastest-lap points now count in the championship standings — previously the fastest-lap bonus showed on the race but was missing from the standings total. Re-save an affected race to correct historic results.
- Fairer dropped scores — when a championship drops each driver's worst result, a meeting you missed is never used as the drop; only events you actually raced can be dropped.
v0.20.0 — June 3, 2026
New (Beta)
- Import race results from a file with AI — On the race management page there's now an "Import results (Beta)" button. Upload the official results as a CSV or a text-based PDF and the app reads the finishing order and driver names for you, then automatically links each name to the right registered driver (and falls back to any platform driver, then ghosts). Anything it's unsure about is clearly flagged with a colour and icon so you can check it. You can reorder positions, fix names, re-link a driver, or create a ghost — then confirm, and the results drop straight into the normal editor for you to review and save as usual. It's a big time-saver over typing every row by hand.
- Beta notes: works best with text-based PDFs (not scanned photos) and one heat/session per file. As always, you review everything before saving — nothing is uploaded automatically.
v0.19.0 — June 3, 2026
Changed
- Simplified meeting creation — Removed the "Parse with AI" rules-parser box from the Create/Edit Meeting forms. It added complexity for little gain; set up your ELO categories with the one-click presets (SAC, SKC, RSS, CCK…) or by adding them manually, exactly as before.
Behind the scenes
- AI driver evaluation now runs on a new provider — The automatic Pro/Sport/Rookie classification that kicks in after a driver's 10th race was moved to a different AI backend (Google Gemini via Replicate). The evaluation behaves the same as before; only the underlying service changed.
v0.18.9 — May 28, 2026
Behind the scenes
- Safer testing of big changes — Set up a fully isolated development environment (
dev.rentalworldranking.com) backed by a separate copy of the database, so major upcoming changes (like the planned ELO/category overhaul) can be tested end-to-end without any risk to live data. No user-facing changes in this release.
v0.18.8 — May 11, 2026
Bug Fixes
- Driver profile pages with any race history are loading again — Root cause for the v0.18.6 regression that v0.18.7 didn't fully fix. The Server Component was producing the right data, but Next.js's server-to-client streaming layer was converting all Date fields to plain strings (a known quirk of how React Server Components serialize objects), while the Client Component was still calling Date methods on them — that threw immediately on the very first race row in any non-empty driver history, leaving the page stuck on the loading animation. Wrapped the three Date method calls in
new Date(value) so the same code now works whether the value is a Date (dev mode, no cache) or an ISO string (production, after server-to-client serialization). Profiles with no races (which were rendering fine, e.g. Kevin's) were not affected because the sort/map callbacks never iterated.
v0.18.7 — May 11, 2026
Bug Fixes
- Some driver profile pages were stuck on the loading skeleton in production after the v0.18.6 deploy — A handful of specific driver profiles (Jon del Valle reported, among others) stopped rendering past the loading animation. They never crashed visibly — they just hung forever. The page was internally getting an unhandled error or a never-resolving promise on the server, and because the page's data-fetching code didn't have a safety net for that, the whole render stayed in "loading" forever. This patch wraps every data-fetching branch of the public driver profile in its own safety net, with detailed logging that names the affected user ID. If any data source (race history, challenge history, regional ranking, tier percentile, organization, even the user lookup itself) now throws for any reason, that section silently degrades to empty and the rest of the profile still renders, while the server logs capture the exact cause for follow-up. No visual change to the UI; profiles that were already working continue to work identically.
v0.18.6 — May 10, 2026
Performance
- Race-detail and organization-detail pages now load fast on mobile, and your own garage no longer slows down as the platform grows — Three more pages got the same treatment as the public driver profile in the previous patch.
/races/<id> was making a separate database call for every driver in the race to fetch their name and photo, one after the other — that's painful for a race with 20+ drivers on a phone. /organizations/<id> was doing the same thing for every member and every organizer, twice. And /garage was secretly downloading every user in the database every time you opened it, just to compute your regional ranking. All three are fixed: the race and organization pages now render on the server with all the driver/member/organizer data fetched in a single batched query; the garage now asks the database "how many drivers in my region rank above me?" with two cheap count reads instead of downloading them all. None of the visible UI changed — the pages just show up.
- Admin dashboard is also faster — The admin users list now shows top-500 by ELO instead of every record. A proper paginated admin UI is a separate project; this is the stopgap.
- The development guide (
CLAUDE.md) now spells out the data-access patterns so every future page follows them by default — server-first data, indexed queries with limits, count-not-download for aggregations, batched fetches instead of one-per-id loops, and bounded lists for anything over 100 rows.
v0.18.5 — May 10, 2026
Performance
- Driver profile pages (
/profile/<uid>) no longer hang on phones — Opening someone else's driver profile on mobile was getting stuck on the loading skeleton, sometimes for tens of seconds, sometimes never finishing. The page was downloading the entire races collection, every user document, every active ghost driver, and every completed challenge from the database — all in the browser, on every visit, just to find this one driver's race history and compute their tier percentile and regional ranking. On a phone over a typical 4G connection that's multiple megabytes of JSON before anything could render, and the page had no timeout, so a flaky connection meant it would silently spin forever. The page has been rewritten to fetch all of this server-side using the proper indexed queries and lightweight aggregation reads — race history pulls only this driver's last 100 races (using an index that already existed), tier percentile uses three cheap count() reads instead of pulling every user document, and regional rank uses two cheap reads instead of scanning the user table. Total bandwidth on a profile open dropped by roughly the size of the database. Tier badge, "Top X% of drivers" line, regional ranking link, win/podium rate, race history, and match-race history all render identically — there's no visual change, the page just shows up.
- Two new database indexes were added to support the cheaper queries:
users (region, elo) for the regional rank lookup and challenges (status, completedAt) for the recent-completed scan. These must be deployed alongside the build.
v0.18.4 — May 10, 2026
Bug Fixes
- "Failed to save results" toast no longer fires after the race results have actually saved, and driver ELO/stats now actually update when a non-admin co-organizer saves a race — When a co-organizer who isn't a platform admin clicked Save on a race manage page, two things were quietly wrong: the page popped up
Failed to save results. Please try again. (even though the race document — including positions, points, status, and timestamps — had already been written and showed correctly elsewhere), and the participating drivers' ELO, total race count, wins, and podiums on their profile pages were never updated by that save. The race itself looked fine, but anyone checking their profile or the rankings afterwards saw their ELO was the same as before, drifting further from reality with every race a non-admin organizer ran. Root cause: the database security rules let co-organizers write the race document but didn't let them write to drivers' user docs (only the user themselves or a platform admin could), so the second half of the save operation was silently rejected — and the frontend treated that rejection as "the whole save failed" rather than "the race saved but the driver stats didn't." The bug has been there since launch and was simply masked while most organizers also held the platform-admin role.
- Database rule: Co-organizers can now write the four race-derived fields on driver user docs —
elo, totalRaces, wins, podiums (plus updatedAt) — and only those. They still can't change roles, driver IDs, organization membership, or any other profile field. The full ELO history audit trail (which already permitted organizer writes) makes any misuse detectable.
- Frontend: Each driver's stat update is now wrapped individually, so one driver failing doesn't poison the rest. The save flow knows the difference between "the race document never saved" (the original error message stays) and "the race saved but the follow-up driver updates failed" (now an honest
Race results saved, but a follow-up update failed. Refresh and re-save to retry.). With the rule fix in place, normal saves should hit zero per-driver failures; the wrappers are belt-and-suspenders for transient network issues or future write paths.
- Net effect for organizers: Saving race results works end-to-end without any error toast. Drivers' ELO and stats actually update. The misleading toast is gone.
- For drivers whose ELO has been silently stale up to now: their
users.elo will only catch up the next time a non-admin organizer (or admin) re-saves a race they participated in. The race documents and the per-race ELO history subcollections were unaffected (those writes already worked), so the source-of-truth audit trail is intact and an admin can re-derive any driver's ELO from race history if needed.
v0.18.3 — May 10, 2026
Bug Fixes
- Championship standings filter no longer auto-selects bogus categories — On the Costa Blanca championship and any other championship configured with cascading finals or rotating heat groups, the standings tab was rendering a filter row with entries like
A / B / C / D / Final A / Final B / Final C / Final D / Pro / Rookie / Sport / carreras and silently auto-selecting the first one (A). None of those describe a coherent driver bucket — A/B/C/D are rotating heat groups (the same driver runs in several of them across the heats) and Pro/Rookie/Sport/Final A–D/carreras are per-session ELO-tier definitions the organizer used to weight ELO impact, not driver categories. With the A filter quietly active, the standings re-ranked drivers using only their A-group races, which made Kevin Sáez and Jon Del Valle both display 70 championship points (Kevin as P1 of EVENTO 2 within the filter, Jon as P1 of EVENTO 1 within the filter), even though the actual unfiltered meeting standings have Jon at P1 in both meetings. The same detection logic that the meetings page got back in v0.17.5/v0.17.7 (rotating-heats detection, plus skipping meeting.categories[] entries that don't correspond to a real race group) is now applied to the championship standings too. For the Costa Blanca championship the filter row no longer renders at all, and the standings show the overall ranking matching the organizer's PDF (Jon Del Valle in P1, Ángel Llopis in P2, Javi Sánchez in P3, Kevin Sáez in P4 …, with the configured "discard worst meeting" rule applied on top). Championships built around real driver categories (S1/S2/S3 with matching race groupNames) keep their per-category filter unchanged.
v0.18.2 — May 10, 2026
Security
- Organizers could see (but not save) the management UI on meetings belonging to other organizations — On any meeting list or meeting detail page, a user who is an organizer of any organization saw a "Manage" button and a "manage" tab on every meeting in the platform, regardless of whether they were actually listed on that meeting's organization. Opening the manage tab rendered the full management surface — registered drivers, schedule, race configuration, point system, results upload — so it leaked another club's operational data to anyone with the global organizer role. Saves were already blocked at the database level (any action button silently produced a permissions error), but the read-side rendering was a real privacy/UX failure and contradicted the v0.18.0 promise that "organizations.organizers[]" is the only thing that decides who can manage what. Only people listed on that meeting's organization (or platform admins) now see the Manage button on the meetings list and the manage tab on the meeting page. Championship management, race management, and organization editing were already correctly scoped — this fix closes the remaining meeting-level path.
v0.18.1 — May 10, 2026
Bug Fixes
- Cascading-finals points are no longer overwritten when an organizer saves the meeting form — On meetings configured with cascading finals (where the final-race points come from one big overall-position curve like
1:200, 2:195, … , 19:150, … , 36:100, … , 53:50, …), opening Edit Meeting and clicking Save was quietly replacing the correct cascading values on every final-race result with the much smaller per-race finals points (typically 1:50, 2:40, … , 10:12 and 0 from P11 onwards). Drivers in Final B/C/D got the same 50/40/32/… curve as Final A instead of their tier-correct values, and anyone outside the per-race top 10 had their points reset to zero. Saving the meeting form now respects the cascading curve for final races: Final A P1 stays at 200, Final B P1 at 150, Final C P1 at 100, Final D P1 at 50, and so on across the full curve.
- Meeting standings now always trust the cascading curve over stored per-result points — Even with the underlying writer fixed, any meeting whose final-race results had been corrupted in the past (by the bug above, or by an import script that didn't apply cascading) would have continued to show the wrong totals on the standings tab, because the standings code was only recomputing points when the stored value was zero. The standings tab now re-derives points from the cascading curve every time it renders for cascading-final meetings, so the displayed standings always reflect the configured curve regardless of what's stored on individual results.
- Repaired EVENTO 1 - CCB and EVENTO 2 - CCB standings and per-race points — Re-ran the cascading curve over the 4 finals on each meeting and rewrote each result's points to match. EVENTO 2: 67 of 68 final results changed; EVENTO 1: 61 of 62. Examples (same in both meetings): Final A P1 went from 50 → 200, Final B P1 50 → 150, Final C P1 50 → 100; in every final, positions past P10 went from 0 to their proper cascading values (e.g. Final A P11–P18 in EVENTO 2 are now 183, 182, …, 176). The two meetings have slightly different cascading curves (EVENTO 1 was set up for 16-driver tiers, EVENTO 2 for 18-driver tiers) — both are now correct against their own configured curves. ELO history was not touched — only the points displayed on each driver's race result and the meeting standings.
v0.18.0 — May 7, 2026
Bug Fixes
- Co-organizers no longer hit "Missing or insufficient permissions" on second-org content — A recurring bug for users added as organizer of more than one organization. Behind the scenes, the app was juggling three different ways of recording "is this person an organizer" (a global flag on the user, the array of UIDs on the organization, and a single legacy "primary org" field on the user), and the second-org case made them disagree — meetings would refuse to save, the race-management page would redirect to "Access Denied" before rules ran, and the championship/meeting create flow would silently fail mid-write. We've collapsed the model so that
organizations.organizers[] is the only source of truth for org permissions everywhere — Firestore rules, client-side edit buttons, page redirects. If you're listed on the organization, you can manage everything under it; if you're not, you can't. No more disagreement between layers.
- Co-organizers can now edit the organization page itself — Logo, brand colors, social links, contact info, custom links — anything on the organization detail page. Previously only the original creator of the org could change these; co-organizers added later got a permission-denied error from Firestore even though the UI showed the edit form. Any UID listed in the organization's
organizers array can now save these edits.
Changed
- Tightened scoping: an organizer of Org-A can no longer create or edit content under Org-B — Previously a user with the global "organizer" flag could create a meeting, championship, or race claiming to belong to any organization, not just the ones they actually organize. Both the Firestore rules and the client now verify at write time that the new doc's
organizationId matches an org you're listed on. If you're an organizer of multiple orgs, nothing changes — your existing access works exactly the same. If you only organize one, you can no longer accidentally create resources under another club's name.
- Removing someone from an organization's organizers list now revokes their access to past content too — When an admin or principal removes a user from
organizations.organizers[], that user immediately loses the ability to edit or delete past meetings, championships, and races under that org — even ones they originally created. Previously the original creator retained access through a fallback rule, which produced confusing situations where former staff could still modify records. The org owns its content; org membership is what controls access.
- The app now picks up new organizer assignments without a hard refresh — When an admin adds you as a co-organizer of an organization, the management buttons in the UI now appear within seconds, instead of requiring a sign-out/sign-in or a full page reload. Same applies in reverse — if you're removed, the controls disappear without needing a refresh.
v0.17.8 — May 6, 2026
Security
- Banner URL preview hardened against unexpected URL schemes — The "Custom Banner URL" field on the Create/Edit Meeting forms previewed whatever URL you typed, with no validation that it actually started with
http(s)://. Pasted javascript: or other unusual schemes ended up in the page DOM as the <img> source. The preview now only renders if the URL begins with http(s):// or is a local image upload (data:image/...); anything else simply doesn't preview. No effect on legitimate banner uploads or URL pastes. Closes two CodeQL js/xss-through-dom alerts.
- Production Docker image no longer ships the npm CLI — The deployed image was built
FROM node:20-alpine, which bundles a copy of the npm command-line tool. We never run npm at runtime (the Next.js standalone server runs via node), but the bundled CLI's own dependencies (tar, minimatch, glob, cross-spawn, brace-expansion) carried about ten HIGH-severity CVEs that kept showing up on the security dashboard. The runner stage of the Dockerfile now strips the CLI on build, removing the entire vulnerable surface in one step. No effect on the running app.
- Build-time
postcss patched — Next.js 16 was bundling an old version of postcss (a CSS processor that runs only at build time) flagged for an XSS-via-stringify issue. The dependency tree now pins postcss to the patched line across the project, clearing the alert.
Bug Fixes
- Removed dead guard checks — Internal cleanup in the data-access helper: a couple of
!= null checks were running after the function had already returned for null inputs, so they could never fail. No behavior change; just trims dead code that was tripping the static analyzer.
- Server-side Firebase Admin SDK actually configured at deploy time — The Kubernetes Secret that's supposed to expose the Firebase Admin credentials to the running pod was using key names with hyphens (
project-id, client-email, private-key). Kubernetes silently skips secret keys that aren't valid environment-variable identifiers, so the pod has been booting without those env vars set the whole time, and any server-rendered page that tried to read Firestore via the Admin SDK would have failed at first contact. The deploy workflow now creates the Secret at deploy time with the correct FIREBASE_ADMIN_* keys, sourced from new GitHub Actions secrets. No effect on anything that was already working; this enables server-side Firestore that was silently broken.
- CI
.env.production writer hardened against stray whitespace in secrets — A trailing newline accidentally left on a Firebase secret value would end up baked into the build and crash Next.js prerender with Firebase: Error (auth/invalid-api-key). The deploy workflow now trims carriage returns and surrounding whitespace from each secret value before writing it.
v0.17.7 — May 2, 2026
Bug Fixes
- Console no longer spammed by Firebase Analytics "offline" errors — If you used an ad blocker, privacy extension, corporate VPN, or briefly lost your network connection, the browser console filled up with
Installations: Could not process request. Application offline. (installations/app-offline) errors every time you navigated. These errors were harmless — analytics simply can't reach Google's servers — but they made real bugs hard to spot. Analytics calls now silently ignore that specific blocked-network case while still surfacing any other unexpected failures as a warning.
- Meeting standings no longer show meaningless filter buttons on CCK-style meetings — On CCK España and any meeting using the "CCK (A/B/C Finals)" preset, the standings tab was showing a row of filter buttons (
All / A / B / C / Final A / Final B / Final C / Heat / Semifinal A / Semifinal B / Semifinal C) that didn't filter to coherent groups: A/B/C are rotating heat groups (the same driver runs in all three), and "Heat"/"Final A"/etc. are per-session ELO-tier definitions, not driver categories. Clicking any of them produced a partial standings list that looked like results were missing. The filter is now smart enough to detect both cases — for CCK-style meetings only the combined "All" view is shown; for true category meetings (S1/S2/S3) the All / S1 / S2 / S3 filter still works as before.
v0.17.6 — April 22, 2026
Bug Fixes
- Co-organizers can now manage meetings they didn't create — If you were added as a co-organizer of an organization but someone else on your team had originally created a meeting, you were silently blocked from actually managing it: the "Edit" button appeared, but opening the results page showed "Access Denied," clicking "Save" on logo/title edits did nothing, and creating a new championship meeting threw an error (even though the meeting was created anyway). All three symptoms shared the same root cause — the app was checking who individually created the meeting instead of who is listed on the organization. Any co-organizer listed in your organization's organizers list can now edit meeting details, save results, and add meetings to championships.
- Guided tour for Create Meeting is reachable again — Organizers who had previously seen or skipped the meeting-form tour couldn't replay it: the "?" icon inside the form only opened a static help page, and the navbar tutorial menu hid the "Meeting Form Guide" option unless you were on an
/admin route (but the Create Meeting form actually opens from the Meetings page). A new "Guided tour" button is now visible in the Create Meeting form header next to the help icon, and the navbar tutorial menu now shows both the App Tour and Meeting Form Guide options to any organizer or admin, from anywhere in the app.
v0.17.5 — April 20, 2026
Bug Fixes
- Meeting standings now split by category — On category-based meetings (S1/S2/S3), the standings tab was showing every driver in one mixed ranking, so a S1 driver's points were compared against S2 and S3 drivers who race completely different heats. Standings now show a category filter bar (All / S1 / S2 / S3) and default to the first category, matching how championship standings already work. Legacy meetings without categories keep the combined view.
v0.17.4 — April 16, 2026
Bug Fixes
- Team principal can now see join requests and all pending invites — Non-admin team principals couldn't see any join requests (the list was always empty). Invites sent by other admins were also invisible. Both are now visible to the team principal on the Manage tab.
v0.17.3 — April 14, 2026
Bug Fixes
- Team owners can invite drivers again — Non-admin team principals were getting a "Missing or insufficient permissions" error when trying to invite drivers. The Firestore query used to detect duplicate invites was missing the
invitedBy filter that security rules require, so every invite attempt was rejected before it could even be sent. Pending invites also silently failed to load for the same reason. Both queries now pass the filter, so team owners can send invites and see their pending list normally.
v0.17.2 — March 31, 2026
Bug Fixes
- Meeting standings — Removed the group filter from meeting standings. Since drivers rotate between groups across heats, filtering by group showed incomplete results. Standings now always show the combined view.
v0.17.1 — March 25, 2026
Bug Fixes
- CCK España race results — Fixed a crash when viewing or editing CCK race results caused by an incompatible point system format from the import scripts
- Team page readability — Teams with light primary colors (yellow, white, etc.) now have properly contrasting text on buttons, badges, and tabs. No more invisible text!
- Organization page readability — Same contrast fix applied to organization pages
- Team create/edit error — Fixed "Unsupported field value: undefined" error when creating or editing a team without filling in all optional fields (like description)
- Admin access to race management — Fixed a timing issue where admins would briefly see "Only organizers can manage race results" before auth loaded
v0.17.0 — March 13, 2026
Interactive Tutorials
First time using Superpole? A guided tour now walks you through the app — meetings, rankings, challenges, your garage, and championships. The tour starts automatically on your first login with a spotlight overlay highlighting each feature.
Organizers get a separate 17-step tour when creating their first meeting, explaining every form field in detail — from race scheduling to ELO categories.
Tap the (?) button in the bottom-right corner anytime to replay the tour.
Training Sessions UX
- Filter training sessions by availability, date, or search for a specific driver
- See who's booked in collapsible participant lists with profile links and ELO sorting
- Manage tab now has driver search and profile links for both races and training sections
v0.16.0 — March 13, 2026
Training Sessions
Meetings now support training sessions that drivers can book!
- Organizers can add training sessions when creating or editing a meeting — each with its own date, time, duration, capacity, and comment badge
- Registered drivers can book sessions directly from the Overview or Training tab
- When a session is full, drivers can join a waitlist — first in line gets auto-promoted when a spot opens
- Training sessions appear in the meeting schedule timeline with orange color coding
- Organizers can manage bookings from the Manage tab (remove drivers, promote from waitlist)
Comment Badges
Races and training sessions now support a comment badge — a free-text label like "Normal", "Reverse", or "Track C" that appears as a purple pill next to the name in schedule and race cards.
v0.15.1 — March 12, 2026
Challenge Admin Filters
The Match Race tab in the admin panel now has proper filters: filter by kart, driver, and date range with a calendar picker. Only options from existing challenges are shown.
CCK España Finals Migration
Final A is now split into two 10-minute races (R1 + R2), both awarding points. Finals B and C have updated point systems matching CCK rules (B: 42→13 pts across 30 positions, C: 11→1 pts across 11 positions) and now include a qualifying lap. Migration script included at scripts/migrate-cck-finals.js.
v0.13.1 — February 27, 2026
Serialization & Performance Fix
Fixed a crash on championship and meeting detail pages caused by raw Firestore Timestamp objects leaking into client components. A new recursive serializer now automatically converts all Timestamps (including nested ones like schedule slot times) at the data-access layer, so every page receives clean, serializable data.
Batch Firestore queries (used for fetching tracks, races, users, and ghost drivers) now run in parallel instead of sequentially, significantly improving load times on pages with many related documents.
v0.15.0 — March 8, 2026
Admin Driver Registration
Organizers and admins can now add drivers to a meeting directly from the Manage tab. Search for registered users or existing ghost drivers by name, or create a new ghost driver on the spot. Added drivers are automatically registered for all races in the meeting. You can also remove drivers with one click. The driver list is collapsible to keep the manage tab clean.
Driver Name & Category Normalization
Driver names in the meeting participants tab are now properly title-cased (e.g., "TOMAS SEMPERE" → "Tomas Sempere"). Category badges now show S1/S2/S3 matching the rankings page, replacing the old ELO-based labels.
Cascading Finals Point System
For events with multiple finals (A, B, C), points can now be assigned based on overall position across all finals. The last driver in Final A always scores higher than the first driver in Final B. Configure a single descending point curve (SSC-style template included) and the system calculates each driver's overall position automatically based on their final tier and finish position.
Finals must be uploaded in chronological order (A → B → C). The race manage page shows lock indicators, tier info, and an "Overall Position" column when cascading is active.
v0.14.1 — March 8, 2026
Multi-Day Meeting Fix
Fixed a bug where the "Multi-day meeting" checkbox would uncheck itself when interacting with the end date picker or changing the start date. The end date field would disappear, making it impossible to create multi-day events. Now the checkbox stays stable, and changing the start date automatically adjusts the end date forward instead of clearing it.
v0.15.3 — March 6, 2026
Community Drivers
Browse and search all registered drivers from the new Drivers page under Community. Filter by category (Pro/Sport/Rookie), sort by ELO, races, wins, or name, and tap any driver to see detailed stats and visit their profile. Features community-wide stats, ghost driver toggle, and full Spanish/English support.
v0.15.5 — March 6, 2026
Match Races Rebrand & Rankings Enhancement
"Challenges" have been renamed to Match Races throughout the entire app — pages, modals, notifications, admin panel, inbox, garage, profile, and landing page — in both English and Spanish.
The Rankings page now shows a new MR Wins stat for each driver, counting how many completed match races they've won. Visible in the desktop table, podium cards, and mobile expandable cards.
The Garage match race history tab now lists all participants for group match races instead of just the first opponent, with a group icon for visual distinction.
v0.14.0 — Teams
New: Racing Teams
Form your own racing team! Any driver can create a team with a unique short ID (e.g., "NEO"), custom logo, and team colors.
Team Features:
- Create teams with SVG or PNG logos, banners, and brand colors
- Organize drivers into up to 4 custom divisions (max 10 per division)
- Team Principal manages the roster: invite drivers, move between divisions, remove members
- Drivers receive team invites in their Garage inbox
Team Identity:
- Team badge and colored border on driver cards across the entire platform
- Team info displayed on driver profiles and garage pages
- Team short ID pill visible in rankings, race results, and podiums
Team Rankings:
- New Rankings view in the Teams directory
- Teams ranked by Top 5 ELO (competitive strength) and Team ELO (overall average)
- Stats: total wins, podiums, and member count
v0.16.0 — March 7, 2026
ELO System Foundation Fixes
Major fixes to the ELO calculation system:
- ELO floor of 0 — Drivers can no longer have negative ELO ratings. The floor is enforced across all calculation paths (race results, reversions, recalculations).
- Ghost drivers included in ELO — The integrity verification and recalculation scripts now include ghost drivers. Previously they were silently excluded, producing incorrect ELO calculations.
- Correct K-Factor in verification — The ELO integrity check was using K=64 instead of the production value of K=128, causing all verifications to report false mismatches.
- Race metadata — Each completed race now stores its Strength of Field (SOF) and the ELO weight that was applied, enabling future analysis and auditing.
- Category-aware initial ELO — Recalculation now uses the driver's category (S1=1500, S2=750, S3=300) instead of hardcoded 1500 for all drivers.
- SKC tiered finals — SKC finals (Oro through Silicio) now have differentiated ELO weights reflecting their skill tier: Oro=100%, Plata=60%, Bronce=45%, Zinc=30%, Magnesio=20%, Sodio=20%, Silicio=20%. Random heat groups use 80% weight since they have lower average SOF due to random draw.
- Provisional ELO — Drivers with fewer than 5 races are labeled "Provisional" (amber badge) in rankings, similar to placement matches in competitive games. A toggle lets you hide provisional drivers from the ranking list.
- Provisional K-Factor — New drivers (< 5 races) get a 1.5x K-Factor boost (K=192) so their rating converges faster — like placement matches in LoL or chess.
- Weight auto-detection — When setting up meeting categories, the system now suggests ELO weights based on group names (e.g., "Final A" → 1.0, "GRUPO 3" → 0.8, "Silver B" → 0.3). Small "Suggest" links appear next to the weight input.
- AI Rules Parser — Paste championship rules text and let AI analyze it to auto-generate category configurations with appropriate ELO weights. Available in both Create and Edit Meeting forms.
- Ghost driver default changed to Sport — Unknown ghost drivers now start at 750 ELO (Sport) instead of 1500 (Pro) for more realistic initial ratings.
- Rebalanced preset weights — SAC: Sport → 0.7, Rookie → 0.4. CCK: Semifinals → 0.7, Final C → 0.3.
- Championship format presets — When creating or editing a meeting, quick-select buttons (SAC, SKC, RSS, CCK) pre-fill the category/weight configuration for common championship formats.
- Championship results ELO fix — Championship race results now correctly include ghost drivers and apply category weight scaling in ELO calculations.
- AI Driver Evaluation — After completing 10 races, drivers are automatically evaluated by AI. The system analyzes your full race history — positions, competition quality (SOF), group difficulty weights — and assigns your definitive category (Pro, Sport, or Rookie). DNF/DNS results are treated as mechanical issues, not skill indicators. Your Garage shows the AI's justification, your strengths, and areas to improve. Disagree? Request a category change from the same page.
- Three-phase ELO journey — The Rankings help section now explains how your rating evolves: Provisional (first 4 races, faster ELO changes), Settled (races 5-9, normal K-Factor), and AI Evaluation (race 10, definitive category assignment).
- AI Evaluations admin panel — Admins can now review all AI driver evaluations from the System section. See evaluation stats, category changes, confidence scores, justifications, and flag potential errors like low confidence or category mismatches.
v0.15.4 — March 6, 2026
User Region Field & Location Filters
Drivers can now set their Region (state, province, or autonomous community) on their profile. The region auto-fills based on your city and country, and is selected from a dropdown of real subdivisions (Comunidades Autónomas for Spain, ISO 3166-2 regions for all other countries). Existing users were auto-populated via a migration script (146/168 matched).
Both the Rankings and Community Drivers pages now have Country and Region filter dropdowns, allowing you to browse drivers by location. The region filter dynamically shows only regions with drivers for the selected country.
Your Garage and public profile now show your regional ranking — see where you stand among drivers in your region (e.g., "#3 Andalucía (42 drivers)").
v0.15.2 — March 6, 2026
Challenge Fixes
- Fixed a crash when deleting a challenge (Firestore Timestamp serialization error).
- Group challenge ELO estimation now shows win/lose predictions for all participants, not just the first two.
- Winner voting in group challenges now lets you vote for any participant, showing the full ELO impact for each scenario.
- Driver tier names in challenges now match rankings (percentile-based instead of fixed thresholds).
- Group challenge position ordering — Group challenges with 3+ drivers now ask for the full finishing order (P1, P2, P3...) with live ELO preview per position.
- Admin: Resolve Challenge — Admins can manually resolve any active/disputed challenge with full position ordering for groups, applying ELO changes and notifying all participants.
- Challenge results in profile — Driver profiles now show completed challenges alongside race results in the history section, with opponent info, track, result, and ELO change.
v0.15.1 — March 5, 2026
Group Challenge Fix
Fixed a bug where joining a group challenge immediately locked it, preventing other drivers from joining. Group challenges now remain open until all slots are filled or the creator clicks the new Start Challenge button. Private group challenges also no longer auto-start until all invited participants have accepted.
v0.15.0 — March 5, 2026
Admin Analytics Upgrade
The Analytics tab now features interactive charts powered by Recharts: area charts for user growth, bar charts for race activity and ELO/age distributions, and donut charts for user lifecycle stages, gender breakdown, and race type distribution. A combined growth trends chart overlays user and race data for at-a-glance comparison.
Garage Race History Improvements
Race history in your garage now shows the circuit/location for each race. Organization branding (gradient backgrounds, colored stripes, logo borders) is now visible on race history rows. Races are always sorted most recent first.
Admin Users: Sort, Filter & Activity Tracking
The Users tab in the admin panel now includes sorting by name, registration date, last activity, ELO, or total races. A new filter panel lets you narrow down users by category (Pro/Sport/Rookie), role (Admin/Organizer/Driver), activity (active in last 30 days, inactive, or never seen), and whether they've raced or not. Each user card now displays their registration date and last seen time, so you can quickly identify inactive accounts or new sign-ups.
Bug Fixes
- Fixed organization brand colors not appearing in garage race history (wrong Firestore field path)
- Switched
lastActivity tracking to use Firestore serverTimestamp() for reliability
v0.14.0 — March 5, 2026
Challenge ELO Balancing
Challenges now award half the ELO compared to a regular race. This prevents 1v1 challenges from swinging ratings as much as a full race with multiple participants. The ELO estimation preview on challenge pages reflects the reduced values, and dispute resolutions by admins use the same 50% scaling.
Remove Participants from Challenges
Challenge creators and admins can now remove participants from a challenge before it starts. An X button appears next to each participant card on pending or accepted challenges. If the last accepted participant is removed from a 1v1, the challenge reverts to pending status. Removed participants receive a notification.
Category Rename: Pro / Sport / Rookie
Driver categories have been renamed from S1/S2/S3 to Pro/Sport/Rookie throughout the entire app. This includes rankings badges, profile pages, admin panels, meeting forms, and all translations. Existing data is unaffected — only the display names have changed.
Multi-Day Meetings
Meetings now support multi-day events. When creating or editing a meeting, check "Multi-day meeting" to add an end date. The date range is displayed throughout the app — for example, "Mar 8-10, 2026" for same-month events or "Mar 28 - Apr 2, 2026" for cross-month events. Multi-day meetings stay in the "upcoming" filter until the last day passes, and registration remains open until the end date.
Organization Edit Permission Fix
Organization creators can now immediately edit their organization after creating it. Previously, the organizers list was empty on creation, which prevented the creator from accessing the edit form. The creator is now automatically added as an organizer. Additionally, the edit button no longer briefly disappears while authentication loads.
Organizer Management Security Fix
Adding and removing organizers from an organization now happens through a secure server action instead of a direct client-side Firestore write. Previously, any authenticated user could call the add/remove functions from the browser console to grant themselves organizer privileges on any organization. Now the server verifies your identity and confirms you are already an organizer or a site admin before the change is applied.
Profile Photo Upload Fix
Uploading a helmet photo on the profile page no longer freezes the form. Previously, if the Firebase Storage upload stalled (e.g., due to a network issue), the "Saving..." button would stay disabled forever. The upload now times out after 30 seconds and shows an error message, allowing the profile to be saved without the photo. Additionally, the photo preview no longer causes a rendering crash — it now uses a standard image element that supports the local preview before the photo is uploaded.
Drag-and-Drop Race Reordering
Races in the meeting manage tab can now be reordered by dragging. Each race card has a grip handle icon (⠿) on the left — grab it with your mouse or touch-and-hold on mobile, then drag the card to the desired position. The up/down arrow buttons remain available as an alternative. Reorder changes are saved immediately to the server.
Qualifying (Qualy) Race Type
Meetings now support an optional Qualy race type. When creating or editing a meeting, you can configure qualifying sessions that appear before heats in the schedule. Qualys use orange color coding and support their own point system configuration. The number of qualys defaults to 0, so existing meetings are unaffected.
Championship Custom Points
A new Custom Points weight mode is available when editing championship meetings. Instead of using race-derived points, you can assign championship-specific points per finishing position (e.g., P1=100, P2=95, P3=92, P4=90, then -1 per position). Use the Superpole curve generator to auto-fill the standard Superpole point distribution, or manually edit any position's points. The number of positions is configurable. Custom points work correctly with category filters — when viewing S1/S2 standings, drivers are re-ranked within the category before points are assigned.
Race Point Preview
Each meeting card in the Edit Championship form now shows a collapsible preview of the meeting's configured race point system. Click "Race Points" to see the full point distribution, helping you understand what each meeting awards before configuring championship weight.
Weight Mode Explanations
Each championship weight mode now shows an info message explaining what it does:
- Default: Points used as-is from race results
- Multiplier: All points multiplied by the factor
- Fixed Max: Top driver gets the configured max, others scaled proportionally
- Custom Points: Position-based championship points replace race points
Edit Meeting Point System
When editing a meeting, organizers can now modify the point system for each race type (heats, superheats, and finals). The same PointSystemBuilder used during meeting creation is now available in the edit form, with tabbed navigation per race type. Changes to position points, qualifying scoring mode, and fastest lap points are applied to all races of that type when saving.
Garage Page Mobile Redesign
The Garage (driver profile) page has been redesigned for mobile screens. The driver card is now compact with a horizontal layout, stats are in a 4-column grid that scales gracefully, and the edit button shows as an icon on small screens. The skeleton loading state matches the new layout.
Bug Fixes
- Standings tiebreakers: When two drivers have the same total points, ties are now broken deterministically. In meeting standings, the driver with the better position in the last race wins. In championship standings, a countback of meeting scores is used — meeting results are sorted highest to lowest (including discarded meetings) and compared one by one until the tie is broken. This applies to both overall and category-filtered views.
- Ghost drivers now appear in championship standings: Ghost (guest) drivers were previously invisible in championship standings. They now appear with their full points, a purple ghost badge, and slightly dimmed styling to distinguish them from registered users. When a ghost driver is claimed, their results seamlessly merge into the claiming user's profile.
- Ghost drivers counted in meeting participants: The participant count on meeting pages now correctly includes ghost drivers who participated in races.
- Championship standings simplified: Removed the cluttered inline points breakdown (Heats/Superheats/Finals colored text) from standings rows. The main view now shows just total points, meetings, races, and best finish. The full breakdown is still available when you expand a driver's details.
- Duplicate Meeting now preserves race types: Previously, duplicating a meeting where race types had been changed (e.g., heats→qualy, superheats→heats) would recreate the original structure. Now it copies the actual races as they are — including names, types, and point systems.
- Edit Meeting syncs qualy configuration: Saving changes in the Edit Meeting form now properly updates the meeting's race configuration to reflect qualifying races and current group structure.
Improvements
- Ghost driver search: Ghost/guest drivers now appear in the unified driver search when uploading race results
- Accent-insensitive search: Driver search ignores accents (á→a, ñ→n) and case for faster organizer workflow
- Consistent driver photos: All profile photos in race results upload now render at uniform sizes
- Post-save redirect: Saving race results keeps you on the manage tab instead of redirecting to overview
- Per-category scaling fix: When filtering championship standings by category, maxPoints scaling is applied per category so the top driver in each category gets the full configured points
- Ghost drivers in standings: Meeting standings now correctly display ghost driver names and ELO
- Category auto-selection: Championship standings category filter auto-selects the first available group
- Image upload hints: Standardized dimension recommendations across organization and championship forms
v0.13.0 — February 6, 2026
Championship Management Improvements
Advanced Qualifying Scoring
Organizers can now choose between two qualifying scoring modes when configuring point systems:
- Pole Only — Awards a flat bonus to the pole position driver (existing behavior)
- Full Distribution — Awards points to multiple qualifying positions, just like race scoring. Configure individual points per position using the same grid, presets, and bulk input tools available for race points.
When using Full Distribution mode, the results manager shows a "Q Pos" numeric input instead of a simple Pole checkbox, allowing organizers to enter each driver's qualifying position.
Duplicate Meeting
A new Duplicate Meeting button appears in the manage tab. It creates a complete copy of the meeting with the same configuration (track, race structure, point systems, categories, schedule slots, rules) but with a fresh set of races and no participants or results. The date resets to today and "(Copy)" is appended to the name. Championship-linked meetings are automatically added to the championship.
Clone Meeting Configuration
When creating a new meeting, a "Clone config from" dropdown appears at the top of the form. Select any existing meeting to instantly pre-fill the race configuration (heats, superheats, finals, point systems), categories, track, organization, schedule slots, and other settings. Name, date, and description are left blank so you can customize the new meeting.
Race Reordering
Races in the manage tab now have up/down arrow buttons to change their display order. The order is saved to Firestore and persists across page loads.
Auto-Complete Meeting Status
Meeting status now updates automatically:
- When all races in a meeting have results uploaded, the meeting is marked as Completed
- When the first result is uploaded, the meeting moves to In Progress
- Past meetings without results now show Past instead of "Scheduled"
Bug Fix: Circuit Selection
Fixed a bug where opening the "Create New Track" modal inside the "Create Championship" form would accidentally close the championship form. The track modal now properly captures clicks without propagating to the parent.
Analytics
Rental World Ranking now tracks user behavior via Firebase Analytics (powered by Google Analytics). This runs automatically in the background — no action needed from users.
What's Tracked
- Page views — every navigation between pages is logged
- Session duration — how long users spend on the site
- User engagement — active time and scroll depth
- Demographics — country, language, device, browser, OS
- Traffic sources — where users come from (referrer, UTM params)
- Returning vs new users
All data is viewable in the Firebase Console → Analytics dashboard.
Zero-Flash Navigation & Animation Optimization
All Page Flash Eliminated
Pages no longer flash briefly when loading or navigating. Entrance animations that caused content to appear invisible then fade in have been removed from all 7 affected pages: profile, garage, rankings, organizations, login, championships, and meetings.
Animations are now only used where they add value — modals, expandable rows, and scroll-triggered reveals. Navigation is handled by the View Transitions API for smooth, instant page loads.
Spinner-Free Loading
All remaining spinner loading indicators have been replaced with skeleton layouts that match the actual page structure:
- Public profile — skeleton now matches the hero gradient, large avatar, stats grid, and race history
- Organization detail — skeleton matches the banner, header card, tabs, and content grid
- Garage — Suspense fallback now shows a proper skeleton instead of a spinner
- Rankings — podium skeleton positioning fixed to match actual card layout
Tab Content No Longer Flashes
Switching tabs on the garage, organization, and meeting pages no longer causes the content to briefly disappear and fade back in.
Mobile Performance & UX Improvements
Page Flash Fixed
Navigating between pages no longer causes a brief flash/flicker effect, especially on mobile devices. The issue was caused by CSS transitions firing on hundreds of elements simultaneously during page transitions.
Mobile Layout Overflow Fixed
Several pages had elements extending beyond the screen edge on mobile, requiring horizontal scrolling:
- Championship standings now display as compact cards on mobile instead of a wide table
- Meeting participants now display as compact cards on mobile
- Tab bars across all pages now fit properly on small screens
- Race detail headers now wrap correctly on narrow screens
Skeleton Loading
Loading states across race detail, garage, and profile pages now show skeleton layouts instead of spinners, providing a more polished experience that matches the page structure.
Custom Schedule Slots
Organizers can now add custom time slots to the meeting schedule alongside races. Use this for activities like:
- Briefing — pre-race driver briefing
- Payment Collection — registration and payment
- Track Walk — guided track walk before racing
How to use
- Go to Create Meeting or Edit Meeting
- Scroll to the Race Schedule section
- Click "Add Custom Slot" (purple button)
- Enter a name, time, and optional duration
- Reorder slots with the up/down arrows — they sit right alongside races
- Auto-fill only affects race times; custom slots keep their manual times
Custom slots appear on the meeting's Schedule tab as purple-styled timeline entries (not clickable, since they aren't races).
Latest Fixes
Meeting Auto-fill Times Fixed
The "Auto-fill" feature when creating a new meeting now correctly treats the "First Race Start" time as the start time (not the pre-grid time). Setting 09:00 will now produce:
- Race 1: Pre-grid 08:55, Start 09:00
- Race 2: Pre-grid 09:10, Start 09:15
Previously it was incorrectly generating 20-minute gaps with the start time offset by 5 minutes.
Race Schedule Improvements
- Group labels: Each race in the schedule now shows its group/category (S1, S2, S3)
- Reorder races: Use the up/down arrows to change race order in the schedule
- Always visible: The Race Schedule section is now always shown, with a helpful message when no races are configured yet
ELO Categories in Edit Meeting
You can now edit the ELO Category System (S1/S2/S3 weights) when editing an existing meeting. Previously this was only available when creating a new meeting.
S3 ELO Weight Fix
Fixed a bug where S3 races were giving full ELO impact instead of the intended 20%. This affected meetings created before the categories feature was added. S3 drivers will now correctly receive scaled ELO changes (e.g., ~13 points instead of ~67 for a P1 finish).
Admin Profile Links
User names in admin tabs are now clickable and link to driver profiles:
- Category Change Requests: Click on a user's name to view their profile
- Ghost Claims: Click on the requesting user or linked user to view their profile
- Hover shows a visual highlight and external link icon
DANGER Mode ELO Fix
Fixed a bug in the admin ELO recalculation "DANGER mode" where manual category overrides could result in negative ELO values:
- When you override a user's original category, any approved category changes from the database are now correctly skipped
- This prevents double ELO adjustments that previously caused incorrect calculations
Rankings Podium Layout Fix
The top 3 driver cards on the rankings page now display correctly:
- All three podium cards are the same size
- 1st place is positioned highest, 2nd place in the middle, 3rd place lowest
- Previously, the 1st place card was scaled larger than the others, causing visual inconsistency
Version 0.12.0 - Rebrand & Improved Search
Release Date: February 5, 2026
Welcome to Rental World Ranking! This release includes a complete rebrand and improved search functionality for Spanish-speaking users.
New Brand Identity
The platform has been renamed from Superpole to Rental World Ranking. The new icon features a racing flag with ranking bars inside, symbolizing both the motorsport focus and the ranking system.
Accent-Insensitive Search
Search now handles Spanish accented characters intelligently:
- García can be found by searching "garcia"
- José can be found by searching "jose"
- Muñoz can be found by searching "munoz"
This applies to all search fields across the app: rankings, organizations, meetings, championships, challenges, and admin panels.
Other Changes
- Simplified navbar with single icon logo
- Updated all page titles and metadata
- Removed old Superpole assets
Version 0.11.0 - Category Filtering & Light Theme Fixes
Release Date: February 4, 2026
Championship standings can now be filtered by driver category (S1/S2/S3), and major light theme readability issues have been resolved across the app.
Championship Category Filter
Championship standings now support category filtering when meetings use the ELO Category System.
How it works:
- If any meeting in the championship has categories configured (e.g., S1, S2, S3), filter buttons appear above the standings table
- Click a category to see only drivers who raced in that category
- Points, positions, wins, and podiums are recalculated for the filtered view
- The "All" button shows the original combined standings
Filter buttons are styled with the championship's brand colors.
Light Theme Fixes
Comprehensive fix for readability issues in light mode:
- Championship detail page: All card borders, section dividers, and table separators are now visible (previously white-on-white)
- Status badges: "Upcoming" and "Active" badges now readable in both themes
- Registration buttons: Register/unregister text now visible in light mode
- Category badges in rankings: S1/S2/S3 badges adapt colors between light and dark themes
Other Changes
- S1 category and Profesional ELO tier color updated from gold to red
- New reusable image components (
UserProfileImage, StandardImage, HeroBanner) used across the app
- Profile photo rendering simplified with consistent fallbacks
Version 0.10.0 - Championship Branding
Release Date: February 4, 2026
Championships now support organization brand colors and custom color themes, plus social links in the header.
Championship Branding
Championships can now display your organization's brand colors throughout the page, or you can set custom colors per championship.
Color priority:
- Custom championship colors (if set)
- Organization brand colors (if "Use organization colors" is enabled)
- Default Superpole blue
Where colors appear:
- Header gradient and border
- Tab bar active state
- Stat card icons
- Action buttons and links
- Standings accent colors
How to set colors:
- Go to your championship's Edit form
- Toggle "Use organization colors" to inherit from your org
- Or set custom Primary and Secondary colors using the color pickers
- Custom colors always take priority over org colors
Social Links in Championship Header
Championship pages now show the organization's social links (website, Instagram, email, WhatsApp, and custom links) directly in the header, so visitors can find your org easily.
Challenges Admin Cleanup
Admins can now filter and bulk-delete expired challenges (past date, never accepted). The expired tab keeps the active challenge list clean.
Organizers Can Create Championships
Organizers can now create championships directly from the Championships page - no longer restricted to the admin panel. Championship cards also show banner/logo imagery.
Bug Fixes
- Fixed untranslated English text on championship pages when using Spanish
- Fixed ghost driver name/ELO resolution in race management
- Organization page "Members"/"Meetings" labels now properly translated
Version 0.9.0 - The International Update
Release Date: January 30, 2026
This release brings Superpole to a global audience with full multilingual support, a new feedback system, and a beautiful light/dark theme toggle!
New in 0.9.0
Multilingual Support 🌍
Speak your language
Superpole now supports both Spanish (default) and English! Switch between languages instantly from the navbar.
How to change language:
- Click the language toggle in the navbar (shows "ES" or "EN" with a flag)
- The entire interface switches immediately
- Your preference is saved for next time
What's translated:
- All page titles and subtitles
- Navigation and menus
- Forms and buttons
- Status messages and badges
- Dates (localized formatting)
- Error messages
- Admin dashboard
We're working on adding more languages! Let us know which language you'd like to see next.
Feedback System 💬
Your voice matters
Found a bug? Have a feature idea? Now you can tell us directly from the app!
How to send feedback:
- Click the speech bubble icon (bottom-right of any page)
- Select a category: Bug, Feature Request, or Other
- Write your message
- Click Send Feedback
What happens next:
- Your feedback goes directly to the admin team
- Admins can respond to your feedback
- Check the notification bell for responses
We read every piece of feedback. Thank you for helping us improve Superpole!
Light & Dark Theme 🌓
Easy on your eyes
Choose between a sleek dark mode (default) or a bright light mode. Perfect for racing in any lighting condition!
How to switch themes:
- Click the sun/moon icon in the navbar
- The theme changes instantly
- Your preference is saved automatically
Theme features:
- Smooth transitions between modes
- Optimized colors for readability
- Racing badges and categories visible in both themes
- No flash when loading the page
Previous Features (0.8.0)
Version 0.8.0 - The Competitive Update
Release Date: January 30, 2026
We're excited to announce our biggest update yet! This release introduces a comprehensive competitive racing ecosystem with ELO rankings, driver challenges, ghost profile recovery, and much more.
New Features
Ghost Driver Claims
Recover your racing history
Did you race at events before creating your Superpole account? Your results were saved under a "ghost" profile, and now you can claim them!
How it works:
- Go to My Garage and open the Claim Ghost tab
- Make sure your profile is complete (name and ID/Passport required)
- Search for your ghost driver profile by the name you used at events
- Click "Claim This Driver" and optionally provide proof (race dates, events attended)
- Submit your claim for admin review
- Once approved, all your historical stats are transferred to your account!
What gets transferred:
- All past race results
- Your earned ELO rating
- Win count and podium finishes
- Total races completed
This is a one-time claim process. Once your ghost profile is merged, your complete racing history will be visible in your Garage.
ELO Rating System
Fair, skill-based rankings for all drivers
Superpole now features a comprehensive ELO rating system inspired by iRacing and chess ratings. Every race you complete updates your rating based on your performance against competitors.
Driver Categories
| Category | Starting ELO | Description |
|----------|--------------|-------------|
| S1 (PRO) | 1500 | Experienced, competitive drivers |
| S2 (Intermediate) | 750 | Regular racers with solid skills |
| S3 (Rookie) | 300 | New drivers learning the ropes |
How ELO works:
- Beat higher-rated drivers = gain more points
- Lose to lower-rated drivers = lose more points
- Every race is a chance to climb the rankings
- K-Factor of 128 ensures responsive rating changes
Ranking Tiers
Your ELO places you in a tier that appears on your profile:
| Tier | Rank | Color |
|------|------|-------|
| Professional | Top 2% | Gold |
| Semi-pro | Top 7% | Orange |
| Cool Driver | Top 15% | Purple |
| Driver | Top 30% | Blue |
| Cool Racer | Top 50% | Cyan |
| Racer | Top 70% | Green |
| Cool Rookie | Top 85% | Violet |
| Rookie | Bottom 15% | Gray |
Category Change Requests
Need to switch categories? Request a change from your Garage:
- Go to My Garage → Category tab
- Select your new category
- Provide a reason for the change (optional)
- Submit for admin approval
Note: Moving to an easier category may reduce your ELO. Moving to a harder category may increase it.
Challenge System
Race on your own schedule
Challenges let you compete against other drivers anytime, anywhere. No need to wait for official events to earn ELO!
Challenge Types
| Type | Participants | Heats | Best For |
|------|-------------|-------|----------|
| 1v1 | 2 drivers | 2 | Quick head-to-head battles |
| Group | 2-5 drivers | 3 | Friends/team competitions |
Creating a Challenge:
- Click "Create Challenge" from the Challenges page
- Choose type: 1v1 or Group
- Set access: Public (anyone can join) or Private (invite only)
- Select race type: Time Attack (fastest lap wins)
- Enter your weight (driver + ballast)
- Choose a track from the list
- Pick a date (weekdays only) and time
- For private challenges, search and invite your opponents
- Submit!
Race Day:
- Complete your heats at the scheduled time and track
- Report results with screenshot evidence
- Your opponent confirms the result
- Once all heats are confirmed, ELO updates automatically!
Challenge Statuses:
- Pending - Waiting for opponent acceptance
- Accepted - Ready to race
- In Progress - Heats being completed
- Completed - All done, ELO updated
- Disputed - Result contested, under admin review
Can't find your track? Use the "Track not listed?" link to request a new track be added!
My Garage
Your personal racing headquarters
The Garage is your central hub for everything related to your racing career.
Tabs:
| Tab | What's Here |
|-----|-------------|
| Overview | Quick stats, recent races, ELO tier badge |
| Race History | All your completed races with positions, points, and ELO changes |
| Challenges | Your challenge record: wins, active challenges, history |
| Claim Ghost | Search and claim historical ghost driver profiles |
| Category | View/request category changes |
Quick Actions from Garage:
- Edit your profile
- View all challenges
- Claim ghost drivers
- Request category change
- See your complete race history
Organizations & Driver Codes
Join your racing community
Organizations represent karting clubs, racing teams, and karting circuits. When you join an organization, you receive an official Driver Code!
Driver Code Format:
[Country]-[Org]-[Number]
Example: ES-SPK-4829
- Country: Your 2-letter country code (ES, US, FR, etc.)
- Org: Organization's unique prefix (2-5 letters)
- Number: Your unique 4-digit identifier
How to get your Driver Code:
- Go to your Profile settings
- Select an organization from the dropdown
- Save your profile
- Your Driver Code is automatically generated!
Where it appears:
- Your profile page
- Race results
- Challenge cards
- Organization member lists
Organization Features:
- Custom branding with logo and colors
- Member management
- Meeting and event creation
- Championship organization
Quality of Life Improvements
Mobile Experience
- Better filter navigation: Filter bars now use dropdowns on mobile instead of horizontal scrolling
- Responsive challenge cards: 1v1 displays stack properly on small screens
- Touch-friendly buttons: All interactive elements are at least 44x44px
- Improved admin panel: Tab navigation with grouped sections and mobile dropdown
Admin Panel Improvements
- Organized tabs: Sections for Overview, Content, Requests, and System
- Track Requests: New tab to review and approve user-submitted tracks
- Badge notifications: Pending request counts shown on tabs
- Mobile dropdown: Easy navigation on all devices
Profile Enhancements
- Helmet photo upload: Add your helmet photo for identification
- Complete profile validation: Clear requirements for all fields
- Organization selection: Join clubs directly from your profile
- Weight tracking: Track your race weight (equipment auto-calculated)
Technical Details
ELO Configuration
| Setting | Value |
|---------|-------|
| K-Factor | 128 |
| Initial Rating (S1) | 1500 |
| Initial Rating (S2) | 750 |
| Initial Rating (S3) | 300 |
| Rating Floor | None |
| Rating Ceiling | None |
Challenge Rules
| Rule | Value |
|------|-------|
| 1v1 Heats | 2 |
| Group Heats | 3 |
| Max Group Size | 5 drivers |
| Scheduling | Weekdays only (Mon-Fri) |
| Evidence | Screenshot required per heat |
Category ELO Adjustments
| From | To | Adjustment |
|------|-----|------------|
| S3 | S2 | +450 |
| S3 | S1 | +1200 |
| S2 | S1 | +750 |
| S2 | S3 | -450 |
| S1 | S2 | -750 |
| S1 | S3 | -1200 |
Getting Started
New Users
- Create your account and complete your profile
- Select your starting category (S3 recommended for beginners)
- Join your local organization for a Driver Code
- Start racing at events or create challenges!
Returning Users
- Check the Claim Ghost tab if you raced before signing up
- Review your category and request a change if needed
- Explore the new Challenges feature
- Update your profile with helmet photo and organization
What's Next?
We're constantly working to improve Superpole. Here's what's planned for upcoming releases:
Coming in 0.10.0
- Position-based challenges: Race for position, not just time
- More languages: Portuguese, Italian, French
- Improved notifications: Real-time challenge updates
Planned for 1.0.0 (Stable Release)
- Championship challenges: Multi-round challenge series
- Team challenges: Organization vs. organization competitions
- Mobile app: Native iOS and Android applications
- Complete test coverage: Ensuring reliability
- Performance audit: Optimizing for all devices
Alpha Notice
Superpole is currently in alpha (version 0.x.x). This means:
- Features are still being developed and tested
- Some functionality may change between versions
- We appreciate your feedback to help shape the product
- Data is preserved, but backup your important information
Feedback
Found a bug? Have a suggestion? We want to hear from you!
- Report issues: Contact your organization admin or reach out directly
- Feature requests: Let us know what would make Superpole better for you
- General feedback: We read every message!
Thank you for being an early adopter of Superpole. Your feedback during this alpha phase is invaluable. See you on track!
Version 0.9.0 | Last Updated: January 30, 2026