@iyulab/router 0.14.0 → 0.15.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.15.1] - 2026-09-17
4
+
5
+ ### Fixed
6
+
7
+ - **Printing no longer adds a trailing blank page when a screen's last block has a bottom
8
+ margin.** 0.15.0 made `<u-outlet>` a grid container in every medium. A grid container keeps
9
+ its children's margins inside its own box, so the last block's bottom margin added to the
10
+ outlet's height; when the content ended within that margin of a page boundary, the outlet
11
+ spilled onto a page that held only the margin. In print media the outlet is now a block box,
12
+ which lets the margin collapse past it and be truncated at the page break:
13
+
14
+ ```css
15
+ @media print { :where(u-outlet) { display: block; } }
16
+ ```
17
+
18
+ Screen layout is unchanged. The grid only matters when the parent has a definite height, and
19
+ an application shell normally sets one for screen media only.
20
+
21
+ ## [0.15.0] - 2026-09-16
22
+
23
+ ### Changed
24
+
25
+ - **`<u-outlet>` now grows when a screen overflows a fixed-height parent.** 0.14.0 declared
26
+ `display: block; height: 100%`, which gives a screen the height it needs to fill a sized
27
+ parent but also pins the outlet to exactly that height. A screen taller than the parent
28
+ therefore overflowed the outlet's box instead of growing it, and a scrolling ancestor adds
29
+ its end padding to the scrollable area of its *in-flow children*, not of what those children
30
+ overflow with. The end gutter dropped out of the scrollable area: scrolling to the bottom of
31
+ a long screen left the content flush against the container's edge, while the gutter survived
32
+ on the other three sides.
33
+
34
+ Swapping `height` for `min-height` is not the fix. A percentage height only resolves against
35
+ a parent whose `height` is specified, and a minimum does not satisfy that — so on a block (or
36
+ flex) box a descendant's `height: 100%` computes to `auto`, and every layout built to fill the
37
+ viewport collapses to its content height.
38
+
39
+ A grid container gives both behaviors at once. A grid item stretches to its area by default,
40
+ which fills without resolving a percentage, so the chain survives while the container's own
41
+ height is indefinite — and because that height is `auto`, the box grows past the minimum when
42
+ content demands it. The rule is now:
43
+
44
+ ```css
45
+ :where(u-outlet) { display: grid; min-height: 100%; }
46
+ ```
47
+
48
+ Multiple children behave as before: a track stretches, but an item with a definite height does
49
+ not. The rule deliberately omits `align-content` and relies on the initial `normal` — setting
50
+ `align-content: start` stops the track from stretching and silently voids the fill chain.
51
+
52
+ Specificity is still zero, so an application's own `u-outlet { … }` rule wins without
53
+ `!important`, exactly as in 0.14.0. `u-outlet { display: block; height: 100% }` restores the
54
+ 0.14.0 box model and `u-outlet { display: inline }` restores the pre-0.14.0 one.
55
+
56
+ ### Contract addition
57
+
58
+ - **Making the outlet *smaller* now takes two declarations.** `min-height` is a floor, so
59
+ `u-outlet { height: 200px }` on its own still measures the parent's height. Write
60
+ `u-outlet { min-height: 0; height: 200px }`. Making the outlet larger, or replacing its
61
+ `display`, needs nothing extra. This is the only behavioral difference for an application
62
+ that was already overriding the rule.
63
+
64
+ ### Tests
65
+
66
+ - The browser suite covering the outlet's box model grows from 9 cases to 15. The overflow
67
+ topology — a parent with a definite height holding a taller child — was not covered before,
68
+ which is why the previous rule shipped green: the suite pinned "an auto-height parent leaves
69
+ the outlet auto" but never its opposite. Also pinned now: the two-declaration override above,
70
+ multiple children keeping their own heights, and `align-content` breaking the fill chain.
71
+
3
72
  ## [0.14.0] - 2026-09-16
4
73
 
5
74
  ### Changed
package/README.md CHANGED
@@ -143,33 +143,76 @@ const routes = [
143
143
 
144
144
  ## Outlet Layout
145
145
 
146
- `<u-outlet>` declares its own `display: block`. A custom element's UA default is
147
- `inline`, which would put a route's block-level screen inside an inline box — so the
148
- outlet adopts a single rule on whichever tree it is connected to (the document, or the
149
- shadow root if it lives in one):
146
+ `<u-outlet>` declares its own box model. A custom element's UA default is `inline`, which
147
+ would put a route's block-level screen inside an inline box — so the outlet adopts its
148
+ rules on whichever tree it is connected to (the document, or the shadow root if it lives in
149
+ one):
150
150
 
151
151
  ```css
152
- :where(u-outlet) { display: block; height: 100%; }
152
+ :where(u-outlet) { display: grid; min-height: 100%; }
153
+ @media print { :where(u-outlet) { display: block; } }
153
154
  ```
154
155
 
155
- `height: 100%` is part of the same rule for a reason. A percentage height resolves against
156
- the nearest block container, so making the outlet a block moves that reference from the box
157
- *above* the outlet onto the outlet itself — and an `auto` height there voids the percentage
158
- silently, collapsing a full-height screen to its content height. Declaring `height: 100%`
159
- keeps the chain intact, and resolves to `auto` whenever the parent's height is `auto`, so
160
- ordinary document flow and printing are unaffected.
156
+ The outlet has to be two things at once, and no single declaration gives both:
161
157
 
162
- The `:where()` wrapper makes the rule's specificity zero, so **any** `u-outlet { }`
163
- rule your application writes wins, regardless of sheet order and without `!important`:
158
+ 1. **It passes a sized parent's height down**, so a screen's `height: 100%` resolves here.
159
+ 2. **It grows with a screen taller than the parent**, so the overflow stays inside the
160
+ outlet's box rather than escaping it.
161
+
162
+ `height: 100%` gives only the first. It pins the outlet to the parent's height, so a taller
163
+ screen overflows the outlet — and a scrolling ancestor adds its end padding to the scrollable
164
+ area of its in-flow children, not of what those children overflow with. The end gutter drops
165
+ out: scrolling to the bottom of a long screen leaves the content flush against the container's
166
+ edge while the gutter survives on the other three sides.
167
+
168
+ `min-height: 100%` alone breaks the first. A percentage height only resolves against a parent
169
+ whose `height` is specified, and a minimum does not satisfy that — so on a block (or flex) box
170
+ a descendant's `height: 100%` computes to `auto` and every fill-the-viewport layout collapses
171
+ to its content height.
172
+
173
+ A grid container gives both. A grid item stretches to its area by default, which fills without
174
+ resolving a percentage, so the chain survives while the container's own height is indefinite —
175
+ and because that height is `auto`, the box grows past the minimum when content demands it.
176
+ Multiple children are unaffected: a track stretches, but an item with a definite height does not.
177
+
178
+ The rule deliberately omits `align-content`; it relies on the initial `normal`. Setting
179
+ `align-content: start` stops the track from stretching and silently voids case 1.
180
+
181
+ When the parent's own height is `auto`, `min-height: 100%` resolves to `auto` too, so ordinary
182
+ document flow is unaffected.
183
+
184
+ ### Printing
185
+
186
+ In print media the outlet is a plain block box instead of a grid container. A grid container is
187
+ an independent formatting context, so the bottom margin of a screen's last block cannot collapse
188
+ through it — the margin lands *inside* the outlet's box and adds to its height. On screen that is
189
+ harmless. On paper it is not: when content ends within that margin of a page boundary, the box
190
+ spills onto a new page that holds nothing but the margin. As a block box, the outlet lets the
191
+ margin collapse past it to the end of the document, and a margin that meets a page break is
192
+ truncated there, so no trailing blank page appears.
193
+
194
+ Print loses nothing by this. The grid exists to pass a *sized* parent's height down, and an
195
+ application shell normally sizes itself to the viewport only for screen media; in print the
196
+ parent's height is `auto`, and `min-height: 100%` resolves to nothing.
197
+
198
+ ### Overriding it
199
+
200
+ The `:where()` wrapper makes both rules' specificity zero, so **any** `u-outlet { … }` rule your
201
+ application writes wins, regardless of sheet order and without `!important`:
164
202
 
165
203
  ```css
166
- u-outlet { display: flex; } /* wins */
167
- u-outlet { height: auto; } /* keep the box, drop the fill */
168
- u-outlet { display: inline; } /* restores the pre-0.14.0 behavior */
169
- @media print { u-outlet { } } /* wins */
204
+ u-outlet { display: flex; } /* wins */
205
+ u-outlet { display: contents; } /* remove the box entirely */
206
+ u-outlet { display: block; height: 100%; } /* restores the 0.14.0 behavior */
207
+ u-outlet { display: inline; } /* restores the pre-0.14.0 behavior */
208
+ @media print { u-outlet { display: grid; } } /* restores the 0.15.0 print behavior */
170
209
  ```
171
210
 
172
- The rule is not media-scoped: the outlet is a block box on screen and in print alike.
211
+ > **Making the outlet *smaller* takes two declarations, not one.** `min-height` is a floor, so
212
+ > `u-outlet { height: 200px }` on its own still measures the parent's height. Write
213
+ > `u-outlet { min-height: 0; height: 200px }`. Making it *larger*, or replacing `display`, needs
214
+ > nothing extra. This is the only contract addition in 0.15.0.
215
+
173
216
 
174
217
  `<u-link>` supports `href`, `target`, `rel`, and `navigate`.
175
218
 
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as isExternalUrl, i as absolutePath, n as __decorate, o as parseUrl, r as __decorateMetadata, s as UOutlet, t as ULink } from "./share-tRZgJ1SR.js";
1
+ import { a as isExternalUrl, i as absolutePath, n as __decorate, o as parseUrl, r as __decorateMetadata, s as UOutlet, t as ULink } from "./share-Cwn-vX3y.js";
2
2
  import { LitElement, css, html } from "lit";
3
3
  import { customElement, property } from "lit/decorators.js";
4
4
  //#region src/types/RouteError.ts
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { s as UOutlet$1, t as ULink$1 } from "./share-tRZgJ1SR.js";
1
+ import { s as UOutlet$1, t as ULink$1 } from "./share-Cwn-vX3y.js";
2
2
  import React from "react";
3
3
  import { createComponent } from "@lit/react";
4
4
  //#region src/react.ts
@@ -12,20 +12,65 @@ import { ifDefined } from "lit/directives/if-defined.js";
12
12
  * 무관하게 `!important` 없이 이긴다.
13
13
  * ⚠constructable 시트(`adoptedStyleSheets`)를 쓴다 — `<style>` 요소와 달리 CSP 의 인라인
14
14
  * 스타일 제한에 걸리지 않는다. 지원하지 않는 환경에서는 `<style>` 로 대신한다.
15
- * ⚠매체를 가르지 않는다 — 인라인 컨테이너는 화면에서도 의도된 적이 없다(라인 박스 때문에
16
- * 높이를 줄 수도, 백분율로 채울 수도 없었다). 인쇄에만 한정하면 화면·인쇄가 서로 다른
17
- * 상자 모델을 갖게 되어 같은 부류의 차이가 다음에 또 난다.
18
- * 🔴`height: 100%` 함께 있어야 한다 `display` 바꾸면 **백분율 높이의 기준 상자가
19
- * 바뀐다.** 종전(inline)에는 아웃렛이 블록 컨테이너가 아니라, 라우트 화면의 `height: 100%`
20
- * «위» 블록(셸의 본문 영역)에 대해 풀렸다. 아웃렛을 block 으로 만들면 기준이
21
- * 아웃렛 자신이 되는데 그 높이가 `auto` 라 백분율이 무효가 되고, 화면을 채우도록 만들어진
22
- * 레이아웃(`u-master-detail-layout` `:host{height:100%}` 등)이 내용 높이로 무너진다.
23
- * 실측(chromium): 같은 화면이 inline 747px block 60px → block+height:100% 747px.
24
- * ⚠부모 높이가 `auto` `100%` `auto` 풀리므로 인쇄(셸이 높이를 놓는다)와 일반
25
- * 문서 흐름에는 영향이 없다 — 이 선언이 «채우기» 를 강요하는 것은 부모가 높이를 가진
26
- * 경우뿐이고, 그것이 종전 동작이다.
15
+ * ⚠«인라인이 아니다» 는 매체를 가르지 않는다 — 인라인 컨테이너는 화면에서도 의도된 적이 없다
16
+ * (라인 박스 때문에 높이를 줄 수도, 백분율로 채울 수도 없었다). 인라인 결함을 인쇄에만 고치면
17
+ * 화면에 같은 결함이 남는다.
18
+ * 🔴**그러나 «어떤 블록 레벨 상자인가» 매체를 가른다** 아래 「인쇄 매체」 절.
19
+ *
20
+ * ## `grid` + `min-height` 인가 요구가 선언으로는 된다
21
+ *
22
+ * 아웃렛은 **동시에 가지**여야 한다:
23
+ * ⑴부모가 높이를 가지면 **그 높이를 자손에게 물려준다**(자손의 `height:100%` 가 여기서 풀린다)
24
+ * ⑵화면이 부모보다 크면 **자기도 함께 자란다**(넘침이 아웃렛 «밖» 으로 새지 않는다)
25
+ *
26
+ * 🔴`height: 100%` 는 ⑴만 준다. 0.14.0 이 그 판이었다 — 콘텐츠 영역이 고정 높이일 때
27
+ * 아웃렛이 그 높이로 **못 박히고**
28
+ * 화면이 밖으로 넘쳐, 스크롤 컨테이너의 끝 패딩이 스크롤 영역에서 빠진다 — 긴 화면을 끝까지
29
+ * 내리면 **내용이 바닥에 붙는다**(거터가 위·좌·우에만 남는다).
30
+ * 🔴`min-height: 100%` 만으로는 ⑴이 깨진다. 백분율 높이는 부모의 **`height`** 가 명시됐을 때만
31
+ * 풀리고 `min-height` 는 그 조건을 만족시키지 않는다(CSS2.1 §10.5) — 그래서 `block` 이든
32
+ * `flex` 든 `min-height` 로 바꾸면 자손의 `height:100%` 가 `auto` 로 풀려 화면이 무너진다.
33
+ * ✅`grid` 만 둘을 함께 준다. 그리드 항목의 기본 `align-self: stretch` 가 «백분율을 푸는 것» 이
34
+ * 아니라 **영역을 채우는 것**이라, 컨테이너 높이가 부정(indefinite)이어도 ⑴이 성립한다.
35
+ * 그리고 컨테이너 높이가 `auto` 라 내용이 크면 ⑵대로 자란다.
36
+ *
37
+ * 실측(chromium · 셸 본문 720px `padding:32px` `overflow:auto` / 화면 1588px):
38
+ *
39
+ * | 규칙 | 전체높이: 표 | 넘침: `scrollHeight` | 아웃렛 박스 |
40
+ * |----------------------------------|-------------:|---------------------:|------------:|
41
+ * | `inline`(0.13.0 이전) | 616 | — | — |
42
+ * | `block; height:100%`(0.14.0) | 616 | 🔴 1620 | 656(고정) |
43
+ * | `contents` | 616 | 1652 | 0(박스 없음)|
44
+ * | **`grid; min-height:100%`** | **616** | **1652** | **1588** |
45
+ * | `flex column; min-height:100%` | 🔴 0 | 1652 | 1588 |
46
+ * | `block; min-height:100%` | 🔴 0 | 1652 | 1588 |
47
+ *
48
+ * ⚠**`contents` 를 택하지 않은 이유는 수치가 아니라 박스다** — 박스가 사라지면 소비자의
49
+ * `u-outlet { padding }`·`{ background }` 와 `getBoundingClientRect()` 가 **오류 없이 아무 일도
50
+ * 안 하게** 된다. 아웃렛이 높이를 끊는 증상 자체가 「내 CSS 가 안 먹는다」로 나타나므로,
51
+ * 그 부류를 새로 만들지 않는다. grid 는 `contents` 의 두 수치를 내면서 박스를 남긴다.
52
+ * ⚠**`align-content` 를 선언하지 말 것** — `start` 를 주면 트랙이 늘어나지 않아 ⑴이 조용히
53
+ * 깨진다(실측: 자손 400px → 0px). 기본값 `normal` 이어야 한다.
54
+ * ⚠**자식이 둘 이상이어도 block 과 같다**(실측: 20px·30px 자식이 각각 20·30 그대로) — 트랙은
55
+ * 늘어나지만 높이가 정해진 항목은 `stretch` 대상이 아니다.
56
+ * ⚠**부모 높이가 `auto` 면 `min-height:100%` 도 `auto` 로 풀린다** — 일반 문서 흐름과 인쇄를
57
+ * 가두지 않는다.
58
+ * 🔴**소비자가 아웃렛을 «줄이려면» `height` 만으로는 부족하고 `min-height: 0` 이 함께 필요하다**
59
+ * — 0.14.0 대비 유일한 계약 추가이며 README·CHANGELOG·참조 문서에 적혀 있다.
60
+ *
61
+ * ## 인쇄 매체 — `block` 으로 돌아간다 (0.15.1)
62
+ *
63
+ * 🔴**grid 는 자기 안에서 여백 접힘을 막는다.** 라우트 화면의 마지막 블록이 `margin-bottom` 을
64
+ * 가지면 그 여백이 아웃렛 높이 «안으로» 들어온다(실측: 내용 300 + 여백 24 → 아웃렛 324).
65
+ * 화면에서는 무해하지만, 인쇄에서는 내용 끝이 쪽 경계에서 그 여백 이내에 있으면 **빈 꼬리 쪽**
66
+ * 이 생긴다. `block` 이면 여백이 문서 끝까지 접혀 나가고, 쪽 경계에 닿은 여백은 조각화에서
67
+ * 잘린다(CSS Fragmentation §5.2) — 소비자 실측: `block` 1쪽 ↔ `grid` 2쪽.
68
+ * ✅**인쇄에서 grid 가 주던 이득은 없다.** grid 의 존재 이유는 ⑴(정해진 부모 높이를 자손에게)
69
+ * 인데, 셸은 뷰포트 높이를 `@media screen` 안에서만 건다 — 인쇄에서 부모 높이는 `auto` 이고
70
+ * `min-height: 100%` 도 0 으로 풀린다. ⇒ 인쇄에서 grid 는 **여백을 가두기만** 한다.
71
+ * ⚠같은 `:where()` 라 특이도 0 그대로다 — 소비자 규칙은 인쇄에서도 `!important` 없이 이긴다.
27
72
  */
28
- var OUTLET_DISPLAY_CSS = ":where(u-outlet) { display: block; height: 100%; }";
73
+ var OUTLET_DISPLAY_CSS = [":where(u-outlet) { display: grid; min-height: 100%; }", "@media print { :where(u-outlet) { display: block; } }"].join("\n");
29
74
  /** 시트를 이미 채택한 트리 — 같은 트리에 두 번 넣지 않는다. */
30
75
  var styledRoots = /* @__PURE__ */ new WeakSet();
31
76
  /**
@@ -1114,12 +1159,12 @@ function catchBasepath(basepath) {
1114
1159
  return basepath;
1115
1160
  }
1116
1161
  //#endregion
1117
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorateMetadata.js
1162
+ //#region \0@oxc-project+runtime@0.150.0/helpers/esm/decorateMetadata.js
1118
1163
  function __decorateMetadata(k, v) {
1119
1164
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1120
1165
  }
1121
1166
  //#endregion
1122
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
1167
+ //#region \0@oxc-project+runtime@0.150.0/helpers/esm/decorate.js
1123
1168
  function __decorate(decorators, target, key, desc) {
1124
1169
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1125
1170
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iyulab/router",
3
- "version": "0.14.0",
3
+ "version": "0.15.1",
4
4
  "description": "A modern client-side router for web applications with support for Lit and React components",
5
5
  "keywords": [
6
6
  "lit",
@@ -40,33 +40,77 @@ export function AppRoot() {
40
40
 
41
41
  ## Outlet Layout
42
42
 
43
- `<u-outlet>` declares its own `display: block`. A custom element's UA default is
44
- `inline`, which would put a route's block-level screen inside an inline box — so the
45
- outlet adopts a single rule on whichever tree it is connected to (the document, or the
46
- shadow root if it lives in one):
43
+ `<u-outlet>` declares its own box model. A custom element's UA default is `inline`, which
44
+ would put a route's block-level screen inside an inline box — so the outlet adopts its
45
+ rules on whichever tree it is connected to (the document, or the shadow root if it lives in
46
+ one):
47
47
 
48
48
  ```css
49
- :where(u-outlet) { display: block; height: 100%; }
49
+ :where(u-outlet) { display: grid; min-height: 100%; }
50
+ @media print { :where(u-outlet) { display: block; } }
50
51
  ```
51
52
 
52
- `height: 100%` is part of the same rule for a reason. A percentage height resolves against
53
- the nearest block container, so making the outlet a block moves that reference from the box
54
- *above* the outlet onto the outlet itself — and an `auto` height there voids the percentage
55
- silently, collapsing a full-height screen to its content height. Declaring `height: 100%`
56
- keeps the chain intact, and resolves to `auto` whenever the parent's height is `auto`, so
57
- ordinary document flow and printing are unaffected.
53
+ The outlet has to be two things at once, and no single declaration gives both:
58
54
 
59
- The `:where()` wrapper makes the rule's specificity zero, so **any** `u-outlet { }`
60
- rule your application writes wins, regardless of sheet order and without `!important`:
55
+ 1. **It passes a sized parent's height down**, so a screen's `height: 100%` resolves here.
56
+ 2. **It grows with a screen taller than the parent**, so the overflow stays inside the
57
+ outlet's box rather than escaping it.
58
+
59
+ `height: 100%` gives only the first. It pins the outlet to the parent's height, so a taller
60
+ screen overflows the outlet — and a scrolling ancestor adds its end padding to the scrollable
61
+ area of its in-flow children, not of what those children overflow with. The end gutter drops
62
+ out: scrolling to the bottom of a long screen leaves the content flush against the container's
63
+ edge while the gutter survives on the other three sides.
64
+
65
+ `min-height: 100%` alone breaks the first. A percentage height only resolves against a parent
66
+ whose `height` is specified, and a minimum does not satisfy that — so on a block (or flex) box
67
+ a descendant's `height: 100%` computes to `auto` and every fill-the-viewport layout collapses
68
+ to its content height.
69
+
70
+ A grid container gives both. A grid item stretches to its area by default, which fills without
71
+ resolving a percentage, so the chain survives while the container's own height is indefinite —
72
+ and because that height is `auto`, the box grows past the minimum when content demands it.
73
+ Multiple children are unaffected: a track stretches, but an item with a definite height does not.
74
+
75
+ The rule deliberately omits `align-content`; it relies on the initial `normal`. Setting
76
+ `align-content: start` stops the track from stretching and silently voids case 1.
77
+
78
+ When the parent's own height is `auto`, `min-height: 100%` resolves to `auto` too, so ordinary
79
+ document flow is unaffected.
80
+
81
+ ### Printing
82
+
83
+ In print media the outlet is a plain block box instead of a grid container. A grid container is
84
+ an independent formatting context, so the bottom margin of a screen's last block cannot collapse
85
+ through it — the margin lands *inside* the outlet's box and adds to its height. On screen that is
86
+ harmless. On paper it is not: when content ends within that margin of a page boundary, the box
87
+ spills onto a new page that holds nothing but the margin. As a block box, the outlet lets the
88
+ margin collapse past it to the end of the document, and a margin that meets a page break is
89
+ truncated there, so no trailing blank page appears.
90
+
91
+ Print loses nothing by this. The grid exists to pass a *sized* parent's height down, and an
92
+ application shell normally sizes itself to the viewport only for screen media; in print the
93
+ parent's height is `auto`, and `min-height: 100%` resolves to nothing.
94
+
95
+ ### Overriding it
96
+
97
+ The `:where()` wrapper makes both rules' specificity zero, so **any** `u-outlet { … }` rule your
98
+ application writes wins, regardless of sheet order and without `!important`:
61
99
 
62
100
  ```css
63
- u-outlet { display: flex; } /* wins */
64
- u-outlet { height: auto; } /* keep the box, drop the fill */
65
- u-outlet { display: inline; } /* restores the pre-0.14.0 behavior */
66
- @media print { u-outlet { } } /* wins */
101
+ u-outlet { display: flex; } /* wins */
102
+ u-outlet { display: contents; } /* remove the box entirely */
103
+ u-outlet { display: block; height: 100%; } /* restores the 0.14.0 behavior */
104
+ u-outlet { display: inline; } /* restores the pre-0.14.0 behavior */
105
+ @media print { u-outlet { display: grid; } } /* restores the 0.15.0 print behavior */
67
106
  ```
68
107
 
69
- The rule is not media-scoped: the outlet is a block box on screen and in print alike.
108
+ > **Making the outlet *smaller* takes two declarations, not one.** `min-height` is a floor, so
109
+ > `u-outlet { height: 200px }` on its own still measures the parent's height. Write
110
+ > `u-outlet { min-height: 0; height: 200px }`. Making it *larger*, or replacing `display`, needs
111
+ > nothing extra. This is the only contract addition in 0.15.0.
112
+
113
+
70
114
 
71
115
  ## Nested Outlet Rule
72
116