wordmark 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +568 -0
  3. data/MIT-LICENSE +22 -0
  4. data/README.md +256 -0
  5. data/app/views/layouts/easyfaa.html.erb +24 -0
  6. data/app/views/recourses/_head.html.erb +3 -0
  7. data/art/autopilot.svg +9 -0
  8. data/art/cube.svg +9 -0
  9. data/art/design.svg +8 -0
  10. data/art/down.html.erb +95 -0
  11. data/art/easyfaa.svg +7 -0
  12. data/art/fountain.svg +9 -0
  13. data/art/goldrush.svg +7 -0
  14. data/art/houston.svg +8 -0
  15. data/art/icons.txt +185 -0
  16. data/art/index.html.erb +157 -0
  17. data/config/locales/easyfaa.en.yml +7 -0
  18. data/lib/wordmark/copy.rb +5 -0
  19. data/lib/wordmark/down.rb +19 -0
  20. data/lib/wordmark/engine.rb +53 -0
  21. data/lib/wordmark/helpers/flows.rb +53 -0
  22. data/lib/wordmark/helpers/heads.rb +60 -0
  23. data/lib/wordmark/helpers/logos.rb +43 -0
  24. data/lib/wordmark/helpers.rb +11 -0
  25. data/lib/wordmark/marks.rb +16 -0
  26. data/lib/wordmark/version.rb +4 -0
  27. data/lib/wordmark.rb +39 -0
  28. data/public/404.html +118 -0
  29. data/public/_headers +28 -0
  30. data/public/bh/css/bh.css +1 -0
  31. data/public/bh/js/bh.js +152 -0
  32. data/public/bh/theme/bootstrap.css +10 -0
  33. data/public/bh/theme/dawn.css +189 -0
  34. data/public/bh/theme/dracula.css +189 -0
  35. data/public/bh/theme/gruvbox.css +189 -0
  36. data/public/bh/theme/monokai.css +190 -0
  37. data/public/bh/theme/nord.css +189 -0
  38. data/public/bh/theme/one_dark.css +189 -0
  39. data/public/bh/theme/solarized.css +188 -0
  40. data/public/bh/theme/tokyo_night.css +189 -0
  41. data/public/css/easyfaa.css +1 -0
  42. data/public/down/autopilot.html +87 -0
  43. data/public/down/cube.html +87 -0
  44. data/public/down/design.html +87 -0
  45. data/public/down/easyfaa.html +84 -0
  46. data/public/down/fountain.html +87 -0
  47. data/public/down/goldrush.html +87 -0
  48. data/public/down/houston.html +87 -0
  49. data/public/favicon/autopilot-180.png +0 -0
  50. data/public/favicon/autopilot-192.png +0 -0
  51. data/public/favicon/autopilot-512.png +0 -0
  52. data/public/favicon/autopilot-96.png +0 -0
  53. data/public/favicon/autopilot-dev.svg +9 -0
  54. data/public/favicon/autopilot.ico +0 -0
  55. data/public/favicon/autopilot.svg +9 -0
  56. data/public/favicon/autopilot.webmanifest +12 -0
  57. data/public/favicon/cube-180.png +0 -0
  58. data/public/favicon/cube-192.png +0 -0
  59. data/public/favicon/cube-512.png +0 -0
  60. data/public/favicon/cube-96.png +0 -0
  61. data/public/favicon/cube-dev.svg +9 -0
  62. data/public/favicon/cube.ico +0 -0
  63. data/public/favicon/cube.svg +9 -0
  64. data/public/favicon/cube.webmanifest +12 -0
  65. data/public/favicon/design-180.png +0 -0
  66. data/public/favicon/design-192.png +0 -0
  67. data/public/favicon/design-512.png +0 -0
  68. data/public/favicon/design-96.png +0 -0
  69. data/public/favicon/design-dev.svg +8 -0
  70. data/public/favicon/design.ico +0 -0
  71. data/public/favicon/design.svg +8 -0
  72. data/public/favicon/design.webmanifest +12 -0
  73. data/public/favicon/easyfaa-180.png +0 -0
  74. data/public/favicon/easyfaa-192.png +0 -0
  75. data/public/favicon/easyfaa-512.png +0 -0
  76. data/public/favicon/easyfaa-96.png +0 -0
  77. data/public/favicon/easyfaa-dev.svg +7 -0
  78. data/public/favicon/easyfaa.ico +0 -0
  79. data/public/favicon/easyfaa.svg +7 -0
  80. data/public/favicon/easyfaa.webmanifest +12 -0
  81. data/public/favicon/fountain-180.png +0 -0
  82. data/public/favicon/fountain-192.png +0 -0
  83. data/public/favicon/fountain-512.png +0 -0
  84. data/public/favicon/fountain-96.png +0 -0
  85. data/public/favicon/fountain-dev.svg +9 -0
  86. data/public/favicon/fountain.ico +0 -0
  87. data/public/favicon/fountain.svg +9 -0
  88. data/public/favicon/fountain.webmanifest +12 -0
  89. data/public/favicon/goldrush-180.png +0 -0
  90. data/public/favicon/goldrush-192.png +0 -0
  91. data/public/favicon/goldrush-512.png +0 -0
  92. data/public/favicon/goldrush-96.png +0 -0
  93. data/public/favicon/goldrush-dev.svg +7 -0
  94. data/public/favicon/goldrush.ico +0 -0
  95. data/public/favicon/goldrush.svg +7 -0
  96. data/public/favicon/goldrush.webmanifest +12 -0
  97. data/public/favicon/houston-180.png +0 -0
  98. data/public/favicon/houston-192.png +0 -0
  99. data/public/favicon/houston-512.png +0 -0
  100. data/public/favicon/houston-96.png +0 -0
  101. data/public/favicon/houston-dev.svg +8 -0
  102. data/public/favicon/houston.ico +0 -0
  103. data/public/favicon/houston.svg +8 -0
  104. data/public/favicon/houston.webmanifest +12 -0
  105. data/public/favicon.ico +0 -0
  106. data/public/font/bootstrap-icons-6LILWPE2.woff2 +0 -0
  107. data/public/font/bootstrap-icons-FRBPO3H7.woff2 +0 -0
  108. data/public/font/ibm-plex-sans-500-latin-LA7QXWWL.woff2 +0 -0
  109. data/public/font/ibm-plex-sans-500-latin-ext-X4QHZICY.woff2 +0 -0
  110. data/public/font/ibm-plex-sans-500-latin-ext.woff2 +0 -0
  111. data/public/font/ibm-plex-sans-500-latin.woff2 +0 -0
  112. data/public/font/ibm-plex-sans-500-vietnamese-24B6BSND.woff2 +0 -0
  113. data/public/font/ibm-plex-sans-500-vietnamese.woff2 +0 -0
  114. data/public/index.html +165 -0
  115. data/public/js/easyfaa.js +1 -0
  116. data/public/logo/autopilot.png +0 -0
  117. data/public/logo/autopilot.svg +9 -0
  118. data/public/logo/cube.png +0 -0
  119. data/public/logo/cube.svg +9 -0
  120. data/public/logo/design.png +0 -0
  121. data/public/logo/design.svg +8 -0
  122. data/public/logo/easyfaa.png +0 -0
  123. data/public/logo/easyfaa.svg +7 -0
  124. data/public/logo/fountain.png +0 -0
  125. data/public/logo/fountain.svg +9 -0
  126. data/public/logo/goldrush.png +0 -0
  127. data/public/logo/goldrush.svg +7 -0
  128. data/public/logo/houston.png +0 -0
  129. data/public/logo/houston.svg +8 -0
  130. data/public/page/400.html +118 -0
  131. data/public/page/404.html +118 -0
  132. data/public/page/406-unsupported-browser.html +118 -0
  133. data/public/page/422.html +118 -0
  134. data/public/page/500.html +118 -0
  135. data/public/site.webmanifest +12 -0
  136. data/public/theme/bootstrap.css +10 -0
  137. data/public/theme/dawn.css +189 -0
  138. data/public/theme/dracula.css +189 -0
  139. data/public/theme/gruvbox.css +189 -0
  140. data/public/theme/monokai.css +190 -0
  141. data/public/theme/nord.css +189 -0
  142. data/public/theme/one_dark.css +189 -0
  143. data/public/theme/solarized.css +188 -0
  144. data/public/theme/tokyo_night.css +189 -0
  145. data/public/v0.21.0/bh/css/bh.css +1 -0
  146. data/public/v0.21.0/bh/js/bh.js +152 -0
  147. data/public/v0.21.0/bh/theme/bootstrap.css +10 -0
  148. data/public/v0.21.0/bh/theme/dawn.css +189 -0
  149. data/public/v0.21.0/bh/theme/dracula.css +189 -0
  150. data/public/v0.21.0/bh/theme/gruvbox.css +189 -0
  151. data/public/v0.21.0/bh/theme/monokai.css +190 -0
  152. data/public/v0.21.0/bh/theme/nord.css +189 -0
  153. data/public/v0.21.0/bh/theme/one_dark.css +189 -0
  154. data/public/v0.21.0/bh/theme/solarized.css +188 -0
  155. data/public/v0.21.0/bh/theme/tokyo_night.css +189 -0
  156. data/public/v0.21.0/css/easyfaa.css +1 -0
  157. data/public/v0.21.0/font/bootstrap-icons-FRBPO3H7.woff2 +0 -0
  158. data/public/v0.21.0/font/ibm-plex-sans-500-latin-LA7QXWWL.woff2 +0 -0
  159. data/public/v0.21.0/font/ibm-plex-sans-500-latin-ext-X4QHZICY.woff2 +0 -0
  160. data/public/v0.21.0/font/ibm-plex-sans-500-latin-ext.woff2 +0 -0
  161. data/public/v0.21.0/font/ibm-plex-sans-500-latin.woff2 +0 -0
  162. data/public/v0.21.0/font/ibm-plex-sans-500-vietnamese-24B6BSND.woff2 +0 -0
  163. data/public/v0.21.0/font/ibm-plex-sans-500-vietnamese.woff2 +0 -0
  164. data/public/v0.21.0/js/easyfaa.js +1 -0
  165. metadata +264 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e743ca7e57d3e884feabd645e6031c85bb5ff56ef6da6104e7a0316788d88422
4
+ data.tar.gz: 75231ac26cb115956b184ce9d23c0215daf7651882923b15322b072da6a888c4
5
+ SHA512:
6
+ metadata.gz: feeb6133c62c586bf3793ed01324ed8f8e937d3f398a4b75335a69abc4bdd2cedad938be04a6a22948ef3dce74d978cc62d3823710172bbaab8661d680a279d3
7
+ data.tar.gz: 9460ceb72aa99f7b23d579a3ab9d8e0da4a16d49789e98e7f9c41d23d9d728cea83c14a5ce5d940f1f689c3899b4d0c4647c8300e7c3a629466aa6c059f526e0
data/CHANGELOG.md ADDED
@@ -0,0 +1,568 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ For more information about changelogs, check [Keep a Changelog](http://keepachangelog.com) and
6
+ [Vandamme](http://tech-angels.github.io/vandamme).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## 0.21.0 - 2026-10-05
11
+
12
+ * [BREAKING] The gem is `wordmark`, and so is its module
13
+
14
+ `gem 'wordmark'` replaces `gem 'easyfaa'`, `require 'wordmark'` replaces `require 'easyfaa'`,
15
+ and the module is `Wordmark`: `Wordmark::Engine`, `Wordmark::Down`, `Wordmark::FormBuilder`,
16
+ `Wordmark.app`. What draws the house stays the house's: the helpers keep their `easyfaa_`
17
+ prefix, the files stay `/css/easyfaa.css` and `/js/easyfaa.js`, the layout `layouts/easyfaa`
18
+ and the locale keys `easyfaa.`. The name `easyfaa` on RubyGems goes to the `faa` command.
19
+
20
+ ## 0.20.0 - 2026-09-25
21
+
22
+ * [BREAKING] The gem is `easyfaa`, and so is everything in it
23
+
24
+ `gem 'easyfaa'` replaces `gem 'houseaccount'`, and the module is `Easyfaa`. Every helper
25
+ swaps its prefix — `easyfaa_logo`, `easyfaa_head_tags`, `easyfaa_layer`, `easyfaa_tags`,
26
+ `easyfaa_icons` — the layout a host renders is `layouts/easyfaa`, the locale keys sit
27
+ under `easyfaa.`, and the two files are `/css/easyfaa.css` and `/js/easyfaa.js`. The site
28
+ is https://design.easyfaa.com, and every URL a page pinned there moves with it.
29
+
30
+ * [BREAKING] The house wears the horizon, in sky and midnight
31
+
32
+ The house's mark is an attitude indicator: a level horizon, the ground below it filled,
33
+ the aircraft symbol above. `easy` is set in the sky, `#5aa9e6`, and `faa` in midnight,
34
+ `#0b1e3a` (`#cfe3f6` in the dark); every drawing is stroked in the sky, so the family
35
+ stays one set. An app the family has no mark for, and every page's footer, wears it.
36
+
37
+ * [BREAKING] The cube is the `cube` app's
38
+
39
+ It stays in the family under its own name — `easyfaa_logo app: :cube`, `/favicon/cube.svg`,
40
+ `/down/cube.html` — and is the house's no longer.
41
+
42
+ * [BREAKING] The lockup is set in IBM Plex Sans 500
43
+
44
+ Quicksand is gone, and `.quicksand` with it: a heading beside a lockup says `.plex`. The
45
+ face is served from `/font` in the same three ranges, and its ascender is Quicksand's
46
+ 0.74em, so every mark keeps its size and nudge.
47
+
48
+ ## 0.19.1 - 2026-09-20
49
+
50
+ * [CHANGE] The bundle is not published to npm
51
+
52
+ Nothing installed it from there: every app on this gem is a Rails app, and the two files a
53
+ page off the gem links come from the site, which keeps every version under its own path.
54
+ The package stays for what builds the bundle, and `private` is what says so.
55
+
56
+ The README said the bundle carried bh's stylesheet and script inside it, which stopped
57
+ being true in 0.18.0. It says what the two files hold now, and where bh's own go under them.
58
+
59
+ ## 0.19.0 - 2026-09-19
60
+
61
+ * [FEATURE] The head of an admin screen is drawn here
62
+
63
+ recourse draws a `recourses/head` partial where a view path supplies one, and this gem
64
+ supplies it: the house's two files and the icons a tab wears. An app on both gems keeps
65
+ no partial of its own, and one wanting something else writes its own, which is found
66
+ first.
67
+
68
+ ## 0.18.0 - 2026-09-19
69
+
70
+ * [BREAKING] The bundle is the house's layer alone
71
+
72
+ It carried bh's stylesheet and script inside it, so a page linking this one got Bootstrap
73
+ and the house together in 378K. It carries neither now: a page links bh's files first and
74
+ this one's after, which is what `houseaccount_layer` draws, and the house stylesheet is
75
+ 12K. `houseaccount_tags` draws the house's two alone, for a page that already has bh's.
76
+
77
+ * [BREAKING] `flow` is this gem's own
78
+
79
+ It wrapped bh's with `super`, which took an `include` ordering between two engines to
80
+ make work. bh no longer draws a signup page at all, so this one draws the whole of it.
81
+ `footer:` is `links:`, and `header:` is gone -- the lockup and the wall are what a house
82
+ flow is rather than options a caller passes. `logo:` is `href:`.
83
+
84
+ * [BREAKING] `houseaccount_url` goes, with `HouseAccount.url` and `HouseAccount::URL`
85
+
86
+ Nothing called it. The static pages name the design site outright.
87
+
88
+ * [BREAKING] The `recourses/head` partial goes
89
+
90
+ It was this gem reaching toward another by the name of its partial. An app that wants the
91
+ house layer on the pages recourse draws writes those two lines itself, which is one file
92
+ in the app that already knows about both.
93
+
94
+
95
+ ## 0.17.0 - 2026-09-18
96
+
97
+ * [FEATURE] bh 6.6, which draws a picture in a bubble as a thumbnail
98
+
99
+ At the height every other picture on these screens is drawn at. The note over a thread
100
+ is opaque and centred with it: it had named a background variable this bundle does not
101
+ define, and drew none.
102
+
103
+ ## 0.16.0 - 2026-09-18
104
+
105
+ * [FEATURE] bh 6.5, which carries a picture in a bubble and a note over a thread
106
+
107
+ `Bh::Message` takes `photos`, drawn under the words in the same bubble, and `chat_with`
108
+ takes a `note:` that holds the top while the thread scrolls under it.
109
+
110
+ * [FIX] The shell fills the screen in whole pixels
111
+
112
+ `100dvh` computes to a fraction on a scaled display, and the tenths over are a scrollbar
113
+ the page cannot use beside the one its content already has.
114
+
115
+ ## 0.15.0 - 2026-09-18
116
+
117
+ * [Breaking change] The nine palettes move to bh as well
118
+
119
+ `dracula`, `nord`, `solarized` and the rest are editor colour schemes restating Bootstrap's
120
+ own families — nothing in them is this house's, which is the test that moved everything
121
+ else. They are bh's now, and the build copies them out of the gem to `public/theme/`, so
122
+ every URL a host has ever linked answers exactly as before.
123
+
124
+ * [Breaking change] Bootstrap 6 moves to the `bh` gem, which this one now depends on
125
+
126
+ Most of what had grown here was not the house's: a combobox, a 6-digit code, a dialog, a
127
+ toast, a thread of messages and twenty-two Stimulus controllers are Bootstrap 6 with the
128
+ markup written once, and are worth the same to any Rails app. They live in `bh` now, along
129
+ with the form builder, nine stylesheets and Bootstrap itself. This gem depends on it and
130
+ bundles it, so `css/houseaccount.css` and `js/houseaccount.js` still carry everything they
131
+ carried before and a host changes nothing.
132
+
133
+ What a host does have to change is where it reaches for a name. `HouseAccount::Message` is
134
+ `Bh::Message` and `HouseAccount::FormBuilder` is `Bh::FormBuilder` — both kept under the
135
+ house's names, so neither breaks — but the locale keys moved: `houseaccount.all`,
136
+ `.ask`, `.clear`, `.close`, `.more`, `.no_results`, `.okay`, `.search`, `.send`, `.typing`
137
+ and `.ago` are now `bh.*`, and a host that overrode one overrides it there. The meta that
138
+ words a confirmation's other button is `bh-cancel` rather than `houseaccount-cancel`.
139
+
140
+ * [Breaking change] `flow` takes what the page stands on rather than assuming it
141
+
142
+ bh's `flow` knows nothing of a lockup or a wall. The house's still draws both — `flow logo:`
143
+ is unchanged — but every other option is now the column's, so a page standing on something
144
+ of its own names the controller that paints it.
145
+
146
+ * [Breaking change] The npm package ships the built tree alone
147
+
148
+ It used to export `app/javascript` and `app/stylesheets` for a host that would rather
149
+ bundle the sources itself. Those sources now reach for bh, which is a gem and cannot be
150
+ resolved from `node_modules` — there is no npm package of bh and there will not be one —
151
+ so the exports go and the package is `public/css`, `public/js`, `public/font` and
152
+ `public/theme`: exactly what the CDN links in the README serve.
153
+
154
+ ## 0.14.2 - 2026-09-18
155
+
156
+ * [Fix] A conversation reads at the house's own size wherever it is drawn
157
+
158
+ A bubble took its type from the page around it, so a chat on a host that compacts its
159
+ body for tables dense with figures came out smaller than the same chat on a page that
160
+ does not. A sentence somebody typed is prose whatever the table beside it needs, so
161
+ `.chat-bubble` and the field under it say their own size.
162
+
163
+ * [Fix] A bubble is read from its start inside a flow
164
+
165
+ A flow centres a card's words, which suits a heading and a one-line answer and not an
166
+ answer long enough to wrap: a paragraph is read down an edge rather than about a middle.
167
+
168
+ * [Fix] A focus ring is not painted over by the link below it
169
+
170
+ The ring is an outline with an offset, drawn outside the box it rings and taking no room,
171
+ so the next link's own background — the tint an active row wears — covered the half that
172
+ overlapped. The focused link is lifted above its siblings, the way the navbar already is
173
+ over the table under it.
174
+
175
+ ## 0.14.1 - 2026-09-17
176
+
177
+ * [Fix] A confirm asks about the link that was clicked rather than whatever holds the focus
178
+
179
+ * [Change] The showcase demonstrates the confirm without a bare dialog standing beside it
180
+
181
+ ## 0.14.0 - 2026-09-17
182
+
183
+ * [Feature] A table's rows can be dragged into an order
184
+
185
+ The `sortable` controller, which is what a recourse page with a grip beside each row
186
+ names: a row is picked up by its grip and dropped somewhere else in the table, and the
187
+ place it landed in is PATCHed to the URL that row carries. Only the row that moved is
188
+ reported — the server shifts whatever it displaced, being the only one that knows how
189
+ many rows stand behind this page — and nothing is rendered from the answer, since the
190
+ row is already where it was dropped and redrawing the table under the cursor that
191
+ dropped it is the thing to avoid. A move the server refuses reloads the enclosing
192
+ frame, so a row never sits somewhere the database never agreed to, and a refresh
193
+ broadcast arriving mid-drag is sat out the way the search form sits one out.
194
+
195
+ SortableJS does the dragging, bundled like everything else here. Its own two classes
196
+ are styled beside the table's: the space a row will land in wears the tint a kept row
197
+ wears, and the grip is `grab`, then `grabbing` while it is held — the whole of the
198
+ affordance, since the icon already says what it is. `touch-action` is taken off that
199
+ square alone, a phone scrolling a table by dragging anywhere else on it.
200
+
201
+ * [Fix] A question half typed survives an answer landing: the field is Turbo's to leave alone,
202
+ and is emptied once the question it held has gone rather than by the morph
203
+
204
+ ## 0.13.3 - 2026-09-17
205
+
206
+ * [Change] The showcase leads with the themes, and says less everywhere else
207
+
208
+ The palette toggle repaints everything under it, so it stands first, and the section is
209
+ Themes — the word the folder, the id and the files have always used. Its button names the
210
+ mode it switches to and nothing else. Icons lost the last paragraph on the page that
211
+ described what the thing under it draws, and on a phone the two card URLs show the path
212
+ without the origin there is no room for.
213
+
214
+ * [Fix] The README pins a version a host can install
215
+
216
+ Three 0.13 releases went out while the README still taught `~> 0.12.0`, which stops short
217
+ of 0.13: a pin that cannot resolve the gem it appears in. It pins `~> 0.13.0` now, every
218
+ example URL names this release, and `package-lock.json`, left at 0.12.0 by the same three
219
+ releases, carries the version its package does.
220
+
221
+ ## 0.13.2 - 2026-09-17
222
+
223
+ * [Fix] The cell a label wraps is `flow-field`; `form-field` is Bootstrap's, and its rules applied
224
+
225
+ ## 0.13.1 - 2026-09-17
226
+
227
+ * [Fix] A card too short for what does not scroll scrolls whole, rather than spilling it
228
+
229
+ * [Change] A ticked box sits beside its words with room between them, and counts as a field
230
+
231
+ ## 0.13.0 - 2026-09-17
232
+
233
+ * [Feature] The ascending sort glyph
234
+
235
+ `bi-sort-up` joins `bi-sort-down` in the subset. A table heading says which way its column
236
+ is sorted, and until now only one of the two directions had a glyph to say it with — the
237
+ other drew an empty box, since a name the subset does not carry has no `content` rule and
238
+ no code point in the font.
239
+
240
+ `unicon` names the pair as `:sort_asc` and `:sort_desc` from 3.7.0, which is where recourse
241
+ reads them from.
242
+ * [Change] The card is as wide as what it holds, and a page asking one question says `30rem`
243
+ * [Change] A legend wears nothing of ours
244
+ * [Change] A form of more than one field reads its rows from where their words start
245
+ * [Feature] `flow-middle` stands a card as tall as the rest and holds its content in the middle
246
+ * [Feature] The builder dresses every kind of field, so a page writes no Bootstrap class
247
+ * [Feature] `form.combobox` is a select the bundle searches, in the house's own words
248
+ * [Change] A fieldset carries its own spacing and the gap between its controls
249
+ * [Change] A rule inside the card is given room either side of it
250
+ * [Feature] `form.check` is a box and the words beside it, which no page draws by hand now
251
+ * [Feature] `form.label` with words and a block wraps the control, so a wide card takes two columns
252
+ * [Feature] `flow-scroll` gives any long card the height, the inner scroll and the fixed foot a chat's card has
253
+
254
+ ## 0.12.0 - 2026-09-17
255
+
256
+ * [Change] The showcase shows rather than describes
257
+
258
+ The page at design.houseaccount.com carried a paragraph over every component saying what
259
+ the component below it was about to do. Each is gone: the thing itself is on the page, a
260
+ few pixels under where the description stood, and it is the one that cannot go stale. What
261
+ is left is the name of each component and, where a path is named, a link to the file.
262
+
263
+ The page reads down the middle now, and its sections stand in the order somebody comes for
264
+ them: Components — with Chat, Wall and Tables as subsections of it, which is what they
265
+ always were — then Error pages, Palettes and Icons, which is Favicons with the drawing
266
+ under `/logo` as its first column. The header says what the page is in one sentence: the
267
+ components, error pages, palettes and icons shared by Fountain, Goldrush, Houston and
268
+ Autopilot, each mark linking to its own host.
269
+
270
+ ## 0.11.0 - 2026-09-16
271
+
272
+ * [Feature] The built stylesheet and script are in the package, for a page that links them
273
+
274
+ The package carried its sources alone, which a bundler can read and a browser cannot: the
275
+ script opens on three bare specifiers nothing resolves without an import map, and the
276
+ stylesheet is fourteen `@import` lines a browser would fetch one after another. So the
277
+ built `css/`, `js/`, `theme/` and `font/` ship beside them, and a page on any host links
278
+ one file from a CDN holding the package — `cdn.jsdelivr.net/npm/houseaccount@0.11.0/public/` —
279
+ at a version that is owed those bytes for good, npm never letting one be written twice.
280
+
281
+ * [Change] Every URL inside the stylesheet is relative
282
+
283
+ It named the site's own root, `/font/…`, which is right in one place and wrong everywhere
284
+ else: under a version prefix, or on a CDN, the font was asked for at a path no host had.
285
+ `../font/…` resolves against wherever the stylesheet is read from, so one build serves the
286
+ root, the versioned copy and the package alike — and the versioned copy, being the same
287
+ bytes as the unversioned one, costs the repository nothing to keep.
288
+
289
+ ## 0.10.1 - 2026-09-16
290
+
291
+ * [Fix] The package a host installs from npm can be bundled
292
+
293
+ Every controller reaches Bootstrap's classes through the bare `bootstrap` specifier, which
294
+ this repo's own build aliases to the bundle under `vendor/`. A host installing the package
295
+ had neither: Bootstrap 6 is not on npm, and `exports` did not name the vendored bundle, so
296
+ the alias that would have fixed it could not resolve either. The bundle is exported as
297
+ `houseaccount/bootstrap`, and the README says which alias to point at it.
298
+
299
+ ## 0.10.0 - 2026-09-14
300
+
301
+ * [Fix] A page is as tall as the window a phone actually shows
302
+
303
+ The body asked for `100vh`, which on a phone measures the window with the browser's own
304
+ bars hidden — they are not, until somebody scrolls. So every flow page stood taller than
305
+ what could be seen: a scrollbar where the content fit, and a foot resting below the fold
306
+ that cost a scroll to reach. `100svh` is the window with the bars showing, and the body
307
+ wears `house-page` for it rather than Bootstrap's `min-vh-100`.
308
+
309
+ * [Change] A new set of trades on the wall, and the house's mark among them
310
+
311
+ Thirteen drawings rather than fourteen: the roller, ladder, frame, plunger, can, hard hat,
312
+ spray, lock, plug, broom, nut, level and the cube. The four apps' own marks are gone from
313
+ it, and with them the grid that placed each one deliberately — every mark is dealt the
314
+ same way now, the cube included.
315
+
316
+ ## 0.9.0 - 2026-09-14
317
+
318
+ * [Breaking change] A one-time code carries the line for the phone again
319
+
320
+ 0.8.0 took `@host #code` out because it is plainly visible in the message that arrives.
321
+ Visible is what it is for: it is Apple's own format, it tells a reader which site the code
322
+ belongs to, and it binds the code to that domain so no other site can ask for it. Without
323
+ it iOS falls back to guessing at the text, which it does not do reliably — the suggestion
324
+ above the keyboard stopped appearing. `HouseAccount.one_time_code` takes `host:` again,
325
+ defaulting to the application's own.
326
+
327
+ * [Fix] A seventh digit leaves no bar behind in the first slot
328
+
329
+ The real field lies transparently across all six slots, and its hidden text sits crammed
330
+ against the left edge rather than under them. A keystroke iOS cannot place answers by
331
+ selecting inside that field, and the grab handles it draws for a selection are its own to
332
+ paint — so one surfaced over the first slot. The selection is collapsed back to the end
333
+ once the code is whole.
334
+
335
+ ## 0.8.1 - 2026-09-14
336
+
337
+ * [Fix] The wall is drawn again after a page Turbo morphs
338
+
339
+ A refresh in place is told what the server sent, and the server sends no wall, so the
340
+ cyanotype came down on any page that redirected to itself — a form refused, say — and the
341
+ controller, still connected, never heard of it.
342
+
343
+ ## 0.8.0 - 2026-09-14
344
+
345
+ * [Breaking change] A one-time code is the sentence alone, without the line for the phone
346
+
347
+ `written` carried a second paragraph, `@host #code`, there for Safari and iOS to read and
348
+ offer the code above the keyboard. It is plainly visible in the message that arrives, so it
349
+ is gone: `written` is now the sentence `spoken` says, with its digits together, and
350
+ `HouseAccount.one_time_code` no longer takes `host:`.
351
+
352
+ ## 0.7.0 - 2026-09-14
353
+
354
+ ## 0.6.0 - 2026-09-14
355
+
356
+ * [Breaking change] `HouseAccount.one_time_code` answers the words in both voices
357
+
358
+ It gave back the text a code is sent in; it gives back a `HouseAccount::Copy` now, whose
359
+ `written` is that same text and whose `spoken` is the sentence alone with the digits one at
360
+ a time, for an app reading a code out over a call. Every caller gains `.written`.
361
+
362
+ ## 0.5.0 - 2026-09-14
363
+
364
+ * [Feature] The `map` controller draws a page's rows on a Google map
365
+
366
+ `data-controller='map'` on an element sized for it, with the host's key and map ID in
367
+ `map-key-value` and `map-id-value`, draws the rows of a page: `map-places-value`, a list
368
+ of Google place IDs, filled in as areas on the boundary layer `map-boundary-value` names —
369
+ `POSTAL_CODE`, `ADMINISTRATIVE_AREA_LEVEL_2` — or pinned where no layer is named, and
370
+ `map-points-value`, a list of `[latitude, longitude]` pairs, pinned as they are. The map
371
+ is fitted round whatever it drew, and `.recourse-map` gives it the height a table takes.
372
+ Recourse's `.map` pages are what name it.
373
+
374
+ ## 0.4.0 - 2026-09-14
375
+
376
+ * [Feature] `houseaccount_icons` names an app's icons on its own, and answers recourse's head
377
+
378
+ The four icon links `houseaccount_head_tags` wrote are a helper of their own, for a head
379
+ the host draws itself, taking another app of the family by name where a page should wear
380
+ the house's cube rather than the app's. The gem also ships `recourses/_head.html.erb`
381
+ calling it, so a host of recourse 5.1 wears its own cube on every admin tab with nothing
382
+ written.
383
+
384
+ * [Fix] The site answers a missing path with the not-found page, not the showcase
385
+
386
+ Cloudflare Pages serves `index.html` at 200 for any path without a file unless a root
387
+ `404.html` exists; a stylesheet asked for at a version the site did not carry came back
388
+ as HTML. The branded not-found page now sits at the root as well.
389
+
390
+ * [Fix] A chat's field takes focus without scrolling the page to it
391
+
392
+ The showcase opened scrolled down to its chat, since the thread controller focused the
393
+ field on load and the browser followed. Focus no longer scrolls; a chat page is sized to
394
+ the window, so its field is in view regardless.
395
+
396
+ ## 0.3.1 - 2026-09-14
397
+
398
+ * [Fix] The gem ships its layout
399
+
400
+ 0.3.0 left `app/views` out of the gem along with the sources the build compiles, so a
401
+ host asking for `layout 'houseaccount'` found no template. The layout ships; the
402
+ JavaScript, stylesheet and font sources still stay behind.
403
+
404
+ ## 0.3.0 - 2026-09-14
405
+
406
+ * [Fix] A chat scrolls inside its card, and the page stands still
407
+
408
+ The flow holding a thread is a flex item of `main`, and `flex: 1` sized it to its content
409
+ over the height it was given, so a long thread grew the page and the way out scrolled off.
410
+ The column is `flex: none` at the window's height now, and only the thread scrolls.
411
+
412
+ * [Fix] Sending a question keeps the reader where they were
413
+
414
+ The ask form under a chat asks Turbo to `replace`, so the redirect back to the page it is
415
+ on is a refresh — morphed in place, scroll kept — rather than a visit landing at the top.
416
+
417
+ * [Fix] A Turbo refresh morphs the page and keeps the scroll
418
+
419
+ The head tags now say `turbo-refresh-method: morph` and `turbo-refresh-scroll: preserve`,
420
+ so an answer landing in a thread leaves the reader at the bottom where they typed, rather
421
+ than at the top of a page drawn again. The layout also names `HouseAccount.app` by its
422
+ current spelling where a page has no title of its own.
423
+
424
+ * [Feature] `flow` draws the page of a signup flow around a card
425
+
426
+ The mark over the wall, a title, a line, one card and the way out, from a host layout's
427
+ one call. The view says its words in `content_for` — `:title`, `:subtitle` and `:width`,
428
+ the card's, which is how a chat's page gets a wider card than a form's — and the layout
429
+ passes `footer:`, pieces joined by a middot, and `logo:`. The column and the card are the
430
+ gem's rules again, `.flow` and `.flow-card`.
431
+
432
+ * [Fix] No gutter is kept for a scrollbar a page has not got
433
+
434
+ Bootstrap 6 reserves the column on every page; a browser with classic scrollbars painted
435
+ its empty track beside a page that fit. The gutter now appears with the scrollbar alone.
436
+
437
+ * [Fix] The versioned copy follows the build until the version is tagged
438
+
439
+ The head helper links `/v<version>/`, and that folder was written once and left, so a
440
+ host reading the gem from a path kept the stylesheet of the day the folder was made.
441
+ Every build now rewrites it until `v<version>` is tagged, and never after.
442
+
443
+ * [Feature] `HouseAccount.one_time_code` is the text that carries a code
444
+
445
+ Every app texting a 6-digit code sends the same two lines, the sentence and the
446
+ `@host #code` Safari reads a code from, and reads them off the gem's locale file rather
447
+ than keeping a copy of its own.
448
+
449
+ * [Breaking change] The constant is `HouseAccount`
450
+
451
+ `HouseAccount::Message`, `HouseAccount::Engine`, `HouseAccount.app`: the house's name
452
+ as the house writes it. The gem and the npm package stay `houseaccount`, since a gem's
453
+ name fixes only the file Bundler requires.
454
+
455
+ * [Feature] A host's layout nests on the gem's
456
+
457
+ A layout hands its page over as `content_for :content` and renders the gem's as a
458
+ template; the bare layout's body now fills the window. The wall stays the gem's, from
459
+ `data-controller='wall'`; what a host draws in front of it, a column and a card say, is
460
+ the host's to style.
461
+
462
+ * [Fix] Body text is Bootstrap's own, and a chat bubble has its sheen back
463
+
464
+ The stylesheet set every page to Helvetica at 14px, a choice made for tables that came
465
+ over with their rules; a page a customer reads on a phone wants Bootstrap's system face at
466
+ 16px, and a host wanting another sets the two properties itself. A bubble wears
467
+ `--bs-gradient` again, as a message thread's do.
468
+
469
+ * [Feature] `dialog` draws a link and the dialog it opens
470
+
471
+ Bootstrap's `<dialog>` with a heading, an X, the block and an `Okay`, and the link that
472
+ opens it through the plugin's own `data-bs-toggle`, sharing an id made from the link's
473
+ words — so no page writes the markup or invents a name, and the `dialog` controller
474
+ carried here from fountain goes.
475
+
476
+ * [Fix] A phone field refuses an eleventh digit rather than taking it and cutting it back
477
+
478
+ A submit shut until the field is valid saw the eleven digits before the format cut them
479
+ to ten, and stayed shut. The key is refused on a full field; a whole number pasted or
480
+ autofilled is reshaped and the field says `input` again; and the country code a number
481
+ arrives with is dropped, since no NANP area code starts with a 1 — which is what
482
+ fountain's `national` controller did on its own.
483
+
484
+ * [Feature] `notices` draws the flash as toasts
485
+
486
+ Every message in the flash as a toast at the bottom right — green for a notice, red for
487
+ an alert, neutral for a key of the host's own — visible at first paint, held while read
488
+ and gone after a moment, the way recourse shows them. The gem's layout calls it, so a
489
+ page it draws shows what a redirect had to say.
490
+
491
+ * [Feature] `HouseAccount::FormBuilder` is the house's form, `pin_field` included
492
+
493
+ Given as `builder:` or a controller's `default_form_builder`: `fieldset` is the one-column
494
+ grid a form's controls sit in, with a legend where given, a label is a `form-label`, a
495
+ text or phone field a large control, the phone one shaped by the `phone` controller as it
496
+ is typed, a submit or a button the solid pill, a `type: :button` one the outlined pill, and a
497
+ disabled one given a `title` says why on hover — `Available soon` — from a wrapper that
498
+ hears the mouse for it. `pin_field` is one real field rendered by Bootstrap
499
+ as six slots, with the `otp` controller from fountain: the slots drawn on a Turbo visit, a pasted or autofilled code sent on its own,
500
+ a refused one kept with the caret at its end.
501
+
502
+ * [Feature] A `<select data-controller='combobox'>` is Bootstrap's combobox, and any `data-turbo-confirm` asks through a dialog
503
+
504
+ The bundle dresses a select — a toggle, a menu with a search box, a check per pick where
505
+ it is `multiple`, an `All` row, a figure beside an option — and keeps the select as what
506
+ the form submits, announcing a pick as its own `change`. Recourse and any app write a
507
+ select and nothing more. The confirm dialog is built by the bundle on the first ask, so
508
+ no page has to carry the markup, and its answer wears the words of the button that asked.
509
+
510
+ * [Feature] Faster first paint: the icon font cut to the glyphs the house draws, Quicksand served from here, and a page's own version linked and kept for a year
511
+
512
+ Bootstrap Icons shipped two thousand glyphs in 134 KB; `art/icons.txt` names the ones a
513
+ HouseAccount page may draw and `rake icons` cuts the font and its stylesheet to those.
514
+ Quicksand comes from `/font` rather than Google, so no page reaches another origin. The
515
+ engine serves this version's copy under `/v<version>/`, cached immutable, and
516
+ `houseaccount_head_tags` links it, so a returning reader fetches nothing.
517
+
518
+ ## 0.2.0 - 2026-09-13
519
+
520
+ * [Feature] The front end of every HouseAccount app, extracted from recourse and the apps
521
+
522
+ One stylesheet and one script — Bootstrap 6 alpha, Bootstrap Icons, Turbo, Stimulus and the
523
+ twenty controllers behind the house's pages — served by the engine at `/css/houseaccount.css`
524
+ and `/js/houseaccount.js`, and published at https://design.houseaccount.com under the same
525
+ paths for a page not on the gem. The nine palettes under `/theme`, every app's mark under
526
+ `/logo` and `/favicon`, and the five error pages under `/page`, which the engine answers a
527
+ failing request with.
528
+
529
+ * [Feature] `houseaccount_head_tags`, `houseaccount_logo`, `chat_with` and `houseaccount_url`
530
+
531
+ A head, a lockup and a thread of bubbles drawn the same way in every app. Which app a host
532
+ is, the gem reads off the Rails application's name, and the head and the down page follow
533
+ it; `houseaccount_logo app: :fountain` draws any of the family's marks seated by its own numbers beside its
534
+ name. `chat_with url:, hints:, messages:` takes messages answering `side`, `text`, `sender`,
535
+ `at`, `delivery` and `cost`, or `HouseAccount::Message`s, and the URL the next one posts to.
536
+
537
+ * [Feature] A layout for a page recourse does not draw
538
+
539
+ `layout 'houseaccount'` on a controller gives a page the shared head — charset, title,
540
+ CSRF and CSP metas, the stylesheet, the script and the icons — then `yield :head`, then
541
+ the page inside `<body>`. `content_for :title` names it; the app's own name stands in.
542
+
543
+ * [Feature] The page an app shows while it is down
544
+
545
+ Its own mark in the middle and the house's at the foot, rendered per app into `/down/<app>.html`
546
+ and answered at `/down.html` by the engine for the app the host named. The design site
547
+ has a mark of its own, a pencil, and wears it.
548
+
549
+ * [Feature] Every release is kept at its own versioned URL
550
+
551
+ `/v0.2.0/css/houseaccount.css` and its script, fonts and palettes stand beside the
552
+ unversioned copies, whole on their own and cached for a year, so a page may pin a
553
+ version and move when it chooses. `rake version` writes a folder once per release.
554
+
555
+ * [Feature] The signup flow's wall of drifting tools, from one attribute
556
+
557
+ `data-controller='wall'` on a page's shell draws the cyanotype of trades and the family's
558
+ marks behind it, from geometry the bundle carries; `.flow-shell`, `.flow-main` and
559
+ `.welcome-card` are the classes the page in front of it wears.
560
+
561
+ * [Feature] A phone is formatted in the browser
562
+
563
+ The server hands over ten digits and `data-controller='phone'`; the controller decides
564
+ `555-555-5555` on a cell and on a field, and gives the field its pattern and placeholder.
565
+
566
+ ## 0.1.0 - 2026-08-27
567
+
568
+ * A library that loads and does not do anything yet.
data/MIT-LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2026 Claudio Baccigalupo
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.