Flutter Soroban Abacus Card with Heaven and Earth Bead Rods

A soroban trainer card for Flutter maths and education apps, built with Wind utility classes: seven rods where every counted bead sits against the reckoning beam (one heaven bead worth 5, four earth beads worth 1), unit dots on the beam, the digit under each rod, and a streak, accuracy and pace row. Bead positions are computed from the number, so the abacus always reads true.

Anılcan Çakır by Anılcan Çakır 99 views 0 stars 3 weeks ago Rev 1
Flutter Soroban Abacus Card with Heaven and Earth Bead Rods preview
main.dart
WDiv(
  className: 'w-[340px] rounded-3xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 p-5 flex flex-col shadow-xl',
  children: [
    WDiv(
      className: 'flex flex-row items-center justify-between w-full',
      children: [
        WDiv(
          className: 'flex flex-row items-center gap-3',
          children: [
            WDiv(
              className: 'flex flex-row items-center justify-center w-10 h-10 rounded-xl bg-amber-600 dark:bg-amber-500',
              child: WDiv(
                className: 'flex flex-col items-center gap-[3px]',
                children: [
                  WDiv(
                    className: 'w-[18px] h-[7px] rounded-full bg-white dark:bg-amber-50'
                  ),
                  WDiv(
                    className: 'w-[18px] h-[2px] bg-amber-200 dark:bg-amber-300'
                  ),
                  WDiv(
                    className: 'w-[18px] h-[7px] rounded-full bg-white dark:bg-amber-50'
                  )
                ]
              )
            ),
            WDiv(
              className: 'flex flex-col',
              children: [
                WText(
                  'Soroban Trainer',
                  className: 'text-base font-bold text-gray-900 dark:text-white'
                ),
                WText(
                  'Flash anzan, level 6',
                  className: 'text-xs text-gray-500 dark:text-gray-400'
                ),
              ]
            ),
          ]
        ),
        WDiv(
          className: 'rounded-full bg-emerald-50 dark:bg-emerald-900/40 px-3 py-1',
          child: WText(
            'Correct',
            className: 'text-xs font-bold text-emerald-600 dark:text-emerald-300'
          )
        ),
      ]
    ),
    WText(
      'Set the number on the rods',
      className: 'text-xs font-medium text-gray-500 dark:text-gray-400 mt-4'
    ),
    WText(
      '3,905,274',
      className: 'text-3xl font-extrabold text-gray-900 dark:text-white mt-1'
    ),
    WDiv(
      className: 'flex flex-col items-center w-full mt-4',
      children: [
        WDiv(
          className: 'rounded-xl bg-amber-900 dark:bg-amber-950 p-[4px]',
          child: WDiv(
            className: 'relative w-[272px] h-[168px] rounded-lg bg-amber-50 dark:bg-stone-900',
            children: [
              WDiv(
                className: 'absolute left-[21px] top-[0px] w-[2px] h-[168px] bg-amber-800/40 dark:bg-amber-200/30'
              ),
              WDiv(
                className: 'absolute left-[59px] top-[0px] w-[2px] h-[168px] bg-amber-800/40 dark:bg-amber-200/30'
              ),
              WDiv(
                className: 'absolute left-[97px] top-[0px] w-[2px] h-[168px] bg-amber-800/40 dark:bg-amber-200/30'
              ),
              WDiv(
                className: 'absolute left-[135px] top-[0px] w-[2px] h-[168px] bg-amber-800/40 dark:bg-amber-200/30'
              ),
              WDiv(
                className: 'absolute left-[173px] top-[0px] w-[2px] h-[168px] bg-amber-800/40 dark:bg-amber-200/30'
              ),
              WDiv(
                className: 'absolute left-[211px] top-[0px] w-[2px] h-[168px] bg-amber-800/40 dark:bg-amber-200/30'
              ),
              WDiv(
                className: 'absolute left-[249px] top-[0px] w-[2px] h-[168px] bg-amber-800/40 dark:bg-amber-200/30'
              ),
              WDiv(
                className: 'absolute left-[0px] top-[54px] w-[272px] h-[6px] bg-amber-900 dark:bg-amber-800'
              ),
              WDiv(
                className: 'absolute left-[7px] top-[4px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[7px] top-[61px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[7px] top-[76px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[7px] top-[91px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[7px] top-[150px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[45px] top-[39px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[45px] top-[61px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[45px] top-[76px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[45px] top-[91px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[45px] top-[106px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[83px] top-[4px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[83px] top-[105px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[83px] top-[120px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[83px] top-[135px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[83px] top-[150px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[121px] top-[39px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[121px] top-[105px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[121px] top-[120px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[121px] top-[135px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[121px] top-[150px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[159px] top-[4px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[159px] top-[61px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[159px] top-[76px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[159px] top-[135px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[159px] top-[150px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[197px] top-[39px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[197px] top-[61px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[197px] top-[76px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[197px] top-[135px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[197px] top-[150px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[235px] top-[4px] w-[30px] h-[14px] rounded-full bg-amber-200 dark:bg-amber-900'
              ),
              WDiv(
                className: 'absolute left-[235px] top-[61px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[235px] top-[76px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[235px] top-[91px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[235px] top-[106px] w-[30px] h-[14px] rounded-full bg-amber-600 dark:bg-amber-500'
              ),
              WDiv(
                className: 'absolute left-[20px] top-[55px] w-[4px] h-[4px] rounded-full bg-white dark:bg-amber-100'
              ),
              WDiv(
                className: 'absolute left-[134px] top-[55px] w-[4px] h-[4px] rounded-full bg-white dark:bg-amber-100'
              ),
              WDiv(
                className: 'absolute left-[248px] top-[55px] w-[4px] h-[4px] rounded-full bg-white dark:bg-amber-100'
              )
            ]
          )
        ),
        WDiv(
          className: 'flex flex-row items-center w-[280px] mt-2',
          children: [
            WDiv(
              className: 'w-[7px] h-[4px]'
            ),
            WText(
              '3',
              className: 'w-[38px] text-center text-lg font-bold text-amber-700 dark:text-amber-400'
            ),
            WText(
              '9',
              className: 'w-[38px] text-center text-lg font-bold text-amber-700 dark:text-amber-400'
            ),
            WText(
              '0',
              className: 'w-[38px] text-center text-lg font-bold text-gray-300 dark:text-gray-600'
            ),
            WText(
              '5',
              className: 'w-[38px] text-center text-lg font-bold text-amber-700 dark:text-amber-400'
            ),
            WText(
              '2',
              className: 'w-[38px] text-center text-lg font-bold text-amber-700 dark:text-amber-400'
            ),
            WText(
              '7',
              className: 'w-[38px] text-center text-lg font-bold text-amber-700 dark:text-amber-400'
            ),
            WText(
              '4',
              className: 'w-[38px] text-center text-lg font-bold text-amber-700 dark:text-amber-400'
            )
          ]
        ),
      ]
    ),
    WDiv(
      className: 'flex flex-row items-center gap-2 w-full mt-3',
      children: [
        WDiv(
          className: 'flex flex-row items-center gap-2 rounded-full bg-amber-50 dark:bg-amber-900/30 px-3 py-1',
          children: [
            WDiv(
              className: 'w-[18px] h-[8px] rounded-full bg-amber-600 dark:bg-amber-500'
            ),
            WText(
              'Heaven bead = 5',
              className: 'text-[11px] font-medium text-amber-800 dark:text-amber-200'
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-row items-center gap-2 rounded-full bg-amber-50 dark:bg-amber-900/30 px-3 py-1',
          children: [
            WDiv(
              className: 'w-[18px] h-[8px] rounded-full bg-amber-600 dark:bg-amber-500'
            ),
            WText(
              'Earth bead = 1',
              className: 'text-[11px] font-medium text-amber-800 dark:text-amber-200'
            ),
          ]
        ),
      ]
    ),
    WDiv(
      className: 'flex flex-row items-center justify-between w-full mt-4',
      children: [
        WDiv(
          className: 'flex flex-col w-[92px] rounded-xl bg-gray-50 dark:bg-gray-800 px-3 py-2',
          children: [
            WText(
              'Streak',
              className: 'text-[11px] font-medium text-gray-400 dark:text-gray-500'
            ),
            WText(
              '12',
              className: 'text-base font-bold text-gray-900 dark:text-white'
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-col w-[92px] rounded-xl bg-gray-50 dark:bg-gray-800 px-3 py-2',
          children: [
            WText(
              'Accuracy',
              className: 'text-[11px] font-medium text-gray-400 dark:text-gray-500'
            ),
            WText(
              '94%',
              className: 'text-base font-bold text-gray-900 dark:text-white'
            ),
          ]
        ),
        WDiv(
          className: 'flex flex-col w-[92px] rounded-xl bg-gray-50 dark:bg-gray-800 px-3 py-2',
          children: [
            WText(
              'Average',
              className: 'text-[11px] font-medium text-gray-400 dark:text-gray-500'
            ),
            WText(
              '3.8 s',
              className: 'text-base font-bold text-gray-900 dark:text-white'
            ),
          ]
        ),
      ]
    ),
    WDiv(
      className: 'w-full mt-4',
      child: WButton(
        className: 'w-full rounded-2xl bg-amber-600 dark:bg-amber-500 py-3 flex flex-row items-center justify-center',
        child: WText(
          'Next number',
          className: 'text-sm font-semibold text-white'
        )
      )
    ),
  ],
)
Stats
Views
99
Stars
0
Revisions
1
Size
13,692 chars
Created
Oct 6, 2026