Every route in apps/kaki-v2 today, redrawn in the direction the owner liked: iOS grey or true-black ground, white cards, the icon’s three colours with one job each (green = act, red = live / needs you now, gold = only the tile’s edge), ivory tiles as the illustration language, Archivo + Archivo Black, codes in Space Mono, kanji in the system CJK face. The White Dragon is a blank tile. Copy is Indonesian by default; notes for the owner are in English.
Each phone is labelled with its real route. Screens scroll inside the frame. Things that work: the floating glass tab bar (tap a tab), segmented controls and entity tabs, the date strip and :30 slots, the steppers, seat and table pickers, taking a seat on Cari Kaki, the voucher field, the pay countdown, toggles, and the state switches above some phones. Light and dark follow your system; the switch at the top pins either. Home, the score table and the pay screen are also shown pinned dark.
Beranda, Main, Komunitas, Pesan, Kamu. No tab is ever hidden (the native tab bar throws if one is), so a signed-out guest gets the AccountTabGate on Komunitas, Pesan and Kamu instead of a missing tab. The bar is the floating glass one from the reference: tap any tab on any phone below and that phone switches to the tab. Home opens on your night (the liked live card), then “Minggu ini”. There is no “Butuh kaki keempat” rail on Home.
iOS Home ScreenWidget + Dynamic IslandThe icon is unchanged. The widget shows tonight’s table as the same wind tiles as the Home live card; the island counts down to the start.
Meja 348 mnt/ · (tabs)/indexBeranda, with a booking tonightThe liked live card on top (countdown, four wind seats, the empty one asking to be filled), then Minggu ini, nearby venues, tournaments, clubs, the score tracker and coaching (coming soon). City chip opens the city picker; the bell works for guests too./ · darkBeranda, dark GelapSame screen pinned dark: true black ground, #1C1C1E cards; the tiles keep their ivory face because they are physical objects./ · guest, no bookingBeranda for a guestSigned out and nothing booked: the live card becomes an invitation. Coming-soon venues are grey, can’t be tapped and show no price. “Masuk” replaces the avatar.3 meja di Bandung masih butuh kaki. Atau pesan meja sendiri, tanpa akun.
/play · (tabs)/playMainFive actions: Cari Kaki (the big one), Pesan meja, Buka meja (guest gate), Event, Pencatat skor. Below: search, open-table filter chips (shared with Cari Kaki) and today’s calendar with collapsible empty hours./community · (tabs)/communityKomunitasEntity tabs Teman · Klub · Peringkat · Game saya (they work). Each panel fetches only when shown. Klub has the “Buat klub” button; Peringkat has the medal tiles and your row tinted.Cara kerja papan peringkat · Game yang belum selesai tetap dihitung.
/community · AccountTabGateKomunitas, signed outThe tab stays; it says what it is for and offers one Sign in button. No signed-in query runs (the old 401 on friend requests).Masuk untuk menambah teman, gabung klub, dan melihat posisimu di papan peringkat.
/messages · (tabs)/messagesPesanConversations with venues, friends, clubs, event rooms and open-table chats. Live over the chat socket; pull to refresh. Unread rows carry the red square./messages · AccountTabGatePesan, signed outSame gate, different reason.Masuk untuk mengirim pesan ke tempat, teman, klub, dan meja yang kamu ikuti.
/you · (tabs)/youKamuThe liked “stats you want to show off”, then everything that is yours: requests (the only way to reach /requests), stats, bookings, clubs ordered owned → admin → member, events, tournaments, and messaging a venue. Tap the photo to change it.Terakhir: Chiitoitsu di Tenpai Addicts, Sabtu.
/you · AccountTabGateKamu, signed outA guest who booked without an account still finds their bookings: “Pesanan di perangkat ini” links to the on-device list.Masuk untuk menyimpan game, melihat statistik, dan mengumpulkan yaku.
+not-found404A themed dead end with one way back.Tautannya mungkin sudah lama atau salah ketik. Tidak ada yang hilang dari akunmu.
The flow Apple already approved, kept in the same steps and redrawn: venue list → schedule (date strip, the server’s own start times including :30) → duration (stepper, whole table or per seat, table picker) → review with guest checkout (name and email only) → held for 15 minutes with the voucher field → QRIS. The app never computes money: every price, fee and total is the server’s figure. Past-midnight starts belong to the trading night, and the closing time is the last START.
/booking · booking/indexVenue listVenues in the current city, searched within that city only. Coming-soon venues are grey, can’t be tapped and show no price. Half price Mon–Thu is a small red ½ on the price, not a paragraph.Pilih tempat, lalu jam mulai. Tanpa akun juga bisa.
/booking · statesVenue list: empty, error, loadingEmpty city links to the city picker; a failed load shows the offline tile with Retry; loading is a skeleton, never a blank page.Tempat baru sedang kami siapkan. Coba kota lain untuk malam ini.
Sepertinya koneksimu terputus. Pesananmu yang lama tetap aman.
/booking/[slug] · schedulePick a day and a startThe liked “room with felt in it”, as the booking page: date strip, table-type chips, and the server’s start times (steps of 30 min) in a grid. Sold slots are struck through; ½ marks half price. Tap a day or a slot. Peringkat is the second tab.23:00 adalah jam mulai terakhir. Jam lewat tengah malam ikut malam sebelumnya.
/booking/[slug]/durationHow long, how many, which tableBig hours stepper, whole table vs per seat (mode cards), seat count, and the table picker as numbered tiles (taken ones greyed). All work. The price line is the server’s quote for this span.Mulai 19:00 · ½ harga hari ini
/booking/[slug]/duration · :30 + unavailableHalf-hour start, and “can’t buy this”At a :30 start there is no table picker (the venue seats you). When the span is gone, the one Unavailable card replaces the form with a way back.Mulai 19:30 · ½ harga hari ini
Untuk jam mulai :30, tempat yang memilihkan meja saat kamu datang.
Seseorang memesan 19:30 sebelum kamu. Belum ada yang dibayar.
/booking/[slug]/confirm · guestReview, with guest checkoutName and email only; no account needed. This screen creates the booking hold and stops; it does not pay. The guest purchase is saved on this device so Pesananku can list it.Tanpa akun. Kami kirim kode pesanan ke email ini dan menyimpannya di perangkat ini.
Punya akun Kaki? Pesanan tersimpan otomatis.
/booking/[slug]/confirm · signed in + refusalSigned in, and a refusalFor a member the email is locked. If the server refuses (slot taken, not enough seats, no table), a toast says so in plain words and the button re-validates.Email akunmu. Ubah di Pengaturan.
/booking/[slug]/heldHeld for 15 minutesA live-card countdown, the itemised total from the server, and the voucher field (type KAKI10 and tap Pakai). Pay opens exactly one QR session; a retry shows the same QR again.Punya kode? Masukkan sebelum bayar.
Harga dan total dari server. Biaya QRIS ditunjukkan di langkah berikutnya.
/booking/[slug]/held · voucher refusalsEvery voucher refusalThe eight server refusals from lib/promo-refusal, each one sentence, under the field. Pick one above the phone.Kode voucher tidak dikenal atau sudah dipakai.
One pay screen for every kind (booking, tournament, seat, event, lesson). The fee step names the QRIS fee in rupiah (never a percentage). The pending screen polls every second and re-checks when the app returns to the front. Four endings: paid, expired (server-confirmed, the only place that may say nothing was charged), unverified timeout (the local clock ran out while the last check failed, so it never says “nothing charged” and tells you not to pay twice) and failed. The payment provider is only ever “gateway pembayaran”.
/pay/methodFee step: QRIS onlyStates the consumer fee in rupiah from the server’s figures, then continues to the one QR. Going back to the pay screen reuses the session; it never opens a second one.Satu QR untuk semua aplikasi bank dan e-wallet.
Biaya QRIS ditarik oleh gateway pembayaran dan sudah termasuk di total. Tidak ada kartu kredit di aplikasi.
/pay/[paymentId] · pendingThe QR, counting downThe code to scan, the exact amount, and a live countdown. Checks every second; “Cek lagi” forces one. Save QR for paying from another phone./pay/[paymentId] · darkThe QR, dark GelapThe QR keeps its white quiet zone in dark mode so every scanner reads it./pay/[paymentId] · paidPaidAlso shown when the server answers already_paid. Where you land next depends on who paid (member → Pesananku; guest → the ticket by code).Rp 55.080 lewat QRIS. Tiketmu sudah siap dan dikirim ke email.
/pay/[paymentId] · expiredExpired (server-confirmed)Only when the server confirms expiry (or the clock ran out while the last check still said pending) may the screen say nothing was charged. A new QR is offered only when allowed.Tidak ada uang yang terpotong. Kamu bisa buat QR baru untuk pesanan yang sama.
/pay/[paymentId] · unverified timeoutCan’t confirm yetThe countdown ended but the last check failed (offline). Money may have moved, so the screen never says “nothing charged”: it says don’t pay twice and keeps checking.Waktu QR habis saat koneksimu terputus. Kalau kamu sudah membayar, uangmu aman: pesananmu akan tercatat begitu kami tersambung lagi.
Cek riwayat di aplikasi bank atau e-wallet-mu dulu sebelum membuat QR baru.
/pay/[paymentId] · failedFailedThe mapped failures, each one sentence: the gateway couldn’t make a QR, too many tries, offline, or the rail is not live. Retry opens a new session only when allowed.Gateway pembayaran sedang bermasalah. Belum ada QR, jadi belum ada yang dibayar.
Tunggu sebentar, lalu coba lagi. Mejamu masih ditahan.
Sambungkan lagi, lalu coba. Kalau kamu sudah scan, jangan bayar dua kali.
Tempat ini belum menerima pembayaran lewat aplikasi. Bayar di kasir saat datang.
/pay/confirmedA ticket, not a receiptThe liked ticket, re-read from the code alone so a guest with nothing else still has it. The code is shown exactly as issued (case-sensitive, never uppercased). Refund or cancel status appears as one line on the ticket.Kami kirim pengingat 1 jam sebelumnya.
Members see their account’s bookings; guests see the bookings saved on this device (no request carries a credential). Only live reservations can be acted on: show QR, reschedule (half-hour slots and table picker, sheet capped at 85%), cancel with no refund, add house players to an event booking, or pay a booking still waiting.
/my-bookings · memberPesanankuTonight on top with the live chip. Each card shows its code in Space Mono. Past bookings carry their status pill (selesai, dibatalkan, refund)./my-bookings · guest deviceBookings on this deviceA guest sees what they bought on this phone, read from the code alone. Signing in saves them to an account.Dibuat tanpa akun di HP ini. Kodenya juga ada di emailmu.
Masuk dengan email yang sama supaya pesanan ini ikut di akunmu dan bisa dijadwal ulang.
/my-bookings · BookingQRShow QRA sheet with the check-in QR and the code, big enough to read across a counter./my-bookings · reschedule sheetRescheduleHalf-hour slots for the chosen day and a table picker, in a sheet capped at 85%. The length stays the same; the server re-prices if needed and says so before moving./my-bookings · cancel confirmCancel, no refundA plain confirm that says the money is not returned before the destructive button (dragon-strong, white text).Meja 2 malam ini 19:00 akan dilepas untuk orang lain. Pembatalan ini tidak mendapat refund.
/my-bookings · house player modalAdd house playersFor an event booking: a stepper up to the event’s maximum, the per-player price from the server, then straight to pay.Kurang orang? Tempat menyediakan pemain untuk melengkapi mejamu.
The board uses the C2/D cards the owner liked (switch between the tile strip and the plain green block above the phone). Tap an empty face to sit; tap yourself to stand up. The seat detail opens with option A’s tile row: the four winds as tiles, the empty seat dashed, tap it to choose your wind. Every fill state from lib/open-tables-api is drawn: open (backed / not yet backed), pay window with its countdown (and extended), confirmed, and the terminal ones: cancelled with refund, lapsed, bumped, completed. Joining needs an account or the guest sheet (Apple 1.0(11)).
/cari-kakiThe boardTonight / tomorrow / weekend, filter chips shared with the Main tab, then one compact card per table. “1 lagi” turns red: that table is one seat from full. The Buka meja button floats above the home indicator (offset, not padding) and is behind the guest gate./seat/[id] · DetailSeat detail, openOption A’s tile row on top: tap the dashed seat to take that wind, then “Minta gabung”. Tabs Detail · Pemain · Chat work. The chip says whether the host has already booked the table (backed) or not yet.Kursi pemain rumah (instruktur) selalu gratis.
/seat/[id] · Pemain, hostHost: approve or rejectThe host sees requests with Terima / Tolak. Approving the request that fills the table opens everyone’s 15-minute pay window, and the screen says so first.Ini kursi terakhir. Begitu kamu terima, semua pemain punya 15 menit untuk bayar. Kalau ada yang tidak bayar, meja batal dan yang sudah bayar direfund.
/seat/[id] · guest checkout sheetJoin as a guestThe join prompt Apple asked for: name and email only, “the host approves first, nothing is paid yet”, and an easy way to sign in instead. The claim code on this device never overwrites a live one.Host menyetujui dulu. Kamu belum membayar apa pun. Kalau disetujui dan meja penuh, kami kirim tautan bayar ke email ini.
/seat/[id] · pay_windowTable full: pay windowEveryone has 15 minutes. The live countdown sits in the red “needs you now” band; the tile row shows who has paid. If the host extends it, a small “diperpanjang” chip appears (pay_window_extended).Kalau waktu habis sebelum semua bayar, meja batal dan uang yang sudah masuk dikembalikan.
/seat/[id] · confirmedConfirmedEveryone paid; the table is on. The claim code in Space Mono, directions, and the scoreboard for tonight.Semua sudah bayar. Sampai jam 20:00!
/seat/[id] · terminal statesCancelled, lapsed, bumped, completedTerminalNotice for each ending, with refund wording that only promises what the server reports. Pick one above.Refund Rp 45.900 sedang diproses ke rekening atau e-wallet asalmu.
Tidak semua kursi terbayar dalam 15 menit, jadi meja batal. Kalau kamu sudah bayar, uangnya dikembalikan.
Pemain lain lebih dulu mengisi kursi North. Kamu belum membayar apa pun untuk meja ini.
Terima kasih sudah main. Hasil malam ini ada di papan skor.
/seat/leaderboard/[id]Tonight’s scoreboardPer-session standings, always saying how old the data is. Start a ranked game from here, publish, or jump back to the table.Riichi santai · Winbardi · 3 hanchan
/post-seat · CreateTableFormOpen a tableA modal form: venue (only live, verified venues; coming-soon ones are left out), day and start, length, game type, rules, level, how many seats are open, and a note. The price per seat comes from the venue’s quote./post-seat · done panelTable is openThe done panel: open the table, share the link, retry any table that failed to create, then Selesai.Orang di Bandung bisa melihatnya di Cari Kaki.
Kam 24 Sep 20:00 tidak tersimpan. Yang lain aman.
/requestsHost inboxEverything waiting on you as a host: seats, club members, event and tournament entries. Tap a row to open the thing; approve or reject inline.Menerima kursi terakhir membuka waktu bayar 15 menit untuk semua.
Every event has a date tile (red underline = it’s a day in the calendar), where it happens, the price the server gives, and how many spots are taken drawn as spots, not a fraction. Event detail has five tabs (Info, Orang, Chat, Game, Papan) that all work here. Approval and money are separate: a host approves a request; paying is its own step. Experiences are booked from an hourly grid into a sheet capped at 88%.
/eventsAll eventsSearch with clear, kind chips, city pills including “Semua kota”. Filtering is local. The error card appears only when both sources fail./event/[id]Event detail, five tabsInfo (when, where with Maps or the online link, price, host club, the full description), Orang (participant spots and people), Chat (the event room), Game (games recorded here) and Papan (the event board). All five work.Turnamen bulanan untuk semua level. Aturan WRC, 4 hanchan, hadiah untuk 3 besar dari klub. Datang 15 menit sebelum mulai untuk undian tempat duduk…
/event/[id] · join statesJoin bar, every stateThe capped queue’s five states plus the “pick a table and hour” path for events with tables, and the refund line after leaving a paid event.Kalau keluar dari event berbayar, refund mengikuti aturan panitia. Status refund muncul di Pesananku.
/event/[id] · EventManageSheetHost toolsPending requests with approve/reject, then edit or cancel the event. Cancelling is destructive and asks again./event/experiencesExperiencesTicketed experiences in the city, each on its own felt card. Change city, retry, open a card.Satu meja, satu malam, sudah diatur semuanya.
/event/experiences/[id]Hourly availability gridTables across, hours down. Full cells are hatched. Tap a free cell to open the booking sheet.Angka = kursi kosong. Mulai Rp 120.000 per meja, dihitung server.
/event/experiences/[id] · EventBookingSheetBooking sheetCapped at 88%. The first booker of a table picks its game; each seat gets a name; a voucher field; then straight to the one QR (already created).Kamu pemesan pertama, jadi kamu yang pilih permainannya.
/event/leaderboard/[id]Event standingsDivision picker, a points chart for the leaders, then the standings with medal tiles. A scope note says what this board counts.Hanya game di event ini. Posisi nasional ada di Komunitas → Peringkat.
/event/matchmaking/[id]Seating room (organiser)Pick a pairing strategy, generate tables, move or bench a player, rename a table, undo every manual change, then lock the round. Record a table from its card.2 perubahan manual
/create-eventCreate a club eventClub, kind, table type, date and start, multi-day, player count, where (search a place, paste a pin, a nearby venue, or my location), approve-first, fee in rupiah (no cash), house rules. The screen says the server does not take a join mode yet.Cara gabung (terbuka / undangan) belum disimpan server. Untuk sekarang semua event memakai persetujuan host.
Public list, the hub with its two bars (registration for players, lifecycle for the organiser), bracket, rounds with seat swaps, standings with the division picker and points chart, plus the create and record-table modals. Tables are multiples of four. Pull-to-refresh can’t be reached inside these modals on iOS, so they show a visible reload button.
/tournamentsTournamentsStatus badges from the server. “Buat turnamen” checks the account first (guest gate) and only then the organiser rights./my-tournamentsMy tournamentsAll / Organizing / Registered. The error card uses the offline tile, not the warning-sign emoji.Periksa koneksi, lalu coba lagi.
/tournament/[id] · playerHub + registration barWhat, when, format, players and rounds, with the registration bar’s states: request, pending, registered (tap to leave), closed, pay entry./tournament/[id] · organiserLifecycle bar + reason sheetPublish → seed → start → pause/resume → finalize, plus cancel and abandon, which both need a reason (ReasonSheet). Pending requests sit on top.Tulis alasannya. Semua pemain akan menerima pesan ini, dan biaya masuk direfund.
/tournament/[id]/bracketBracketKnockout tables of four; the top two go on. Organisers generate or advance a round from here and record a table./tournament/[id]/round/[roundId]Round + seat swap sheetGenerate seating, lock and start, close the round; swap two seats in a sheet capped at 70%./tournament/[id]/standingsFull standingsDivision picker, points chart, the full table; Try again on failure./create-tournamentCreate a tournamentPick the club (or create one), the ruleset profile, table size in multiples of four, dates; a visible reload button because pull-to-refresh can’t be reached in this modal.Draf belum terlihat publik sampai kamu terbitkan.
/record-tableRecord a tournament tablePlacement or net scores; record; a recorded table can be reopened with a reason. Visible reload button.Jumlah harus 0. Sekarang: 0
Dicatat Agus · 15:42. Klasemen sudah diperbarui.
A club draws its own header: a felt banner, the logo as a rounded monogram, the verified tick. Every management control follows the server’s canManage flag, for both what shows and where it goes. The venue page keeps the liked “room with felt in it” hero. Avatars are monograms, never emoji. The edit sheet is a modal, so “where the club plays” is its own pushed screen (a route pushed from a modal would render behind it).
/club/[id] · memberClub, member viewJoin/leave toggle, message the admins, share and the menu. Tabs Tentang · Anggota · Game · Papan work. Members can host a game (open table) from here.Klub riichi paling tua di Bandung. Main tiap Senin di Tiga Naga, liga bulanan, pemula selalu diajak.
/club/[id] · adminClub, admin viewWhat canManage unlocks: members needing review first, then member management (promote, demote, remove), regulars (guest players), invite friends and the share link, host an event, transfer owner and disband./club/[id] · edit sheetEdit clubA modal capped at 92%: banner and logo, name, description, style, and “where the club plays” (opens club-location as its own screen)./create-clubCreate a clubCover and logo (a failed upload says so; a slow one can’t be submitted twice), name, city, style. Then “Ke klub” or “Lewati dulu”.Logo gagal diunggah. Coba lagi atau lanjut tanpa logo.
/club-location/[id]Where the club playsSearch a place (opens place-search, no map), or paste a map pin, then save.Ditampilkan di halaman klub dan dipakai untuk event baru.
/venue/[id]Venue profileThe liked hero drawn from tiles on felt. Tabs Tentang · Event · Ulasan · Papan (Papan hides when rank is off). Only a 404 means “not bookable”; offline keeps the booking button.Mejanya otomatis semua, stafnya sabar ngajarin.
/venue/[id] · write a reviewRate and reviewTap the stars (they work), write, send. Guests get “Masuk untuk menulis ulasan” instead. A failed send keeps the text.Masuk untuk menulis ulasan. Ulasan lain tetap bisa kamu baca.
Mejanya otomatis semua, stafnya sabar ngajarin.
Malam minggu penuh, pesan dulu.
/player/[id]Player profilePublic: rating, stats, yaku collection. Add friend or message, wave, invite to a table; every write passes the guest gate./player/[id] · block / reportBlock or reportThe menu sheet: report with a reason, block (or unblock). Destructive rows are red./leaderboard/[scope]Scoped leaderboardApp, club, event, venue or group scope. Board chips always send the board explicitly. Medal tiles 1–3, your row tinted, then how the board works.Rating naik-turun tiap game ranked. Game yang belum selesai tetap dihitung. Kamu bisa keluar dari papan publik di Pengaturan.
Your messages are green tiles of text, theirs are white cards. Images, references to a booking or a venue, a long-press menu (report, block user, delete, mute sender, block sender, each confirmed), photo permission handled with a toast. Notifications mark themselves read and route by payload; the socket only covers chat, so the inbox refreshes by pull.
/chat/[conversationId]Chat threadText, an image, a venue reference (taps to the venue) and a booking reference. Sends are optimistic./chat/[conversationId] · long-pressLong-press menuThe pressed message lifts; the menu offers Report, Delete, Mute sender, Block sender, Block user. Each one asks to confirm./chat/[conversationId] · attachAttach a booking, or a photoA sheet capped at 70% lists your bookings to reference. Choosing a photo asks for library access; if refused, a toast says so./notificationsNotificationsTap marks read and routes to the thing. “Tandai semua dibaca” on top; pull to refresh.Today every coaching route shows the one “coming soon” screen. The other three phones are the redesigned screens for when the flag turns on; they are marked FLAG OFF and are not reachable now. Lesson checkout will reuse guest checkout and the QRIS pay screen; the fee is not computed before the booking exists.
/coaching · /coach/[id] · /class/[id] · /coach-dashboardCoaching, coming soonWhat every coaching route shows while the flag is off.Kelas pemula dan pelatih pribadi sedang kami siapkan. Sementara itu, banyak meja terbuka yang menerima pemula.
/coachingDiscovery Flag offClasses and coaches tabs, coach tools for coaches, and “become a coach”.Kamu pelatih? Buka jadwal dan terima murid.
/coach/[id]Coach + lesson Flag offProfile, reviews, a week strip of slots, then guest checkout → /pay/method.Mantan juara Bandung Open. Fokus bertahan dan membaca discard.
/class/[id] · /coach-dashboardClass + coach tools Flag offEnroll or leave, share. Coach dashboard: profile, weekly availability, create a class (capacity 2–20).Hana Nugraha · Winbardi · 4 Sabtu mulai 3 Okt
The approved plus board: East on top, South and North on the sides, West at the bottom, every card upright and raised because you tap it. Winds are text labels, the corner is a big 東 over “East - 2”, “Honba” is English, and the red End game button is the same height as Riichi and Chombo. Every step of the win flow is its own pushed screen (owner decision D5, never a bottom sheet), each with the same top: back, seven progress bars, the round. It works offline; ranked results go through the outbox. Type never shrinks below the scorekeeper floors; the page scrolls instead.
/game · PlaceChooserWhere are you playing?Bookings, clubs, events, open tables, or personal. An anchored game counts on that place’s board; a personal one moves only your stats.
Game yang terhubung ke tempat ikut papan peringkat tempat itu.
/game · HouseRulesPickerHouse rulesThe library of sheets with bundled fallbacks, so it works offline. The HK value table is the owner’s own; ITM counts points with a sheet minimum. Rules show as a grouped list with steppers and toggles./game · SeatingPanelWho sits whereFour winds as the same raised cards as the table. Search players or add a guest name; shuffle seats. The panel is capped at 82% when it opens as a sheet./game · SettingsPanelGame settingsLength, uma (must sum to zero, else every submission is refused), timer, and ranked, which needs an account and every seat filled by a player.Semua kursi terisi pemain berakun, jadi game ini bisa ranked.
/game · DiceRollModalRoll the diceTwo ivory dice; the total says where the wall breaks.Dinding dibuka di depan East (Kamu).
/game · timer modal · TimerBoxRound timerAny length, like the phone’s own timer: spin hours, minutes and seconds (no presets). Set it once; it lives as a strip on the table. The pause icon is two plain bars so it scales with text size./game · the tableThe approved plus boardEast on top, raised player cards, 東 with “East - 2”, Honba 1, one riichi stick, the last hand, Riichi · Chombo · settings, Catat menang · Seri, and the red End game at the same height as Riichi/Chombo. Undo lives on the history.
/game · darkThe table, dark GelapSame board pinned dark. The dealer card keeps its green ring; riichi stays red; the ivory buttons stay ivory./game/win-whoWin 1 · who wonSeat cards with their scores. Several winners is a row here (reachable on HK/ITM, not on Riichi)./game/win-howWin 2 · Ron or TsumoTwo big choices. On a self-draw, the dealt-in step is skipped./game/win-dealt-inWin 3 · who dealt inOnly the three other seats. Not shown on a tsumo.Lia ron dari…
/game/win-pointsWin 4 · the valueHan and fu steppers, the points the engine reads back, pao, and two shortcuts: scan the hand, or pick from readings. This step writes nothing./game/win-readingsWin 5 · readingsThe scanned or typed hand with the winning tile ringed, then each reading of it; the highest is pre-selected. Tile width follows text size./game/penaltyWin 6 · penaltiesFree-form penalties, answered before the win is staged. Most hands: “Tidak ada”.Misalnya salah panggil atau buka tangan. Dicatat terpisah dari tangan ini.
/game/win-recapWin 7 · recapWho pays whom, in full, before anything is written. Terima records it and shows the round-advance popup.Lia ron dari Dimas · 3 han 30 fu · Riichi, Pinfu, Dora 1
/game · round-advance popupNext roundAfter accepting: the big 東 over the new round, who deals, and the honba count. One tap back to the table.
Dealer sekarang Dimas. Honba kembali 0.
/game/win-multiSeveral winnersFor HK or ITM double wins: each winner’s value in its own row, one deal-in.Hong Kong · keduanya ron dari Dimas
Nilai per faan dari tabel rumah klubmu.
/game/riichiRiichiPick one or more players (it works), confirm; each puts a 1.000 stick on the table.Bisa lebih dari satu. Masing-masing menaruh 1.000.
/game/chomboChomboWho, and what it costs under this sheet. A chombo resets the hand and breaks zero-sum on purpose.Dimas −8.000. Tangan diulang, dealer dan honba tetap. Poin ini tidak dibagi ke pemain lain.
/game · draw sheetSeri (draw)Exhaustive draw with who is tenpai, or an abortive draw. The sheet shell is capped at 86%.
Siapa yang tenpai?
/game/hand-valuesHand valuesMid-hand lookup with search. When a search finds nothing, the empty state says why.Ron di kiri · tsumo (non-dealer/dealer) di bawahnya.
/game/scanScan a handThe camera, a frame for the hand, tiles recognised on the device. If permission is denied and can be asked again, a “grant” button; otherwise an explanation. Pick from the library too.Letakkan 14 tile dalam bingkai, sejajar.
Kaki butuh kamera untuk membaca tile. Gambar tidak dikirim ke mana pun.
/game/scan-reviewCheck the scanFix any tile with the keyboard (the White Dragon key is blank), mark red fives and bonus tiles, then “Pakai tangan ini” or leave without publishing./game/start-fromStart from…An active booking, a club, an event, or a personal game. Events has its own empty state; loading errors say so with a retry.Tidak ada event yang sedang berjalan untukmu hari ini.
/game/menuThe ••• menuThree actions: rename a player, change rules, abandon (with confirm). Hand values is a link, not a fourth action. Close only.6 tangan akan hilang dan tidak masuk papan. Ini tidak bisa diurungkan.
/game/settingsTable settingsDrag a player onto a wind, swap two seats, rename, rule overrides, end game. Seats freeze once the result is in the outbox./game · EndGameSheet · IncompleteSaveSheet · recapEnd gameFinal scores with uma before saving; if the game isn’t finished, save it as unfinished (it still counts) or keep playing. After saving: the recap and “keep these rules?”.
Masuk papan Winbardi. Rating diperbarui saat online.
Riichi · WRC dengan 2 perubahan. Pakai lagi untuk game berikutnya.
Simpan sekarang? Game yang belum selesai tetap dihitung di papan dengan skor saat ini.
/game/summaryScoresheetReplayed from the log: final standings, every hand, and the ranked sync status (queued offline, sent, or private because it isn’t anchored).Di antrean. Dikirim otomatis saat online.
Recorded games are polled (the socket is chat only), there is no confirmation step any more, and a game with no rounds is normal. Stats count only hands that resolved; a locked row is “not yet”, never an error.
/ranked-gamesMy recorded gamesPlacement tile, place, date, rating change. Open the rounds inline, report a wrong result (with confirm), show older games./ranked-game/[id]One gameSeats, the round log (none is normal), the outbox state, and “lepaskan kursiku” to detach your seat, with confirm.Tersinkron · masuk papan Tenpai Addicts
Tidak ada ronde tercatat. Game ini dicatat hanya dengan skor akhir, dan itu normal.
/ranked-statsStats, one board at a timeBoard chips; win and deal-in rates over resolving hands only; locked rows say when they unlock./record-resultRecord a casual resultFormat, then assign a place to each seat in a sheet capped at 70%. The idempotency key is made at the tap, and the result goes through its outbox./statsStats & historyThe pro stats screen. It is plan-gated; while plans are off, nothing here sells. Error uses the tile, not the warning-sign emoji.Koneksi terputus. Game-mu tetap aman.
Catat game pertamamu di Pencatat skor.
The intro pager can be skipped and lets you “look around” without signing in. Sign-in is an email code, Apple (iOS only) and Google; a dismissed Apple sheet is not an error. Signup is one question per screen, each answer saved as it’s given. Onboarding keeps “Keluar” on every state (Apple 2.1). Settings adds the owner’s decision: the theme follows the system by default. Plans are off, so membership redirects to Kamu.
/introFirst-run pagerThree pages (tap the dots). “Lihat-lihat dulu” goes into the app, not to a sign-in wall.Meja yang kurang satu orang, di dekatmu. Tap kursi kosong, duduk.
Pilih jam, bayar QRIS, tunjukkan kode. Tanpa akun juga bisa.
Pencatat skor gratis, bisa tanpa internet. Setiap yaku jadi koleksimu.
/sign-in · emailSign inEmail code first; Apple on iOS only; Google. The keyboard pushes the form (padding on iOS only).
kakiKami kirim kode 6 angka ke emailmu. Tanpa kata sandi.
Dengan lanjut, kamu setuju dengan Ketentuan dan Kebijakan Privasi Kaki.
/sign-in · codeEnter the codeSix boxes, change email, resend after a short wait.Kode dikirim ke dewi.lestari@gmail.com
/sign-in · errorsSign-in errorsWrong code, rate limit with a wait time, an offline hint, and an OAuth callback error from ?error=. A cancelled Apple sheet shows nothing.Kodenya tidak cocok. Cek lagi atau kirim kode baru.
Terlalu banyak percobaan. Coba lagi dalam 1 menit 20 detik.
Sambungkan ke internet, lalu kirim kode lagi.
Masuk dengan Google tidak selesai. Coba lagi, atau pakai kode email.
/signup · stepsSign-up, one question per screenShown: name, username (live availability), WhatsApp code. The other steps in the same chrome: WhatsApp number, email, overall experience, style experience. Each answer is saved when given; “Coba lagi” on a failed save.Ditampilkan ke pemain lain di meja.
Teman bisa mencarimu dengan ini.
@dewi sudah dipakai. Coba @dewi.lestari
Tersedia
Dikirim ke +62 812-3456-7890
/onboarding · create · complete · editProfileCreate: photo, name, username (checking / available / taken / unknown-offline, which doesn’t block), gender, skill with no default, styles, Terms. Complete-basics asks only what’s missing. Edit is the same form with Simpan. “Keluar” on every state.Mengecek…
Dua hal ini dibutuhkan untuk main ranked.
Tidak bisa mengecek (offline). Kamu tetap bisa menyimpan.
/settingsSettingsProfile, public leaderboard opt-out, language, and the theme: Ikuti sistem (default), Terang, Gelap. Stats, replay onboarding, legal, sign out. The plan row is hidden while plans are off.Sekarang: Gelap, mengikuti iPhone-mu.
Kaki 3.4.0 · kakimahjong.com
/settings · delete accountDelete account: armed → confirmTap “Hapus akun” once to arm it: the warning and the final red button appear. Nothing is deleted on the first tap.Profil, teman, klub yang kamu miliki, dan rating akan dihapus.
Ini permanen. Pesanan yang sudah dibayar tetap tercatat di tempat, tapi tidak bisa kamu lihat lagi di aplikasi.
/membershipMembership Plans offPLANS_ENABLED is false, so this route redirects to Kamu today. The design for later: plans from the store, upgrade, restore purchases, privacy and terms.Statistik lengkap, turnamen klub, riwayat tanpa batas.
Privasi · Ketentuan
/j/[kind]/[id]Invite link landingFor a seat, club, event, tournament or class. Joining never replaces who is signed in on this device; with no session it falls back to an anonymous guest. Errors say what happened.
kakiMejanya mungkin sudah penuh atau dibatalkan.
/city-pickerCity picker (form sheet)A 0.9 detent sheet. Tap a city; falls back to the current city; retry on failure./place-searchPlace searchSearches on submit, never per keystroke. Clear, Try again, choose a place. There is no map.Tekan Cari di keyboard untuk mencari.
Loading is always a skeleton in the final layout, never a blank screen. There is no global offline banner (the app has no connection detector): each screen shows its own cloud-offline tile with Retry, and pay and sign-in have their own offline wording. Errors use a tile or an icon, never the warning-sign emoji. One toast at a time. A private route opened by a guest goes Home with a toast that says why. The booking-end reminder slides in at 15 and 5 minutes.
skeletonsLoadingThe final layout, shimmering: a live-card block, a rail, a grouped list.per-screen offline · emptyOffline, and emptyA request timed out (20 s, 12 s for /me): the screen keeps what it had and offers Retry, with the cloud-offline tile. Empty (here: no open tables tonight) always offers the next thing to do.Meja terbuka belum bisa dimuat. Pencatat skor tetap bisa dipakai tanpa internet.
Buka meja sendiri, nanti orang lain yang mengisi kursinya.
error cardsErrors, with a tileFull-screen and inline error cards, each with one next step. The three old the warning-sign emoji glyphs (my-bookings, stats, my-tournaments) become tiles.Server sedang bermasalah. Kode pesananmu tetap berlaku di tempat.
Papan peringkat tidak bisa dimuat.
Ulasan belum dimuat · offline
ToastProviderToastsOne at a time, from the top, on plain Animated. Green square = done, red = didn’t work, white = info. Shown: a guest bounced from a private route.3 meja di Bandung masih butuh kaki.
useGuestGate().promptSignInGuest sign-in promptA guest taps something that needs an account (open a table, join a club, record ranked): the tap stops before any request and this sheet says why. It never bounces or fails silently.Pemain lain perlu tahu siapa host-nya. Butuh 30 detik.
BookingEndRemindersBooking ends soonA local reminder over whatever screen is open, at 15 and 5 minutes. It only tells; extending happens at the counter.