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.
Files changed (41) hide show
  1. package/dist/controls/ButtonLink.svelte +5 -1
  2. package/dist/controls/Input.svelte.d.ts +1 -1
  3. package/dist/controls/Option.svelte +3 -3
  4. package/dist/controls/Select.svelte +4 -3
  5. package/dist/controls/Slider.svelte +5 -1
  6. package/dist/cssprops.js +3 -0
  7. package/dist/dropdowns/DropdownMenu.svelte +40 -31
  8. package/dist/layout/Bar.svelte +4 -2
  9. package/dist/layout/Container.svelte.d.ts +6 -4
  10. package/dist/layout/DataListItem.svelte +1 -1
  11. package/dist/layout/FormProvider.svelte +3 -1
  12. package/dist/layout/GridLayout.svelte +1 -1
  13. package/dist/layout/Inline.svelte +5 -1
  14. package/dist/layout/Page.svelte +29 -1
  15. package/dist/layout/ResponsiveText.svelte +1 -1
  16. package/dist/layout/ResponsiveText.svelte.d.ts +2 -0
  17. package/dist/layout/Sidebar.svelte +22 -7
  18. package/dist/layout/SplitPane.svelte +3 -3
  19. package/dist/layout/Stack.svelte +5 -1
  20. package/dist/layout/TabBar.svelte +2 -3
  21. package/dist/layout/Table.svelte +21 -11
  22. package/dist/layout/Tile.svelte +1 -0
  23. package/dist/overlays/Dialog.svelte +2 -2
  24. package/dist/overlays/Dialog.svelte.d.ts +2 -2
  25. package/dist/overlays/Tooltip.svelte +65 -27
  26. package/dist/overlays/Tooltip.svelte.d.ts +1 -0
  27. package/dist/review/loadReviewAppPage.d.ts +1 -1
  28. package/dist/review/scenarios/IncredibleAppShell.svelte +44 -37
  29. package/dist/review/scenarios/LaunchStudio.svelte +108 -83
  30. package/dist/review/scenarios/LayoutWorkbench.svelte +49 -34
  31. package/dist/review/scenarios/TableWorkbench.svelte +82 -74
  32. package/dist/review/scenarios/VisualSystemBoard.svelte +387 -0
  33. package/dist/review/scenarios/VisualSystemBoard.svelte.d.ts +3 -0
  34. package/dist/review/scenarios.d.ts +8 -4
  35. package/dist/review/scenarios.js +9 -4
  36. package/dist/types.d.ts +3 -0
  37. package/dist/vars/colors.css +1 -1
  38. package/dist/vars/defaults.css +8 -1
  39. package/dist/vars/layout.css +7 -0
  40. package/dist/vars/themes/bootstrap.css +1 -0
  41. 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>Product Launch Scenario</p>
60
+ <p>Encyclopedia Of Strategic Containers</p>
49
61
 
50
62
  <Stack gap="0">
51
63
  <div>
52
- <Tag success>Ready</Tag>
53
- <Tag info>Pilot</Tag>
54
- <Tag warning>Needs Comms Review</Tag>
64
+ <Tag success>Stable</Tag>
65
+ <Tag info>Briefing</Tag>
66
+ <Tag warning>Needs Footnote</Tag>
55
67
  </div>
56
- <h1>Ship the migration control center</h1>
68
+ <h1>Contain the cascade without spilling the tea</h1>
57
69
  </Stack>
58
70
  <p>
59
- This review page exercises hero treatment, tabs, split panes, overlays,
60
- status tags, and richer control states without relying on ad hoc demo
61
- chrome.
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 Launch Brief
84
+ Open Doctrine Brief
71
85
  </Button>
72
- <ButtonLink href="#launch-plan">Jump To Plan</ButtonLink>
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>Launch Studio</strong></div>
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 brief</button></li>
85
- <li><button type="button">Share plan</button></li>
86
- <li><button type="button">Archive launch</button></li>
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>Audience</h3>
109
+ <h3>Sphere</h3>
96
110
  {/snippet}
97
111
  <ResponsiveText>
98
- {#snippet xs()}Compact lane{/snippet}
99
- {#snippet small()}Narrow launch lane{/snippet}
100
- {#snippet medium()}Balanced launch lane{/snippet}
101
- {#snippet large()}Wide launch lane{/snippet}
102
- {#snippet xl()}Executive launch lane{/snippet}
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>Enterprise rollout is first in line.</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>Coverage</h3>
125
+ <h3>Stability</h3>
109
126
  {/snippet}
110
127
  <Progress state={progressState} value={rolloutPercent} max={100}>
111
- {rolloutPercent}% launch readiness
128
+ {rolloutPercent}% boundary confidence
112
129
  </Progress>
113
130
  </Card>
114
131
  <Card>
115
132
  {#snippet header()}
116
- <h3>CTA Surface</h3>
133
+ <h3>Margin Note</h3>
117
134
  {/snippet}
118
- <p>
119
- <Tooltip tooltipText="Use this to expose secondary explanatory text.">
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 Help Copy
138
+ Review Margin Note
122
139
  </Button>
123
140
  </Tooltip>
124
- </p>
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
- The left pane uses an accordion to exercise native details
160
- styling in a denser app surface.
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>Launch brief</summary>
185
+ <summary>Doctrine brief</summary>
167
186
  <p>
168
- Messaging is approved for enterprise accounts. Support macros
169
- still need a final pass.
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
- Readiness checklist
194
+ Boundary checklist
175
195
  </summary>
176
196
  <div data-audit-target="accordion-open">
177
197
  <p>
178
- Remaining blockers are limited to docs and rollout comms.
179
- </p>
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
- Traffic can be routed back to the old experience inside five
190
- minutes if error rate rises.
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>Control surface</h2>
220
+ <h2>Policy controls</h2>
199
221
  </TextLayout>
200
222
  <Card>
201
223
  {#snippet header()}
202
- <h3>Audience and rollout</h3>
224
+ <h3>Sphere and boundary</h3>
203
225
  {/snippet}
204
226
 
205
- <p>
227
+ <Stack gap="var(--space-sm)">
206
228
  <RadioButton bind:group={selectedAudience} value="enterprise">
207
- Enterprise
229
+ Atlantic pact
208
230
  </RadioButton>
209
231
  <RadioButton bind:group={selectedAudience} value="midmarket">
210
- Mid-market
232
+ Non-aligned observers
211
233
  </RadioButton>
212
234
  <RadioButton bind:group={selectedAudience} value="self-serve">
213
- Self-serve
235
+ Backchannel committee
214
236
  </RadioButton>
215
- </p>
237
+ </Stack>
216
238
 
217
- <p>
239
+ <div>
218
240
  <Select bind:value={rolloutTrack}>
219
- <Option value="pilot"><strong>Pilot</strong> ring</Option>
220
- <Option value="canary"><strong>Canary</strong> ring</Option>
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>General</strong> availability</Option
244
+ ><strong>Summit</strong> doctrine</Option
223
245
  >
224
246
  </Select>
225
- </p>
247
+ </div>
226
248
 
227
249
  <p>
228
- <strong>Rollout percentage:</strong>
250
+ <strong>Boundary confidence:</strong>
229
251
  {rolloutPercent}%
230
252
  </p>
231
- <p>
253
+ <div>
232
254
  <Slider bind:value={rolloutPercent} min={0} max={100} />
233
- </p>
255
+ </div>
234
256
  <Progress state={progressState} value={rolloutPercent} max={100}>
235
- {selectedAudience} · {rolloutTrack}
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
- This tab gives the harness a second named state while exercising
246
- row layouts and semantic tag surfaces.
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>Engineering</h3>
275
+ <h3>Map Room</h3>
253
276
  {/snippet}
254
- <p><Tag success>Green</Tag></p>
255
- <p>Rollback rehearsed and metrics alerts verified.</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>Marketing</h3>
282
+ <h3>Historian</h3>
260
283
  {/snippet}
261
- <p><Tag warning>Reviewing</Tag></p>
262
- <p>Announcement email still needs regional approval.</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>Support</h3>
289
+ <h3>Protocol Desk</h3>
267
290
  {/snippet}
268
- <p><Tag info>Queued</Tag></p>
269
- <p>Macro updates are prepared for the pilot cohort.</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
- Timeline is intentionally quiet. It exists to show a third tab state
278
- without adding more bespoke chrome.
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="svelte"
282
- code={`<Hero>
283
- <Tag success>Ready</Tag>
284
- <ButtonLink href="#launch-plan">Jump To Plan</ButtonLink>
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>Launch brief</h2>
324
+ <h2>Doctrine brief</h2>
302
325
  <p>
303
- This dialog exercises overlay surfaces, sticky close affordances,
304
- and nested content containers.
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>Target cohort</h3>
335
+ <h3>Sphere</h3>
311
336
  {/snippet}
312
- <p>{selectedAudience}</p>
337
+ <strong>{selectedAudienceLabel}</strong>
313
338
  </Card>
314
339
  <Card>
315
340
  {#snippet header()}
316
- <h3>Release track</h3>
341
+ <h3>Boundary</h3>
317
342
  {/snippet}
318
- <p>{rolloutTrack}</p>
343
+ <strong>{rolloutTrackLabel}</strong>
319
344
  </Card>
320
345
  <Card>
321
346
  {#snippet header()}
322
- <h3>Readiness</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: "Launch Readiness",
14
+ title: "Aisle Containment",
15
15
  metric: "87%",
16
- detail: "Three blockers remain before release cutoff.",
16
+ detail: "Core storage categories remain aligned with spring reset targets.",
17
17
  },
18
18
  {
19
- title: "Open Approvals",
19
+ title: "Drawer Dividers",
20
20
  metric: "12",
21
- detail: "Legal and security still need sign-off.",
21
+ detail: "Twelve modular drawer programs are under assortment review.",
22
22
  },
23
23
  {
24
- title: "Active Experiments",
24
+ title: "Elfa Experiments",
25
25
  metric: "4",
26
- detail: "Two pricing variants are outperforming control.",
26
+ detail: "Four shelving pilots are active across closet and pantry segments.",
27
27
  },
28
28
  {
29
- title: "Support Load",
29
+ title: "Label Maker Load",
30
30
  metric: "19",
31
- detail: "Queue volume is down 8% week over week.",
31
+ detail: "Nineteen signage updates are queued for category managers.",
32
32
  },
33
33
  ];
34
34
  let hideSidebar = $state(false);
35
- let selectedTile = $state("pipeline");
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>Layout Workbench</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 Sidebar" : "Hide Sidebar"}
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>Launches</button></li>
71
- <li><button>Approvals</button></li>
72
- <li><button>Insights</button></li>
73
- <li><button>Settings</button></li>
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>Sidebar and card layout workbench</h1>
79
+ <h1>Container Store field report</h1>
80
80
  <p>
81
- This scenario exercises page chrome, a collapsible sidebar, summary cards,
82
- and interactive tiles in the same route.
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>Review</Button></p>
97
+ <p><Button>Inspect</Button></p>
95
98
  </Card>
96
99
  {/each}
97
100
  </GridLayout>
98
101
 
99
- <TextLayout><h2>Interactive tiles</h2></TextLayout>
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("pipeline")}
107
+ onclick={() => inspectTile("closet wall")}
105
108
  >
106
- <h3>Pipeline</h3>
107
- <p>Inspect work across launch stages.</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("customers")}>
111
- <h3>Customers</h3>
112
- <p>See which accounts need a follow-up this week.</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("experiments")}>
116
- <h3>Experiments</h3>
117
- <p>Review rollout status and watch for regressions.</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 workspace</h3>
122
- <p>Keep this board in the default sidebar view.</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> workspace is now in focus. This gives
136
- the review harness a second state for tiles without adding custom layout
137
- chrome.
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>