<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kukuri.git/modules/orgflow-ui/src/wasmJsMain/resources, branch main</title>
<subtitle>kukuri: Kotlin Multiplatform app (desktop / wasm / native / Android) for the orgflow UI</subtitle>
<link rel='alternate' type='text/html' href='https://openpgpkey.dangofactory.net/cgit/cgit.cgi/kukuri.git/'/>
<entry>
<title>Phone layout: tab icons, short labels, and a working way to shoot at phone width</title>
<updated>2026-09-26T07:41:01+00:00</updated>
<author>
<name>charlie</name>
<email>root@dangofactory.local</email>
</author>
<published>2026-09-26T07:41:01+00:00</published>
<link rel='alternate' type='text/html' href='https://openpgpkey.dangofactory.net/cgit/cgit.cgi/kukuri.git/commit/?id=52a808ac2a248d4e0667674895f263a6e25dce5c'/>
<id>52a808ac2a248d4e0667674895f263a6e25dce5c</id>
<content type='text'>
The narrow layout was already implemented to 2.22's skeleton, but measuring it
at a real phone width found two problems, and getting to that measurement took
three failed approaches worth recording.

Why a Galaxy S25 user agent changed nothing: Firefox will not make a window
narrower than 500 CSS px. Requesting 380/400/412/450/500 returned 500 every
time, while 600 and 700 were honoured exactly. An S25 is 384-412 px, so the
real width is unreachable in a top-level window - the limit is the window, not
the UA. Shrinking the Compose canvas element to 384 also failed: the canvas
attribute became 384 but Compose kept laying out against 500, so the capture
showed 500-wide content cut off at 384 and the tab bar lost Live and settings
off the right edge. What works is an iframe of the exact size - it has its own
viewport, so the app inside sees innerWidth 384 and Compose lays out against
real dimensions. phone-host.html is now part of the web resources so it ships
with the bundle, and shot-phone.py drives it. Recorded as 2.29 so this is not
re-derived later.

With a true 384px viewport, the tab bar did not fit. Laying labels out with
SpaceEvenly got only Home, Timeline, Calendar and Note on screen; Live and
settings were pushed off and never drawn. Six text labels do not fit 384px.

So the tabs are now an icon over a short label, each weighted equally
(2.28):
  - icons drawn on a Canvas, no image assets: house, list, calendar, page,
    camera, gear
  - short labels, chosen rather than truncated - cutting a word mid-way makes
    it unreadable, so separate short names are used: Home / Line / Cal / Note /
    Live / Settings
  - labels stay English. One tab reading 設定 among five English ones mixes
    languages inside a single row; in-page headings stay Japanese, but the tab
    row is a list of proper names.
  - icons are never shown alone, for the same reason 2.22 rejected an
    icon-only nav: NN/g's Icon Usability (2014) found icons on their own do
    not convey meaning reliably.

Wide layout gets the same six glyphs on the left-column nav, as asked. The
same frame now looks the same at both widths, so nothing has to be relearned
when the window changes; wide has room for the full words, so it keeps
"Timeline" and "Calendar".

Calendar bar, per the same request: the centre pill on the month view is now
今月 rather than 今日 (the day view keeps 今日), and the pill is drawn with a
fill so it reads as pressable rather than as a heading. Both bars were
re-measured at 384px and fit.

One capture trap worth knowing: the browser profile is reused so the wasm
caches and startup is fast, which means a stale build can be served and the
screenshot silently shows the previous version - it did, showing "Time" and
"設定" after those strings had already changed. The URL now carries a
cache-buster that the harness forwards to the inner iframe.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The narrow layout was already implemented to 2.22's skeleton, but measuring it
at a real phone width found two problems, and getting to that measurement took
three failed approaches worth recording.

Why a Galaxy S25 user agent changed nothing: Firefox will not make a window
narrower than 500 CSS px. Requesting 380/400/412/450/500 returned 500 every
time, while 600 and 700 were honoured exactly. An S25 is 384-412 px, so the
real width is unreachable in a top-level window - the limit is the window, not
the UA. Shrinking the Compose canvas element to 384 also failed: the canvas
attribute became 384 but Compose kept laying out against 500, so the capture
showed 500-wide content cut off at 384 and the tab bar lost Live and settings
off the right edge. What works is an iframe of the exact size - it has its own
viewport, so the app inside sees innerWidth 384 and Compose lays out against
real dimensions. phone-host.html is now part of the web resources so it ships
with the bundle, and shot-phone.py drives it. Recorded as 2.29 so this is not
re-derived later.

With a true 384px viewport, the tab bar did not fit. Laying labels out with
SpaceEvenly got only Home, Timeline, Calendar and Note on screen; Live and
settings were pushed off and never drawn. Six text labels do not fit 384px.

So the tabs are now an icon over a short label, each weighted equally
(2.28):
  - icons drawn on a Canvas, no image assets: house, list, calendar, page,
    camera, gear
  - short labels, chosen rather than truncated - cutting a word mid-way makes
    it unreadable, so separate short names are used: Home / Line / Cal / Note /
    Live / Settings
  - labels stay English. One tab reading 設定 among five English ones mixes
    languages inside a single row; in-page headings stay Japanese, but the tab
    row is a list of proper names.
  - icons are never shown alone, for the same reason 2.22 rejected an
    icon-only nav: NN/g's Icon Usability (2014) found icons on their own do
    not convey meaning reliably.

Wide layout gets the same six glyphs on the left-column nav, as asked. The
same frame now looks the same at both widths, so nothing has to be relearned
when the window changes; wide has room for the full words, so it keeps
"Timeline" and "Calendar".

Calendar bar, per the same request: the centre pill on the month view is now
今月 rather than 今日 (the day view keeps 今日), and the pill is drawn with a
fill so it reads as pressable rather than as a heading. Both bars were
re-measured at 384px and fit.

One capture trap worth knowing: the browser profile is reused so the wasm
caches and startup is fast, which means a stale build can be served and the
screenshot silently shows the previous version - it did, showing "Time" and
"設定" after those strings had already changed. The URL now carries a
cache-buster that the harness forwards to the inner iframe.
</pre>
</div>
</content>
</entry>
<entry>
<title>Wasm shell: fix the Japanese font lookup so text renders</title>
<updated>2026-09-26T00:49:50+00:00</updated>
<author>
<name>charlie</name>
<email>root@dangofactory.local</email>
</author>
<published>2026-09-26T00:49:50+00:00</published>
<link rel='alternate' type='text/html' href='https://openpgpkey.dangofactory.net/cgit/cgit.cgi/kukuri.git/commit/?id=8403dd628e955bd9eb4eea6bd83540c0c1f324b5'/>
<id>8403dd628e955bd9eb4eea6bd83540c0c1f324b5</id>
<content type='text'>
The web shell never loaded its font. webfont.js stores the bundled TTF as
base64 in window.__orgflowFontB64, but the fetch/XHR shim in index.html only
looked for globalThis.__orgflowFontBlobs, which nothing ever created. Every
font request therefore fell through to the real fetch, the nested
composeResources path does not exist on the deploy server (its FTP forbids
MKD, which is why the font is shipped flat in the first place), and the app
rendered with no font at all.

Visible effect: every date number and every Japanese label came out as tofu
boxes. Confirmed by capturing the running app - document.fonts reported
"loaded n=0", and the calendar grid showed squares where the digits belong.

Fix: decode __orgflowFontB64 into the Blob map the shim expects. The decode
runs once at parse time and again lazily on the first matching request, because
webfont.js is loaded after this script and may not have run yet when the first
font read happens.

Two other things were established while chasing this, and are worth recording
because they look like application bugs but are not:

- The month grid appeared to stop at the 19th. It was not a layout bug: the
  browser chrome left only 650px of viewport, and a 7-column month grid needs
  roughly 190px per row, so six rows cannot fit. The screenshot tool now runs
  the browser in kiosk mode and sizes it to the full screen (1280x1024), and
  the grid shows the whole month plus the out-dates.
- The calendar's "today" cell looked like a two-cell red block in one capture.
  It is a single cell; the earlier reading was off because the viewport was
  small and the cells were being squeezed.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The web shell never loaded its font. webfont.js stores the bundled TTF as
base64 in window.__orgflowFontB64, but the fetch/XHR shim in index.html only
looked for globalThis.__orgflowFontBlobs, which nothing ever created. Every
font request therefore fell through to the real fetch, the nested
composeResources path does not exist on the deploy server (its FTP forbids
MKD, which is why the font is shipped flat in the first place), and the app
rendered with no font at all.

Visible effect: every date number and every Japanese label came out as tofu
boxes. Confirmed by capturing the running app - document.fonts reported
"loaded n=0", and the calendar grid showed squares where the digits belong.

Fix: decode __orgflowFontB64 into the Blob map the shim expects. The decode
runs once at parse time and again lazily on the first matching request, because
webfont.js is loaded after this script and may not have run yet when the first
font read happens.

Two other things were established while chasing this, and are worth recording
because they look like application bugs but are not:

- The month grid appeared to stop at the 19th. It was not a layout bug: the
  browser chrome left only 650px of viewport, and a 7-column month grid needs
  roughly 190px per row, so six rows cannot fit. The screenshot tool now runs
  the browser in kiosk mode and sizes it to the full screen (1280x1024), and
  the grid shows the whole month plus the out-dates.
- The calendar's "today" cell looked like a two-cell red block in one capture.
  It is a single cell; the earlier reading was off because the viewport was
  small and the cells were being squeezed.
</pre>
</div>
</content>
</entry>
<entry>
<title>kukuri reset: welcome-only app shell + bridge/vendor modules + CI infra</title>
<updated>2026-09-03T10:10:18+00:00</updated>
<author>
<name>ketsuban</name>
<email>ketsuban@kukuri.dev</email>
</author>
<published>2026-09-03T10:10:18+00:00</published>
<link rel='alternate' type='text/html' href='https://openpgpkey.dangofactory.net/cgit/cgit.cgi/kukuri.git/commit/?id=20fbdb7c15fd74efc62833d295373b0ce601e9e5'/>
<id>20fbdb7c15fd74efc62833d295373b0ce601e9e5</id>
<content type='text'>
Full pre-reset history preserved on branch backup/full-pre-reset (2ccab79).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Full pre-reset history preserved on branch backup/full-pre-reset (2ccab79).
</pre>
</div>
</content>
</entry>
</feed>
