@kurtbruns/kestrel 1.20.0 → 1.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.
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>Kestrel</title>
7
7
  <link rel="icon" href="/favicon.svg">
8
- <link rel="stylesheet" href="./styles.css?v=00bc34db">
8
+ <link rel="stylesheet" href="./styles.css?v=aacdaf66">
9
9
  <script>
10
10
  // Sidebar mode guard — set the width-based data-nav on <html> before first paint so the
11
11
  // sidebar renders in its final width with no flash. The collapse toggle's override is
@@ -116,6 +116,6 @@
116
116
  </section>
117
117
  <div id="toasts" role="status" aria-live="polite"></div>
118
118
 
119
- <script src="./app.js?v=0af2b352"></script>
119
+ <script src="./app.js?v=e3dbd207"></script>
120
120
  </body>
121
121
  </html>
@@ -2,7 +2,13 @@
2
2
  prefers-color-scheme (see the dark block below). This is the admin surface's own
3
3
  palette — independent of, and never loaded alongside, the reader/email-card
4
4
  `TOKENS` in src/lib/page.ts. The two reuse names like --muted and --bg with
5
- different values on purpose; don't assume they share meaning. */
5
+ different values on purpose; don't assume they share meaning.
6
+
7
+ Specificity, not source order, decides this file's cascade, so rules stay grouped by
8
+ component. That is why Biome's noDescendingSpecificity is off in biome.json, which takes no
9
+ comments: it compares selectors by their last element alone, so `#settingsBtn svg` outranks
10
+ every later `svg` rule, components that never nest included, and satisfying it would mean
11
+ moving rules out of their sections, changing the cascade to fix nothing. */
6
12
  :root {
7
13
  color-scheme: light dark;
8
14
  /* Layering — one named z-index ladder (DESIGN §9). Every fixed or floating surface
@@ -1197,7 +1203,6 @@ body.tool-mode .content {
1197
1203
  }
1198
1204
  }
1199
1205
 
1200
- /* biome-ignore lint/style/noDescendingSpecificity: specificity (not source order) decides the cascade; base rule grouped here intentionally */
1201
1206
  button {
1202
1207
  font-family: inherit;
1203
1208
  font-size: 14px;
@@ -1524,7 +1529,6 @@ td a {
1524
1529
  text-decoration: none;
1525
1530
  font-weight: 500;
1526
1531
  }
1527
- /* biome-ignore lint/style/noDescendingSpecificity: specificity (not source order) decides the cascade; hover rule grouped with its base */
1528
1532
  td a:hover {
1529
1533
  text-decoration: underline;
1530
1534
  }
@@ -1942,6 +1946,24 @@ th.num .th-sort {
1942
1946
  cursor: default;
1943
1947
  }
1944
1948
 
1949
+ /* A labelled block (a code block, or the API reference's query and content-type tables):
1950
+ its label line, then the block. Ahead of the sections below, which refine it. */
1951
+ .block {
1952
+ margin-top: 10px;
1953
+ }
1954
+ .block-head {
1955
+ display: flex;
1956
+ align-items: center;
1957
+ justify-content: space-between;
1958
+ margin: 8px 0 4px;
1959
+ }
1960
+ .block-label {
1961
+ display: block;
1962
+ font-size: 12px;
1963
+ font-weight: 600;
1964
+ color: var(--muted);
1965
+ }
1966
+
1945
1967
  /* A route's or an object's sections (query, body, returns, refusals, fields) as Stripe's and
1946
1968
  Mux's references set theirs: a heading over a rule, then unboxed rows, each with the name,
1947
1969
  its type, and Required on one line and what it means under it, so a long name never
@@ -4148,6 +4170,11 @@ button.api-filter-clear svg {
4148
4170
  max-width: 1440px;
4149
4171
  line-height: 1.5;
4150
4172
  }
4173
+ /* A resource: its heading over a rule, scrolling with its routes. */
4174
+ .api-res {
4175
+ margin-top: 16px;
4176
+ scroll-margin-top: var(--bar-h);
4177
+ }
4151
4178
  /* One reading measure for the page, a doc page's (720px): the intro, the topics, and each
4152
4179
  route's and object's prose and tables keep it, and only a route's examples, beside its
4153
4180
  prose on a wide screen, reach past it. */
@@ -4192,11 +4219,6 @@ button.api-filter-clear svg {
4192
4219
  margin: 0 0 10px;
4193
4220
  font-size: 14px;
4194
4221
  }
4195
- /* A resource: its heading over a rule, scrolling with its routes. */
4196
- .api-res {
4197
- margin-top: 16px;
4198
- scroll-margin-top: var(--bar-h);
4199
- }
4200
4222
  /* A resource's heading, set like the page's other headings, flush with the text: it only
4201
4223
  pins under the bar, its vertical padding the band the rows scroll beneath. */
4202
4224
  .api-res-head {
@@ -4992,20 +5014,10 @@ button.copy-btn.api-copy-path {
4992
5014
  }
4993
5015
 
4994
5016
  /* --- copying text out of the app (DESIGN §7, ui/copy.ts) ---
4995
- A labelled block (a code block, or the API reference's query and content-type tables):
4996
- its label line, then the block. The Copy is a control outside the five roles: the word
4997
- and its glyph, no fill or border, quiet on the line it shares; the glyph turns to a
4998
- check in the ok hue for a moment once a copy has landed, and the word stays. A Copy
4999
- beside a single value (an address) is the same control. --- */
5000
- .block {
5001
- margin-top: 10px;
5002
- }
5003
- .block-head {
5004
- display: flex;
5005
- align-items: center;
5006
- justify-content: space-between;
5007
- margin: 8px 0 4px;
5008
- }
5017
+ The Copy is a control outside the five roles: the word and its glyph, no fill or border,
5018
+ quiet on the line it shares; the glyph turns to a check in the ok hue for a moment once a
5019
+ copy has landed, and the word stays. A Copy beside a single value (an address) is the same
5020
+ control. --- */
5009
5021
  button.copy-btn {
5010
5022
  display: inline-flex;
5011
5023
  align-items: center;
@@ -5037,12 +5049,6 @@ button.copy-btn svg {
5037
5049
  button.copied svg {
5038
5050
  color: var(--ok-fg);
5039
5051
  }
5040
- .block-label {
5041
- display: block;
5042
- font-size: 12px;
5043
- font-weight: 600;
5044
- color: var(--muted);
5045
- }
5046
5052
  /* A code block (an example, a curl command, a template): a raised card with its label and Copy
5047
5053
  in a header inside it, so the code stands apart from the page in both themes. */
5048
5054
  .code-block {
@@ -5122,6 +5128,13 @@ button.copied svg {
5122
5128
  align-items: center;
5123
5129
  gap: 12px;
5124
5130
  margin: 0 0 14px;
5131
+ scroll-margin-top: 20px; /* a link to the section leaves its title room at the top */
5132
+ }
5133
+ @media (max-width: 539px) {
5134
+ /* The phone's floating menu button, 52px tall from the top, would cover the title. */
5135
+ .set-sec-head {
5136
+ scroll-margin-top: 60px;
5137
+ }
5125
5138
  }
5126
5139
  .set-sec-title {
5127
5140
  margin: 0;
@@ -5234,6 +5247,7 @@ button.copied svg {
5234
5247
  min-width: 0;
5235
5248
  }
5236
5249
  .set-logo-tile {
5250
+ position: relative;
5237
5251
  width: 100%;
5238
5252
  aspect-ratio: 1;
5239
5253
  border-radius: 10px;
@@ -5253,6 +5267,22 @@ button.copied svg {
5253
5267
  .set-logo-tile:hover {
5254
5268
  border-color: var(--accent);
5255
5269
  }
5270
+ .set-logo-tile.dragover::after {
5271
+ content: "Drop to upload";
5272
+ position: absolute;
5273
+ inset: 0;
5274
+ display: flex;
5275
+ align-items: center;
5276
+ justify-content: center;
5277
+ padding: 8px;
5278
+ border: 2px dashed var(--ring);
5279
+ border-radius: inherit;
5280
+ background: color-mix(in srgb, var(--ring) 14%, var(--card));
5281
+ color: var(--fg);
5282
+ font-size: 11px;
5283
+ font-weight: 600;
5284
+ text-align: center;
5285
+ }
5256
5286
  .set-logo-ph {
5257
5287
  display: flex;
5258
5288
  flex-direction: column;
@@ -5526,29 +5556,38 @@ button.set-field-remove {
5526
5556
  margin-top: 5px;
5527
5557
  }
5528
5558
 
5529
- /* --- confirmation email: the rendered card + the words-only edit body ---
5530
- The card colors are LITERALS matching src/emails/system.ts, which now ships light+dark
5531
- (its `prefers-color-scheme` block). The light literals are here; a dark @media block
5532
- below overrides them with the email's dark palette, so the preview tracks the dashboard
5533
- theme and stays byte-honest about what a light- or dark-mode inbox receives. */
5559
+ /* --- confirmation email: the rendered preview + the words-only edit body ---
5560
+ The stage and column copy the email's frame in src/emails/system.ts, and their colors are
5561
+ LITERALS matching its light and dark palettes (its `prefers-color-scheme` block). The
5562
+ light literals are here; a dark @media block below overrides them, so the preview tracks
5563
+ the dashboard theme and shows what a light- or dark-mode inbox receives. */
5564
+ /* The top border is the app's, not the email's: it keeps the inbox row above from reading as
5565
+ part of an email whose page is the same white. */
5534
5566
  .set-ce-stage {
5535
- background: #f4f4f5;
5536
- padding: 22px 18px;
5567
+ border-top: 1px solid var(--line);
5568
+ background: #ffffff;
5569
+ padding: 8px 12px 48px;
5537
5570
  }
5538
- .set-ce-card {
5539
- max-width: 440px;
5571
+ .set-ce-col {
5572
+ max-width: 664px;
5540
5573
  margin: 0 auto;
5541
- background: #ffffff;
5542
- border-radius: 8px;
5543
- padding: 28px 26px;
5544
- font-size: 15px;
5574
+ padding: 24px 32px 32px;
5575
+ font-size: 16px;
5545
5576
  line-height: 1.6;
5546
5577
  color: #18181b;
5578
+ word-break: break-word;
5579
+ }
5580
+ /* The email's narrow rule, at its width, so a phone sees what its inbox will show. */
5581
+ @media (max-width: 560px) {
5582
+ .set-ce-col {
5583
+ padding-left: 12px;
5584
+ padding-right: 12px;
5585
+ }
5547
5586
  }
5548
5587
  .set-ce-msg {
5549
5588
  margin: 0 0 20px;
5550
5589
  }
5551
- /* Publication masthead inside the preview card, matching masthead() in
5590
+ /* Publication masthead inside the preview, matching masthead() in
5552
5591
  src/emails/system.ts (logo beside name + tagline, over a hairline rule). Light
5553
5592
  literals here; the dark @media block below carries the dark overrides. */
5554
5593
  .set-ce-mast {
@@ -5638,8 +5677,6 @@ button.set-field-remove {
5638
5677
  color: #ffffff;
5639
5678
  border-radius: 6px;
5640
5679
  text-decoration: none;
5641
- font-size: 15px;
5642
- font-weight: 500;
5643
5680
  }
5644
5681
  .set-ce-foot {
5645
5682
  color: #71717a;
@@ -5660,17 +5697,15 @@ button.set-field-remove {
5660
5697
  .set-ce-editfoot .grow {
5661
5698
  flex: 1;
5662
5699
  }
5663
- /* Dark rendering of the preview card — the email's dark palette (the reader card pages'
5664
- tokens: page #18181b, card #232327, ink #ededed, muted #a1a1aa, rule #2e2e33, accent
5665
- button #e5e7eb/#18181b), matching the `prefers-color-scheme` block in
5666
- src/emails/system.ts. Overrides only the card literals; the edit body + chrome around
5667
- it already theme via the --* tokens. */
5700
+ /* Dark rendering of the preview: the email's dark palette (page #18181b, ink #ededed,
5701
+ muted #a1a1aa, rule #2e2e33, accent button #e5e7eb/#18181b), matching the
5702
+ `prefers-color-scheme` block in src/emails/system.ts. Overrides only the preview's
5703
+ literals; the edit body + chrome around it already theme via the --* tokens. */
5668
5704
  @media (prefers-color-scheme: dark) {
5669
5705
  .set-ce-stage {
5670
5706
  background: #18181b;
5671
5707
  }
5672
- .set-ce-card {
5673
- background: #232327;
5708
+ .set-ce-col {
5674
5709
  color: #ededed;
5675
5710
  }
5676
5711
  .set-ce-mast {