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