contain-css-svelte 1.1.4 → 1.1.6
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/dist/controls/ButtonLink.svelte +5 -1
- package/dist/controls/Input.svelte.d.ts +1 -1
- package/dist/controls/Option.svelte +3 -3
- package/dist/controls/Select.svelte +4 -3
- package/dist/controls/Slider.svelte +5 -1
- package/dist/cssprops.js +3 -0
- package/dist/dropdowns/DropdownMenu.svelte +40 -31
- package/dist/layout/Bar.svelte +4 -2
- package/dist/layout/Container.svelte.d.ts +6 -4
- package/dist/layout/DataListItem.svelte +1 -1
- package/dist/layout/FormProvider.svelte +3 -1
- package/dist/layout/GridLayout.svelte +1 -1
- package/dist/layout/Inline.svelte +5 -1
- package/dist/layout/Page.svelte +29 -1
- package/dist/layout/ResponsiveText.svelte +1 -1
- package/dist/layout/ResponsiveText.svelte.d.ts +2 -0
- package/dist/layout/Sidebar.svelte +22 -7
- package/dist/layout/SplitPane.svelte +3 -3
- package/dist/layout/Stack.svelte +5 -1
- package/dist/layout/TabBar.svelte +2 -3
- package/dist/layout/Table.svelte +21 -11
- package/dist/layout/Tile.svelte +1 -0
- package/dist/overlays/Dialog.svelte +2 -2
- package/dist/overlays/Dialog.svelte.d.ts +2 -2
- package/dist/overlays/Tooltip.svelte +65 -27
- package/dist/overlays/Tooltip.svelte.d.ts +1 -0
- package/dist/review/loadReviewAppPage.d.ts +1 -1
- package/dist/review/scenarios/IncredibleAppShell.svelte +44 -37
- package/dist/review/scenarios/LaunchStudio.svelte +108 -83
- package/dist/review/scenarios/LayoutWorkbench.svelte +49 -34
- package/dist/review/scenarios/TableWorkbench.svelte +82 -74
- package/dist/review/scenarios/VisualSystemBoard.svelte +387 -0
- package/dist/review/scenarios/VisualSystemBoard.svelte.d.ts +3 -0
- package/dist/review/scenarios.d.ts +8 -4
- package/dist/review/scenarios.js +9 -4
- package/dist/types.d.ts +3 -0
- package/dist/vars/colors.css +1 -1
- package/dist/vars/defaults.css +8 -1
- package/dist/vars/layout.css +7 -0
- package/dist/vars/themes/bootstrap.css +1 -0
- package/package.json +1 -1
|
@@ -29,6 +29,16 @@ let selectedAudience = $state("enterprise");
|
|
|
29
29
|
let rolloutTrack = $state("pilot");
|
|
30
30
|
let rolloutPercent = $state(68);
|
|
31
31
|
let launchBriefOpen = $state(false);
|
|
32
|
+
const audienceLabels = {
|
|
33
|
+
enterprise: "Atlantic pact",
|
|
34
|
+
midmarket: "Non-aligned observers",
|
|
35
|
+
"self-serve": "Backchannel committee",
|
|
36
|
+
};
|
|
37
|
+
const rolloutLabels = {
|
|
38
|
+
pilot: "Berlin buffer",
|
|
39
|
+
canary: "Embassy cable",
|
|
40
|
+
general: "Summit doctrine",
|
|
41
|
+
};
|
|
32
42
|
function resolveProgressState(value) {
|
|
33
43
|
if (value >= 100)
|
|
34
44
|
return "complete";
|
|
@@ -37,6 +47,8 @@ function resolveProgressState(value) {
|
|
|
37
47
|
return "inprogress";
|
|
38
48
|
}
|
|
39
49
|
let progressState = $derived(resolveProgressState(rolloutPercent));
|
|
50
|
+
let selectedAudienceLabel = $derived(audienceLabels[selectedAudience]);
|
|
51
|
+
let rolloutTrackLabel = $derived(rolloutLabels[rolloutTrack]);
|
|
40
52
|
</script>
|
|
41
53
|
|
|
42
54
|
<Hero
|
|
@@ -45,20 +57,22 @@ let progressState = $derived(resolveProgressState(rolloutPercent));
|
|
|
45
57
|
headingFg="var(--primary-fg)"
|
|
46
58
|
>
|
|
47
59
|
<TextLayout>
|
|
48
|
-
<p>
|
|
60
|
+
<p>Encyclopedia Of Strategic Containers</p>
|
|
49
61
|
|
|
50
62
|
<Stack gap="0">
|
|
51
63
|
<div>
|
|
52
|
-
<Tag success>
|
|
53
|
-
<Tag info>
|
|
54
|
-
<Tag warning>Needs
|
|
64
|
+
<Tag success>Stable</Tag>
|
|
65
|
+
<Tag info>Briefing</Tag>
|
|
66
|
+
<Tag warning>Needs Footnote</Tag>
|
|
55
67
|
</div>
|
|
56
|
-
<h1>
|
|
68
|
+
<h1>Contain the cascade without spilling the tea</h1>
|
|
57
69
|
</Stack>
|
|
58
70
|
<p>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
71
|
+
Containment was a Cold War policy of limiting expansion by surrounding a
|
|
72
|
+
rival power with alliances, aid, military readiness, and patient
|
|
73
|
+
diplomacy. In this miniature entry, the doctrine is treated as a civic art
|
|
74
|
+
of boundaries: buffers hold, channels stay open, and every communique is
|
|
75
|
+
filed in a box marked "do not escalate before breakfast."
|
|
62
76
|
</p>
|
|
63
77
|
|
|
64
78
|
<Inline>
|
|
@@ -67,23 +81,23 @@ let progressState = $derived(resolveProgressState(rolloutPercent));
|
|
|
67
81
|
data-audit-action="open-dialog"
|
|
68
82
|
onclick={() => (launchBriefOpen = true)}
|
|
69
83
|
>
|
|
70
|
-
Open
|
|
84
|
+
Open Doctrine Brief
|
|
71
85
|
</Button>
|
|
72
|
-
<ButtonLink href="#launch-plan">Jump To
|
|
86
|
+
<ButtonLink href="#launch-plan">Jump To Map Room</ButtonLink>
|
|
73
87
|
</Inline>
|
|
74
88
|
</TextLayout>
|
|
75
89
|
</Hero>
|
|
76
90
|
<Page data-audit-target="page">
|
|
77
91
|
{#snippet header()}<Bar --bar-border-top="none" --bar-border-bottom="none">
|
|
78
|
-
<div><strong>
|
|
92
|
+
<div><strong>Containment Studio</strong></div>
|
|
79
93
|
<div>
|
|
80
94
|
<DropdownMenu triggerAuditAction="open-launch-menu">
|
|
81
95
|
{#snippet label()}
|
|
82
96
|
Quick Actions
|
|
83
97
|
{/snippet}
|
|
84
|
-
<li><button type="button">Duplicate
|
|
85
|
-
<li><button type="button">Share
|
|
86
|
-
<li><button type="button">Archive
|
|
98
|
+
<li><button type="button">Duplicate memo</button></li>
|
|
99
|
+
<li><button type="button">Share doctrine</button></li>
|
|
100
|
+
<li><button type="button">Archive communique</button></li>
|
|
87
101
|
</DropdownMenu>
|
|
88
102
|
</div>
|
|
89
103
|
</Bar>
|
|
@@ -92,36 +106,39 @@ let progressState = $derived(resolveProgressState(rolloutPercent));
|
|
|
92
106
|
<GridLayout card>
|
|
93
107
|
<Card>
|
|
94
108
|
{#snippet header()}
|
|
95
|
-
<h3>
|
|
109
|
+
<h3>Sphere</h3>
|
|
96
110
|
{/snippet}
|
|
97
111
|
<ResponsiveText>
|
|
98
|
-
{#snippet xs()}
|
|
99
|
-
{#snippet small()}Narrow
|
|
100
|
-
{#snippet medium()}Balanced
|
|
101
|
-
{#snippet large()}Wide
|
|
102
|
-
{#snippet xl()}
|
|
112
|
+
{#snippet xs()}Pocket doctrine{/snippet}
|
|
113
|
+
{#snippet small()}Narrow buffer{/snippet}
|
|
114
|
+
{#snippet medium()}Balanced boundary{/snippet}
|
|
115
|
+
{#snippet large()}Wide diplomatic lane{/snippet}
|
|
116
|
+
{#snippet xl()}Grand strategy briefing{/snippet}
|
|
103
117
|
</ResponsiveText>
|
|
104
|
-
<p>
|
|
118
|
+
<p>
|
|
119
|
+
The inner sphere marks the states, offices, and observers expected to
|
|
120
|
+
receive the first memo before policy hardens into posture.
|
|
121
|
+
</p>
|
|
105
122
|
</Card>
|
|
106
123
|
<Card>
|
|
107
124
|
{#snippet header()}
|
|
108
|
-
<h3>
|
|
125
|
+
<h3>Stability</h3>
|
|
109
126
|
{/snippet}
|
|
110
127
|
<Progress state={progressState} value={rolloutPercent} max={100}>
|
|
111
|
-
{rolloutPercent}%
|
|
128
|
+
{rolloutPercent}% boundary confidence
|
|
112
129
|
</Progress>
|
|
113
130
|
</Card>
|
|
114
131
|
<Card>
|
|
115
132
|
{#snippet header()}
|
|
116
|
-
<h3>
|
|
133
|
+
<h3>Margin Note</h3>
|
|
117
134
|
{/snippet}
|
|
118
|
-
<
|
|
119
|
-
<Tooltip tooltipText="
|
|
135
|
+
<Inline>
|
|
136
|
+
<Tooltip tooltipText="Diplomatic cables also need explanatory hover text.">
|
|
120
137
|
<Button data-audit-action="show-tooltip" data-audit-focus="true">
|
|
121
|
-
Review
|
|
138
|
+
Review Margin Note
|
|
122
139
|
</Button>
|
|
123
140
|
</Tooltip>
|
|
124
|
-
</
|
|
141
|
+
</Inline>
|
|
125
142
|
</Card>
|
|
126
143
|
</GridLayout>
|
|
127
144
|
</Container>
|
|
@@ -156,38 +173,43 @@ let progressState = $derived(resolveProgressState(rolloutPercent));
|
|
|
156
173
|
<TextLayout>
|
|
157
174
|
<h2>Decision stack</h2>
|
|
158
175
|
<p>
|
|
159
|
-
|
|
160
|
-
|
|
176
|
+
A containment policy normally joins military preparedness,
|
|
177
|
+
economic assistance, diplomatic signaling, and public patience.
|
|
178
|
+
The entries below summarize the map-room logic without pretending
|
|
179
|
+
that history ever fits neatly inside one filing cabinet.
|
|
161
180
|
</p>
|
|
162
181
|
</TextLayout>
|
|
163
182
|
|
|
164
183
|
<Accordion>
|
|
165
184
|
<details open>
|
|
166
|
-
<summary>
|
|
185
|
+
<summary>Doctrine brief</summary>
|
|
167
186
|
<p>
|
|
168
|
-
|
|
169
|
-
|
|
187
|
+
The memo argues for containment by strong boundaries and calm
|
|
188
|
+
escalation paths. The footnotes are mildly theatrical, because
|
|
189
|
+
every serious doctrine needs one sentence wearing a tiny hat.
|
|
170
190
|
</p>
|
|
171
191
|
</details>
|
|
172
192
|
<details>
|
|
173
193
|
<summary data-audit-action="open-accordion">
|
|
174
|
-
|
|
194
|
+
Boundary checklist
|
|
175
195
|
</summary>
|
|
176
196
|
<div data-audit-target="accordion-open">
|
|
177
197
|
<p>
|
|
178
|
-
Remaining
|
|
179
|
-
|
|
180
|
-
<p>
|
|
181
|
-
<Tag success>QA Signed Off</Tag>
|
|
182
|
-
<Tag warning>Docs Pending</Tag>
|
|
198
|
+
Remaining risks are limited to vague metaphors, leaky
|
|
199
|
+
margins, and one suspiciously ambitious sidebar.
|
|
183
200
|
</p>
|
|
201
|
+
<Inline wrap="wrap">
|
|
202
|
+
<Tag success>Buffers Stable</Tag>
|
|
203
|
+
<Tag warning>Footnotes Pending</Tag>
|
|
204
|
+
</Inline>
|
|
184
205
|
</div>
|
|
185
206
|
</details>
|
|
186
207
|
<details>
|
|
187
208
|
<summary>Fallback plan</summary>
|
|
188
209
|
<p>
|
|
189
|
-
|
|
190
|
-
|
|
210
|
+
If a crisis escalates, return the matter to the old treaty
|
|
211
|
+
room, serve lukewarm coffee, and let the ambassadors discover
|
|
212
|
+
whether their sternest sentences still fit inside the folder.
|
|
191
213
|
</p>
|
|
192
214
|
</details>
|
|
193
215
|
</Accordion>
|
|
@@ -195,44 +217,44 @@ let progressState = $derived(resolveProgressState(rolloutPercent));
|
|
|
195
217
|
|
|
196
218
|
{#snippet right()}
|
|
197
219
|
<TextLayout>
|
|
198
|
-
<h2>
|
|
220
|
+
<h2>Policy controls</h2>
|
|
199
221
|
</TextLayout>
|
|
200
222
|
<Card>
|
|
201
223
|
{#snippet header()}
|
|
202
|
-
<h3>
|
|
224
|
+
<h3>Sphere and boundary</h3>
|
|
203
225
|
{/snippet}
|
|
204
226
|
|
|
205
|
-
<
|
|
227
|
+
<Stack gap="var(--space-sm)">
|
|
206
228
|
<RadioButton bind:group={selectedAudience} value="enterprise">
|
|
207
|
-
|
|
229
|
+
Atlantic pact
|
|
208
230
|
</RadioButton>
|
|
209
231
|
<RadioButton bind:group={selectedAudience} value="midmarket">
|
|
210
|
-
|
|
232
|
+
Non-aligned observers
|
|
211
233
|
</RadioButton>
|
|
212
234
|
<RadioButton bind:group={selectedAudience} value="self-serve">
|
|
213
|
-
|
|
235
|
+
Backchannel committee
|
|
214
236
|
</RadioButton>
|
|
215
|
-
</
|
|
237
|
+
</Stack>
|
|
216
238
|
|
|
217
|
-
<
|
|
239
|
+
<div>
|
|
218
240
|
<Select bind:value={rolloutTrack}>
|
|
219
|
-
<Option value="pilot"><strong>
|
|
220
|
-
<Option value="canary"><strong>
|
|
241
|
+
<Option value="pilot"><strong>Berlin</strong> buffer</Option>
|
|
242
|
+
<Option value="canary"><strong>Embassy</strong> cable</Option>
|
|
221
243
|
<Option value="general"
|
|
222
|
-
><strong>
|
|
244
|
+
><strong>Summit</strong> doctrine</Option
|
|
223
245
|
>
|
|
224
246
|
</Select>
|
|
225
|
-
</
|
|
247
|
+
</div>
|
|
226
248
|
|
|
227
249
|
<p>
|
|
228
|
-
<strong>
|
|
250
|
+
<strong>Boundary confidence:</strong>
|
|
229
251
|
{rolloutPercent}%
|
|
230
252
|
</p>
|
|
231
|
-
<
|
|
253
|
+
<div>
|
|
232
254
|
<Slider bind:value={rolloutPercent} min={0} max={100} />
|
|
233
|
-
</
|
|
255
|
+
</div>
|
|
234
256
|
<Progress state={progressState} value={rolloutPercent} max={100}>
|
|
235
|
-
{
|
|
257
|
+
{selectedAudienceLabel} · {rolloutTrackLabel}
|
|
236
258
|
</Progress>
|
|
237
259
|
</Card>
|
|
238
260
|
{/snippet}
|
|
@@ -242,31 +264,32 @@ let progressState = $derived(resolveProgressState(rolloutPercent));
|
|
|
242
264
|
<TextLayout>
|
|
243
265
|
<h2>Readiness board</h2>
|
|
244
266
|
<p>
|
|
245
|
-
|
|
246
|
-
|
|
267
|
+
Containment depended on slow maintenance: cables answered on time,
|
|
268
|
+
boundaries rehearsed before emergencies, and public explanations
|
|
269
|
+
prepared before rumors filled the room.
|
|
247
270
|
</p>
|
|
248
271
|
</TextLayout>
|
|
249
272
|
<GridLayout card --card-width="var(--card-width-small)">
|
|
250
273
|
<Card>
|
|
251
274
|
{#snippet header()}
|
|
252
|
-
<h3>
|
|
275
|
+
<h3>Map Room</h3>
|
|
253
276
|
{/snippet}
|
|
254
|
-
<
|
|
255
|
-
<p>
|
|
277
|
+
<Inline><Tag success>Stable</Tag></Inline>
|
|
278
|
+
<p>Boundaries rehearsed and annotation alerts verified.</p>
|
|
256
279
|
</Card>
|
|
257
280
|
<Card>
|
|
258
281
|
{#snippet header()}
|
|
259
|
-
<h3>
|
|
282
|
+
<h3>Historian</h3>
|
|
260
283
|
{/snippet}
|
|
261
|
-
<
|
|
262
|
-
<p>
|
|
284
|
+
<Inline><Tag warning>Reviewing</Tag></Inline>
|
|
285
|
+
<p>One paragraph still confuses containment with a casserole lid.</p>
|
|
263
286
|
</Card>
|
|
264
287
|
<Card>
|
|
265
288
|
{#snippet header()}
|
|
266
|
-
<h3>
|
|
289
|
+
<h3>Protocol Desk</h3>
|
|
267
290
|
{/snippet}
|
|
268
|
-
<
|
|
269
|
-
<p>
|
|
291
|
+
<Inline><Tag info>Queued</Tag></Inline>
|
|
292
|
+
<p>Memo templates are prepared for the next boxed-in briefing.</p>
|
|
270
293
|
</Card>
|
|
271
294
|
</GridLayout>
|
|
272
295
|
</div>
|
|
@@ -274,15 +297,15 @@ let progressState = $derived(resolveProgressState(rolloutPercent));
|
|
|
274
297
|
<TextLayout>
|
|
275
298
|
<h2>Timeline</h2>
|
|
276
299
|
<p>
|
|
277
|
-
|
|
278
|
-
|
|
300
|
+
The short chronology begins with a warning, becomes a doctrine, and
|
|
301
|
+
ends as a habit of institutions. The dates matter, but so does the
|
|
302
|
+
recurring act of putting tension into procedural containers.
|
|
279
303
|
</p>
|
|
280
304
|
<Code
|
|
281
|
-
language="
|
|
282
|
-
code={
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
</Hero>`}
|
|
305
|
+
language="text"
|
|
306
|
+
code={`1946: The long telegram frames expansion as a pressure problem.
|
|
307
|
+
1947: The Truman Doctrine names aid as a boundary tool.
|
|
308
|
+
1949: NATO turns the boundary into an institution.`}
|
|
286
309
|
/>
|
|
287
310
|
</TextLayout>
|
|
288
311
|
{/if}
|
|
@@ -298,28 +321,30 @@ let progressState = $derived(resolveProgressState(rolloutPercent));
|
|
|
298
321
|
>
|
|
299
322
|
<div data-audit-target="dialog-open">
|
|
300
323
|
<TextLayout>
|
|
301
|
-
<h2>
|
|
324
|
+
<h2>Doctrine brief</h2>
|
|
302
325
|
<p>
|
|
303
|
-
|
|
304
|
-
|
|
326
|
+
The brief treats containment as an argument for patience under
|
|
327
|
+
pressure. It is less a wall than a series of labeled compartments:
|
|
328
|
+
alliances, aid, signals, reserves, and enough coffee to keep the
|
|
329
|
+
night staff civil.
|
|
305
330
|
</p>
|
|
306
331
|
</TextLayout>
|
|
307
332
|
<GridLayout card --card-width="var(--card-width-small)">
|
|
308
333
|
<Card>
|
|
309
334
|
{#snippet header()}
|
|
310
|
-
<h3>
|
|
335
|
+
<h3>Sphere</h3>
|
|
311
336
|
{/snippet}
|
|
312
|
-
<
|
|
337
|
+
<strong>{selectedAudienceLabel}</strong>
|
|
313
338
|
</Card>
|
|
314
339
|
<Card>
|
|
315
340
|
{#snippet header()}
|
|
316
|
-
<h3>
|
|
341
|
+
<h3>Boundary</h3>
|
|
317
342
|
{/snippet}
|
|
318
|
-
<
|
|
343
|
+
<strong>{rolloutTrackLabel}</strong>
|
|
319
344
|
</Card>
|
|
320
345
|
<Card>
|
|
321
346
|
{#snippet header()}
|
|
322
|
-
<h3>
|
|
347
|
+
<h3>Confidence</h3>
|
|
323
348
|
{/snippet}
|
|
324
349
|
<Progress state={progressState} value={rolloutPercent} max={100}>
|
|
325
350
|
{rolloutPercent}%
|
|
@@ -11,28 +11,28 @@ import Tile from "../../layout/Tile.svelte";
|
|
|
11
11
|
import TextLayout from "../../typography/TextLayout.svelte";
|
|
12
12
|
const cards = [
|
|
13
13
|
{
|
|
14
|
-
title: "
|
|
14
|
+
title: "Aisle Containment",
|
|
15
15
|
metric: "87%",
|
|
16
|
-
detail: "
|
|
16
|
+
detail: "Core storage categories remain aligned with spring reset targets.",
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
|
-
title: "
|
|
19
|
+
title: "Drawer Dividers",
|
|
20
20
|
metric: "12",
|
|
21
|
-
detail: "
|
|
21
|
+
detail: "Twelve modular drawer programs are under assortment review.",
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
|
-
title: "
|
|
24
|
+
title: "Elfa Experiments",
|
|
25
25
|
metric: "4",
|
|
26
|
-
detail: "
|
|
26
|
+
detail: "Four shelving pilots are active across closet and pantry segments.",
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
|
-
title: "
|
|
29
|
+
title: "Label Maker Load",
|
|
30
30
|
metric: "19",
|
|
31
|
-
detail: "
|
|
31
|
+
detail: "Nineteen signage updates are queued for category managers.",
|
|
32
32
|
},
|
|
33
33
|
];
|
|
34
34
|
let hideSidebar = $state(false);
|
|
35
|
-
let selectedTile = $state("
|
|
35
|
+
let selectedTile = $state("closet wall");
|
|
36
36
|
let tileSelected = $state(false);
|
|
37
37
|
function toggleSidebar() {
|
|
38
38
|
hideSidebar = !hideSidebar;
|
|
@@ -47,7 +47,7 @@ function inspectTile(tile) {
|
|
|
47
47
|
{#snippet header()}
|
|
48
48
|
<Bar primary>
|
|
49
49
|
<div>
|
|
50
|
-
<h1>
|
|
50
|
+
<h1>Container Store Report</h1>
|
|
51
51
|
</div>
|
|
52
52
|
|
|
53
53
|
<Inline>
|
|
@@ -56,7 +56,7 @@ function inspectTile(tile) {
|
|
|
56
56
|
aria-expanded={!hideSidebar}
|
|
57
57
|
onclick={toggleSidebar}
|
|
58
58
|
>
|
|
59
|
-
{hideSidebar ? "Show
|
|
59
|
+
{hideSidebar ? "Show Aisles" : "Hide Aisles"}
|
|
60
60
|
</Button>
|
|
61
61
|
<MiniButton aria-label="Notifications">3</MiniButton>
|
|
62
62
|
</Inline>
|
|
@@ -67,19 +67,22 @@ function inspectTile(tile) {
|
|
|
67
67
|
<Sidebar left>
|
|
68
68
|
<MenuList striped>
|
|
69
69
|
<li><button class="active">Overview</button></li>
|
|
70
|
-
<li><button>
|
|
71
|
-
<li><button>
|
|
72
|
-
<li><button>
|
|
73
|
-
<li><button>
|
|
70
|
+
<li><button>Closets</button></li>
|
|
71
|
+
<li><button>Pantries</button></li>
|
|
72
|
+
<li><button>Bins</button></li>
|
|
73
|
+
<li><button>Receipts</button></li>
|
|
74
74
|
</MenuList>
|
|
75
75
|
</Sidebar>
|
|
76
76
|
{/snippet}
|
|
77
77
|
|
|
78
78
|
<TextLayout>
|
|
79
|
-
<h1>
|
|
79
|
+
<h1>Container Store field report</h1>
|
|
80
80
|
<p>
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
The Container Store continues to position organization as a premium retail
|
|
82
|
+
service, not merely a collection of bins. Store teams report steady demand
|
|
83
|
+
for closet systems, pantry canisters, drawer programs, and labeled
|
|
84
|
+
back-of-house workflows that make small spaces feel professionally
|
|
85
|
+
governed.
|
|
83
86
|
</p>
|
|
84
87
|
</TextLayout>
|
|
85
88
|
<GridLayout card>
|
|
@@ -91,35 +94,47 @@ function inspectTile(tile) {
|
|
|
91
94
|
|
|
92
95
|
<h2>{card.metric}</h2>
|
|
93
96
|
<p>{card.detail}</p>
|
|
94
|
-
<p><Button>
|
|
97
|
+
<p><Button>Inspect</Button></p>
|
|
95
98
|
</Card>
|
|
96
99
|
{/each}
|
|
97
100
|
</GridLayout>
|
|
98
101
|
|
|
99
|
-
<TextLayout><h2>Interactive
|
|
102
|
+
<TextLayout><h2>Interactive report sections</h2></TextLayout>
|
|
100
103
|
<GridLayout tile>
|
|
101
104
|
<Tile
|
|
102
105
|
interactive
|
|
103
106
|
data-audit-action="select-tile"
|
|
104
|
-
onclick={() => inspectTile("
|
|
107
|
+
onclick={() => inspectTile("closet wall")}
|
|
105
108
|
>
|
|
106
|
-
<h3>
|
|
107
|
-
<p>
|
|
109
|
+
<h3>Closet wall</h3>
|
|
110
|
+
<p>
|
|
111
|
+
Review shelving attach rates, installation capacity, and the mix of
|
|
112
|
+
drawers, rods, and upper storage in the current Elfa program.
|
|
113
|
+
</p>
|
|
108
114
|
</Tile>
|
|
109
115
|
|
|
110
|
-
<Tile interactive onclick={() => inspectTile("
|
|
111
|
-
<h3>
|
|
112
|
-
<p>
|
|
116
|
+
<Tile interactive onclick={() => inspectTile("pantry aisle")}>
|
|
117
|
+
<h3>Pantry aisle</h3>
|
|
118
|
+
<p>
|
|
119
|
+
Compare clear canisters, turntables, risers, and private-label
|
|
120
|
+
replenishment against seasonal meal-prep traffic.
|
|
121
|
+
</p>
|
|
113
122
|
</Tile>
|
|
114
123
|
|
|
115
|
-
<Tile interactive onclick={() => inspectTile("
|
|
116
|
-
<h3>
|
|
117
|
-
<p>
|
|
124
|
+
<Tile interactive onclick={() => inspectTile("desk drawer")}>
|
|
125
|
+
<h3>Desk drawer</h3>
|
|
126
|
+
<p>
|
|
127
|
+
Review office trays, cable boxes, desktop files, and small-item storage
|
|
128
|
+
as hybrid work demand settles into a steadier pattern.
|
|
129
|
+
</p>
|
|
118
130
|
</Tile>
|
|
119
131
|
|
|
120
132
|
<Tile selectable>
|
|
121
|
-
<h3>Pin this
|
|
122
|
-
<p>
|
|
133
|
+
<h3>Pin this aisle</h3>
|
|
134
|
+
<p>
|
|
135
|
+
Keep this section in the weekly merchant packet for follow-up on margin,
|
|
136
|
+
attachment, and staff training.
|
|
137
|
+
</p>
|
|
123
138
|
</Tile>
|
|
124
139
|
</GridLayout>
|
|
125
140
|
|
|
@@ -132,9 +147,9 @@ function inspectTile(tile) {
|
|
|
132
147
|
{/snippet}
|
|
133
148
|
|
|
134
149
|
<p>
|
|
135
|
-
The <strong>{selectedTile}</strong>
|
|
136
|
-
|
|
137
|
-
|
|
150
|
+
The <strong>{selectedTile}</strong> section is now in focus. The next
|
|
151
|
+
review should compare traffic, basket size, and installation
|
|
152
|
+
availability before making changes to the regional plan.
|
|
138
153
|
</p>
|
|
139
154
|
</Card>
|
|
140
155
|
</div>
|